summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 14:22:51 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 14:22:51 +0000
commit9ada0093e92388590c7368600ca4e9e3e376f0d0 (patch)
treea56fe41110023676d7082028cbaa47ca4b6e6164 /modules
parentInitial commit. (diff)
downloadpam-9ada0093e92388590c7368600ca4e9e3e376f0d0.tar.xz
pam-9ada0093e92388590c7368600ca4e9e3e376f0d0.zip
Adding upstream version 1.5.2.upstream/1.5.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'modules')
-rw-r--r--modules/Makefile.am94
-rw-r--r--modules/Makefile.in767
-rw-r--r--modules/modules.map10
-rw-r--r--modules/pam_access/Makefile.am36
-rw-r--r--modules/pam_access/Makefile.in1222
-rw-r--r--modules/pam_access/README131
-rw-r--r--modules/pam_access/README.xml39
-rw-r--r--modules/pam_access/access.conf122
-rw-r--r--modules/pam_access/access.conf.5222
-rw-r--r--modules/pam_access/access.conf.5.xml253
-rw-r--r--modules/pam_access/pam_access.8139
-rw-r--r--modules/pam_access/pam_access.8.xml265
-rw-r--r--modules/pam_access/pam_access.c985
-rwxr-xr-xmodules/pam_access/tst-pam_access2
-rw-r--r--modules/pam_debug/Makefile.am36
-rw-r--r--modules/pam_debug/Makefile.in1180
-rw-r--r--modules/pam_debug/README64
-rw-r--r--modules/pam_debug/README.xml41
-rw-r--r--modules/pam_debug/pam_debug.8144
-rw-r--r--modules/pam_debug/pam_debug.8.xml231
-rw-r--r--modules/pam_debug/pam_debug.c108
-rwxr-xr-xmodules/pam_debug/tst-pam_debug2
-rw-r--r--modules/pam_debug/tst-pam_debug-retval.c65
-rw-r--r--modules/pam_deny/Makefile.am36
-rw-r--r--modules/pam_deny/Makefile.in1180
-rw-r--r--modules/pam_deny/README31
-rw-r--r--modules/pam_deny/README.xml36
-rw-r--r--modules/pam_deny/pam_deny.8102
-rw-r--r--modules/pam_deny/pam_deny.8.xml135
-rw-r--r--modules/pam_deny/pam_deny.c60
-rwxr-xr-xmodules/pam_deny/tst-pam_deny2
-rw-r--r--modules/pam_deny/tst-pam_deny-retval.c58
-rw-r--r--modules/pam_echo/Makefile.am36
-rw-r--r--modules/pam_echo/Makefile.in1180
-rw-r--r--modules/pam_echo/README50
-rw-r--r--modules/pam_echo/README.xml36
-rw-r--r--modules/pam_echo/pam_echo.8132
-rw-r--r--modules/pam_echo/pam_echo.8.xml170
-rw-r--r--modules/pam_echo/pam_echo.c260
-rwxr-xr-xmodules/pam_echo/tst-pam_echo2
-rw-r--r--modules/pam_echo/tst-pam_echo-retval.c101
-rw-r--r--modules/pam_env/Makefile.am37
-rw-r--r--modules/pam_env/Makefile.in1248
-rw-r--r--modules/pam_env/README101
-rw-r--r--modules/pam_env/README.xml39
-rw-r--r--modules/pam_env/environment5
-rw-r--r--modules/pam_env/environment.51
-rw-r--r--modules/pam_env/pam_env.8160
-rw-r--r--modules/pam_env/pam_env.8.xml271
-rw-r--r--modules/pam_env/pam_env.c894
-rw-r--r--modules/pam_env/pam_env.conf73
-rw-r--r--modules/pam_env/pam_env.conf.5132
-rw-r--r--modules/pam_env/pam_env.conf.5.xml136
-rwxr-xr-xmodules/pam_env/tst-pam_env2
-rw-r--r--modules/pam_exec/Makefile.am33
-rw-r--r--modules/pam_exec/Makefile.in1150
-rw-r--r--modules/pam_exec/README79
-rw-r--r--modules/pam_exec/README.xml41
-rw-r--r--modules/pam_exec/pam_exec.8188
-rw-r--r--modules/pam_exec/pam_exec.8.xml319
-rw-r--r--modules/pam_exec/pam_exec.c522
-rwxr-xr-xmodules/pam_exec/tst-pam_exec2
-rw-r--r--modules/pam_faildelay/Makefile.am36
-rw-r--r--modules/pam_faildelay/Makefile.in1181
-rw-r--r--modules/pam_faildelay/README33
-rw-r--r--modules/pam_faildelay/README.xml41
-rw-r--r--modules/pam_faildelay/pam_faildelay.893
-rw-r--r--modules/pam_faildelay/pam_faildelay.8.xml136
-rw-r--r--modules/pam_faildelay/pam_faildelay.c138
-rwxr-xr-xmodules/pam_faildelay/tst-pam_faildelay2
-rw-r--r--modules/pam_faildelay/tst-pam_faildelay-retval.c88
-rw-r--r--modules/pam_faillock/Makefile.am50
-rw-r--r--modules/pam_faillock/Makefile.in1344
-rw-r--r--modules/pam_faillock/README140
-rw-r--r--modules/pam_faillock/README.xml46
-rw-r--r--modules/pam_faillock/faillock.878
-rw-r--r--modules/pam_faillock/faillock.8.xml123
-rw-r--r--modules/pam_faillock/faillock.c176
-rw-r--r--modules/pam_faillock/faillock.conf62
-rw-r--r--modules/pam_faillock/faillock.conf.5171
-rw-r--r--modules/pam_faillock/faillock.conf.5.xml253
-rw-r--r--modules/pam_faillock/faillock.h75
-rw-r--r--modules/pam_faillock/main.c231
-rw-r--r--modules/pam_faillock/pam_faillock.8262
-rw-r--r--modules/pam_faillock/pam_faillock.8.xml362
-rw-r--r--modules/pam_faillock/pam_faillock.c764
-rwxr-xr-xmodules/pam_faillock/tst-pam_faillock2
-rw-r--r--modules/pam_filter/Makefile.am37
-rw-r--r--modules/pam_filter/Makefile.in1294
-rw-r--r--modules/pam_filter/README78
-rw-r--r--modules/pam_filter/README.xml41
-rw-r--r--modules/pam_filter/pam_filter.8172
-rw-r--r--modules/pam_filter/pam_filter.8.xml261
-rw-r--r--modules/pam_filter/pam_filter.c714
-rw-r--r--modules/pam_filter/pam_filter.h32
-rwxr-xr-xmodules/pam_filter/tst-pam_filter2
-rw-r--r--modules/pam_filter/upperLOWER/Makefile.am15
-rw-r--r--modules/pam_filter/upperLOWER/Makefile.in728
-rw-r--r--modules/pam_filter/upperLOWER/upperLOWER.c141
-rw-r--r--modules/pam_ftp/Makefile.am33
-rw-r--r--modules/pam_ftp/Makefile.in1150
-rw-r--r--modules/pam_ftp/README52
-rw-r--r--modules/pam_ftp/README.xml41
-rw-r--r--modules/pam_ftp/pam_ftp.8125
-rw-r--r--modules/pam_ftp/pam_ftp.8.xml183
-rw-r--r--modules/pam_ftp/pam_ftp.c215
-rwxr-xr-xmodules/pam_ftp/tst-pam_ftp2
-rw-r--r--modules/pam_group/Makefile.am35
-rw-r--r--modules/pam_group/Makefile.in1221
-rw-r--r--modules/pam_group/README52
-rw-r--r--modules/pam_group/README.xml34
-rw-r--r--modules/pam_group/group.conf106
-rw-r--r--modules/pam_group/group.conf.5121
-rw-r--r--modules/pam_group/group.conf.5.xml147
-rw-r--r--modules/pam_group/pam_group.8109
-rw-r--r--modules/pam_group/pam_group.8.xml162
-rw-r--r--modules/pam_group/pam_group.c815
-rwxr-xr-xmodules/pam_group/tst-pam_group2
-rw-r--r--modules/pam_issue/Makefile.am33
-rw-r--r--modules/pam_issue/Makefile.in1150
-rw-r--r--modules/pam_issue/README79
-rw-r--r--modules/pam_issue/README.xml41
-rw-r--r--modules/pam_issue/pam_issue.8158
-rw-r--r--modules/pam_issue/pam_issue.8.xml234
-rw-r--r--modules/pam_issue/pam_issue.c306
-rwxr-xr-xmodules/pam_issue/tst-pam_issue2
-rw-r--r--modules/pam_keyinit/Makefile.am33
-rw-r--r--modules/pam_keyinit/Makefile.in1150
-rw-r--r--modules/pam_keyinit/README67
-rw-r--r--modules/pam_keyinit/README.xml41
-rw-r--r--modules/pam_keyinit/pam_keyinit.8150
-rw-r--r--modules/pam_keyinit/pam_keyinit.8.xml250
-rw-r--r--modules/pam_keyinit/pam_keyinit.c298
-rwxr-xr-xmodules/pam_keyinit/tst-pam_keyinit2
-rw-r--r--modules/pam_lastlog/Makefile.am33
-rw-r--r--modules/pam_lastlog/Makefile.in1150
-rw-r--r--modules/pam_lastlog/README96
-rw-r--r--modules/pam_lastlog/README.xml41
-rw-r--r--modules/pam_lastlog/pam_lastlog.8197
-rw-r--r--modules/pam_lastlog/pam_lastlog.8.xml343
-rw-r--r--modules/pam_lastlog/pam_lastlog.c804
-rwxr-xr-xmodules/pam_lastlog/tst-pam_lastlog2
-rw-r--r--modules/pam_limits/Makefile.am40
-rw-r--r--modules/pam_limits/Makefile.in1227
-rw-r--r--modules/pam_limits/README70
-rw-r--r--modules/pam_limits/README.xml39
-rw-r--r--modules/pam_limits/limits.conf61
-rw-r--r--modules/pam_limits/limits.conf.5349
-rw-r--r--modules/pam_limits/limits.conf.5.xml360
-rw-r--r--modules/pam_limits/pam_limits.8152
-rw-r--r--modules/pam_limits/pam_limits.8.xml257
-rw-r--r--modules/pam_limits/pam_limits.c1215
-rwxr-xr-xmodules/pam_limits/tst-pam_limits2
-rw-r--r--modules/pam_listfile/Makefile.am33
-rw-r--r--modules/pam_listfile/Makefile.in1150
-rw-r--r--modules/pam_listfile/README101
-rw-r--r--modules/pam_listfile/README.xml41
-rw-r--r--modules/pam_listfile/pam_listfile.8211
-rw-r--r--modules/pam_listfile/pam_listfile.8.xml297
-rw-r--r--modules/pam_listfile/pam_listfile.c397
-rwxr-xr-xmodules/pam_listfile/tst-pam_listfile2
-rw-r--r--modules/pam_localuser/Makefile.am36
-rw-r--r--modules/pam_localuser/Makefile.in1181
-rw-r--r--modules/pam_localuser/README38
-rw-r--r--modules/pam_localuser/README.xml41
-rw-r--r--modules/pam_localuser/pam_localuser.8123
-rw-r--r--modules/pam_localuser/pam_localuser.8.xml202
-rw-r--r--modules/pam_localuser/pam_localuser.c126
-rwxr-xr-xmodules/pam_localuser/tst-pam_localuser2
-rw-r--r--modules/pam_localuser/tst-pam_localuser-retval.c144
-rw-r--r--modules/pam_loginuid/Makefile.am33
-rw-r--r--modules/pam_loginuid/Makefile.in1150
-rw-r--r--modules/pam_loginuid/README29
-rw-r--r--modules/pam_loginuid/README.xml36
-rw-r--r--modules/pam_loginuid/pam_loginuid.893
-rw-r--r--modules/pam_loginuid/pam_loginuid.8.xml142
-rw-r--r--modules/pam_loginuid/pam_loginuid.c267
-rwxr-xr-xmodules/pam_loginuid/tst-pam_loginuid2
-rw-r--r--modules/pam_mail/Makefile.am33
-rw-r--r--modules/pam_mail/Makefile.in1150
-rw-r--r--modules/pam_mail/README71
-rw-r--r--modules/pam_mail/README.xml41
-rw-r--r--modules/pam_mail/pam_mail.8159
-rw-r--r--modules/pam_mail/pam_mail.8.xml280
-rw-r--r--modules/pam_mail/pam_mail.c468
-rwxr-xr-xmodules/pam_mail/tst-pam_mail2
-rw-r--r--modules/pam_mkhomedir/Makefile.am44
-rw-r--r--modules/pam_mkhomedir/Makefile.in1280
-rw-r--r--modules/pam_mkhomedir/README36
-rw-r--r--modules/pam_mkhomedir/README.xml36
-rw-r--r--modules/pam_mkhomedir/mkhomedir_helper.863
-rw-r--r--modules/pam_mkhomedir/mkhomedir_helper.8.xml83
-rw-r--r--modules/pam_mkhomedir/mkhomedir_helper.c439
-rw-r--r--modules/pam_mkhomedir/pam_mkhomedir.8135
-rw-r--r--modules/pam_mkhomedir/pam_mkhomedir.8.xml219
-rw-r--r--modules/pam_mkhomedir/pam_mkhomedir.c267
-rwxr-xr-xmodules/pam_mkhomedir/tst-pam_mkhomedir2
-rw-r--r--modules/pam_mkhomedir/tst-pam_mkhomedir-retval.c110
-rw-r--r--modules/pam_motd/Makefile.am33
-rw-r--r--modules/pam_motd/Makefile.in1150
-rw-r--r--modules/pam_motd/README82
-rw-r--r--modules/pam_motd/README.xml41
-rw-r--r--modules/pam_motd/pam_motd.8195
-rw-r--r--modules/pam_motd/pam_motd.8.xml215
-rw-r--r--modules/pam_motd/pam_motd.c445
-rwxr-xr-xmodules/pam_motd/tst-pam_motd2
-rw-r--r--modules/pam_namespace/Makefile.am48
-rw-r--r--modules/pam_namespace/Makefile.in1348
-rw-r--r--modules/pam_namespace/README227
-rw-r--r--modules/pam_namespace/README.xml44
-rw-r--r--modules/pam_namespace/argv_parse.c172
-rw-r--r--modules/pam_namespace/argv_parse.h43
-rw-r--r--modules/pam_namespace/md5.c261
-rw-r--r--modules/pam_namespace/md5.h36
-rw-r--r--modules/pam_namespace/namespace.conf31
-rw-r--r--modules/pam_namespace/namespace.conf.5168
-rw-r--r--modules/pam_namespace/namespace.conf.5.xml223
-rwxr-xr-xmodules/pam_namespace/namespace.init25
-rw-r--r--modules/pam_namespace/pam_namespace.8154
-rw-r--r--modules/pam_namespace/pam_namespace.8.xml381
-rw-r--r--modules/pam_namespace/pam_namespace.c2272
-rw-r--r--modules/pam_namespace/pam_namespace.h192
-rw-r--r--modules/pam_namespace/pam_namespace.service.in11
-rw-r--r--modules/pam_namespace/pam_namespace_helper.849
-rw-r--r--modules/pam_namespace/pam_namespace_helper.8.xml62
-rw-r--r--modules/pam_namespace/pam_namespace_helper.in15
-rwxr-xr-xmodules/pam_namespace/tst-pam_namespace2
-rw-r--r--modules/pam_nologin/Makefile.am36
-rw-r--r--modules/pam_nologin/Makefile.in1181
-rw-r--r--modules/pam_nologin/README41
-rw-r--r--modules/pam_nologin/README.xml46
-rw-r--r--modules/pam_nologin/pam_nologin.8130
-rw-r--r--modules/pam_nologin/pam_nologin.8.xml175
-rw-r--r--modules/pam_nologin/pam_nologin.c163
-rwxr-xr-xmodules/pam_nologin/tst-pam_nologin2
-rw-r--r--modules/pam_nologin/tst-pam_nologin-retval.c226
-rw-r--r--modules/pam_permit/Makefile.am36
-rw-r--r--modules/pam_permit/Makefile.in1180
-rw-r--r--modules/pam_permit/README30
-rw-r--r--modules/pam_permit/README.xml41
-rw-r--r--modules/pam_permit/pam_permit.884
-rw-r--r--modules/pam_permit/pam_permit.8.xml106
-rw-r--r--modules/pam_permit/pam_permit.c84
-rwxr-xr-xmodules/pam_permit/tst-pam_permit2
-rw-r--r--modules/pam_permit/tst-pam_permit-retval.c58
-rw-r--r--modules/pam_pwhistory/Makefile.am45
-rw-r--r--modules/pam_pwhistory/Makefile.in1289
-rw-r--r--modules/pam_pwhistory/README66
-rw-r--r--modules/pam_pwhistory/README.xml41
-rw-r--r--modules/pam_pwhistory/opasswd.c564
-rw-r--r--modules/pam_pwhistory/opasswd.h66
-rw-r--r--modules/pam_pwhistory/pam_pwhistory.8163
-rw-r--r--modules/pam_pwhistory/pam_pwhistory.8.xml247
-rw-r--r--modules/pam_pwhistory/pam_pwhistory.c390
-rw-r--r--modules/pam_pwhistory/pwhistory_helper.854
-rw-r--r--modules/pam_pwhistory/pwhistory_helper.8.xml68
-rw-r--r--modules/pam_pwhistory/pwhistory_helper.c119
-rwxr-xr-xmodules/pam_pwhistory/tst-pam_pwhistory2
-rw-r--r--modules/pam_rhosts/Makefile.am33
-rw-r--r--modules/pam_rhosts/Makefile.in1150
-rw-r--r--modules/pam_rhosts/README56
-rw-r--r--modules/pam_rhosts/README.xml41
-rw-r--r--modules/pam_rhosts/pam_rhosts.8128
-rw-r--r--modules/pam_rhosts/pam_rhosts.8.xml171
-rw-r--r--modules/pam_rhosts/pam_rhosts.c142
-rwxr-xr-xmodules/pam_rhosts/tst-pam_rhosts2
-rw-r--r--modules/pam_rootok/Makefile.am36
-rw-r--r--modules/pam_rootok/Makefile.in1180
-rw-r--r--modules/pam_rootok/README33
-rw-r--r--modules/pam_rootok/README.xml41
-rw-r--r--modules/pam_rootok/pam_rootok.8106
-rw-r--r--modules/pam_rootok/pam_rootok.8.xml131
-rw-r--r--modules/pam_rootok/pam_rootok.c174
-rwxr-xr-xmodules/pam_rootok/tst-pam_rootok2
-rw-r--r--modules/pam_rootok/tst-pam_rootok-retval.c72
-rw-r--r--modules/pam_securetty/Makefile.am33
-rw-r--r--modules/pam_securetty/Makefile.in1150
-rw-r--r--modules/pam_securetty/README42
-rw-r--r--modules/pam_securetty/README.xml41
-rw-r--r--modules/pam_securetty/pam_securetty.8140
-rw-r--r--modules/pam_securetty/pam_securetty.8.xml202
-rw-r--r--modules/pam_securetty/pam_securetty.c286
-rwxr-xr-xmodules/pam_securetty/tst-pam_securetty2
-rw-r--r--modules/pam_selinux/Makefile.am37
-rw-r--r--modules/pam_selinux/Makefile.in1182
-rw-r--r--modules/pam_selinux/README85
-rw-r--r--modules/pam_selinux/README.xml41
-rw-r--r--modules/pam_selinux/pam_selinux.8151
-rw-r--r--modules/pam_selinux/pam_selinux.8.xml276
-rw-r--r--modules/pam_selinux/pam_selinux.c818
-rw-r--r--modules/pam_selinux/pam_selinux_check.835
-rw-r--r--modules/pam_selinux/pam_selinux_check.c161
-rwxr-xr-xmodules/pam_selinux/tst-pam_selinux2
-rw-r--r--modules/pam_sepermit/Makefile.am42
-rw-r--r--modules/pam_sepermit/Makefile.in1234
-rw-r--r--modules/pam_sepermit/README48
-rw-r--r--modules/pam_sepermit/README.xml41
-rw-r--r--modules/pam_sepermit/pam_sepermit.8131
-rw-r--r--modules/pam_sepermit/pam_sepermit.8.xml194
-rw-r--r--modules/pam_sepermit/pam_sepermit.c440
-rw-r--r--modules/pam_sepermit/sepermit.conf11
-rw-r--r--modules/pam_sepermit/sepermit.conf.5117
-rw-r--r--modules/pam_sepermit/sepermit.conf.5.xml110
-rwxr-xr-xmodules/pam_sepermit/tst-pam_sepermit2
-rw-r--r--modules/pam_setquota/Makefile.am29
-rw-r--r--modules/pam_setquota/Makefile.in1146
-rw-r--r--modules/pam_setquota/README80
-rw-r--r--modules/pam_setquota/README.xml41
-rw-r--r--modules/pam_setquota/pam_setquota.8186
-rw-r--r--modules/pam_setquota/pam_setquota.8.xml301
-rw-r--r--modules/pam_setquota/pam_setquota.c389
-rwxr-xr-xmodules/pam_setquota/tst-pam_setquota2
-rw-r--r--modules/pam_shells/Makefile.am33
-rw-r--r--modules/pam_shells/Makefile.in1150
-rw-r--r--modules/pam_shells/README24
-rw-r--r--modules/pam_shells/README.xml41
-rw-r--r--modules/pam_shells/pam_shells.891
-rw-r--r--modules/pam_shells/pam_shells.8.xml117
-rw-r--r--modules/pam_shells/pam_shells.c108
-rwxr-xr-xmodules/pam_shells/tst-pam_shells2
-rw-r--r--modules/pam_stress/Makefile.am32
-rw-r--r--modules/pam_stress/Makefile.in1150
-rw-r--r--modules/pam_stress/README61
-rw-r--r--modules/pam_stress/README.xml31
-rw-r--r--modules/pam_stress/pam_stress.8190
-rw-r--r--modules/pam_stress/pam_stress.8.xml356
-rw-r--r--modules/pam_stress/pam_stress.c534
-rwxr-xr-xmodules/pam_stress/tst-pam_stress2
-rw-r--r--modules/pam_succeed_if/Makefile.am33
-rw-r--r--modules/pam_succeed_if/Makefile.in1150
-rw-r--r--modules/pam_succeed_if/README131
-rw-r--r--modules/pam_succeed_if/README.xml41
-rw-r--r--modules/pam_succeed_if/pam_succeed_if.8226
-rw-r--r--modules/pam_succeed_if/pam_succeed_if.8.xml307
-rw-r--r--modules/pam_succeed_if/pam_succeed_if.c618
-rwxr-xr-xmodules/pam_succeed_if/tst-pam_succeed_if2
-rw-r--r--modules/pam_time/Makefile.am34
-rw-r--r--modules/pam_time/Makefile.in1221
-rw-r--r--modules/pam_time/README35
-rw-r--r--modules/pam_time/README.xml34
-rw-r--r--modules/pam_time/pam_time.8122
-rw-r--r--modules/pam_time/pam_time.8.xml198
-rw-r--r--modules/pam_time/pam_time.c677
-rw-r--r--modules/pam_time/time.conf65
-rw-r--r--modules/pam_time/time.conf.5115
-rw-r--r--modules/pam_time/time.conf.5.xml149
-rwxr-xr-xmodules/pam_time/tst-pam_time2
-rw-r--r--modules/pam_timestamp/Makefile.am60
-rw-r--r--modules/pam_timestamp/Makefile.in1349
-rw-r--r--modules/pam_timestamp/README56
-rw-r--r--modules/pam_timestamp/README.xml46
-rw-r--r--modules/pam_timestamp/hmac_openssl_wrapper.c381
-rw-r--r--modules/pam_timestamp/hmac_openssl_wrapper.h57
-rw-r--r--modules/pam_timestamp/hmacfile.c163
-rw-r--r--modules/pam_timestamp/hmacsha1.c295
-rw-r--r--modules/pam_timestamp/hmacsha1.h15
-rw-r--r--modules/pam_timestamp/pam_timestamp.8135
-rw-r--r--modules/pam_timestamp/pam_timestamp.8.xml208
-rw-r--r--modules/pam_timestamp/pam_timestamp.c873
-rw-r--r--modules/pam_timestamp/pam_timestamp_check.8133
-rw-r--r--modules/pam_timestamp/pam_timestamp_check.8.xml207
-rw-r--r--modules/pam_timestamp/pam_timestamp_check.c42
-rw-r--r--modules/pam_timestamp/sha1.c253
-rw-r--r--modules/pam_timestamp/sha1.h65
-rwxr-xr-xmodules/pam_timestamp/tst-pam_timestamp2
-rw-r--r--modules/pam_tty_audit/Makefile.am32
-rw-r--r--modules/pam_tty_audit/Makefile.in1149
-rw-r--r--modules/pam_tty_audit/README70
-rw-r--r--modules/pam_tty_audit/README.xml41
-rw-r--r--modules/pam_tty_audit/pam_tty_audit.8135
-rw-r--r--modules/pam_tty_audit/pam_tty_audit.8.xml199
-rw-r--r--modules/pam_tty_audit/pam_tty_audit.c450
-rwxr-xr-xmodules/pam_tty_audit/tst-pam_tty_audit2
-rw-r--r--modules/pam_umask/Makefile.am33
-rw-r--r--modules/pam_umask/Makefile.in1150
-rw-r--r--modules/pam_umask/README65
-rw-r--r--modules/pam_umask/README.xml41
-rw-r--r--modules/pam_umask/pam_umask.8176
-rw-r--r--modules/pam_umask/pam_umask.8.xml261
-rw-r--r--modules/pam_umask/pam_umask.c238
-rwxr-xr-xmodules/pam_umask/tst-pam_umask2
-rw-r--r--modules/pam_unix/CHANGELOG54
-rw-r--r--modules/pam_unix/Makefile.am63
-rw-r--r--modules/pam_unix/Makefile.in1537
-rw-r--r--modules/pam_unix/README206
-rw-r--r--modules/pam_unix/README.xml41
-rw-r--r--modules/pam_unix/bigcrypt.c163
-rw-r--r--modules/pam_unix/bigcrypt.h1
-rw-r--r--modules/pam_unix/bigcrypt_main.c18
-rw-r--r--modules/pam_unix/lckpwdf.-c142
-rw-r--r--modules/pam_unix/md5.c258
-rw-r--r--modules/pam_unix/md5.h39
-rw-r--r--modules/pam_unix/md5_broken.c4
-rw-r--r--modules/pam_unix/md5_crypt.c157
-rw-r--r--modules/pam_unix/md5_good.c5
-rw-r--r--modules/pam_unix/pam_unix.8285
-rw-r--r--modules/pam_unix/pam_unix.8.xml501
-rw-r--r--modules/pam_unix/pam_unix_acct.c291
-rw-r--r--modules/pam_unix/pam_unix_auth.c215
-rw-r--r--modules/pam_unix/pam_unix_passwd.c875
-rw-r--r--modules/pam_unix/pam_unix_sess.c134
-rw-r--r--modules/pam_unix/passverify.c1211
-rw-r--r--modules/pam_unix/passverify.h115
-rw-r--r--modules/pam_unix/support.c893
-rw-r--r--modules/pam_unix/support.h182
-rwxr-xr-xmodules/pam_unix/tst-pam_unix2
-rw-r--r--modules/pam_unix/unix_chkpwd.853
-rw-r--r--modules/pam_unix/unix_chkpwd.8.xml67
-rw-r--r--modules/pam_unix/unix_chkpwd.c246
-rw-r--r--modules/pam_unix/unix_update.852
-rw-r--r--modules/pam_unix/unix_update.8.xml67
-rw-r--r--modules/pam_unix/unix_update.c192
-rw-r--r--modules/pam_unix/yppasswd.h51
-rw-r--r--modules/pam_unix/yppasswd_xdr.c40
-rw-r--r--modules/pam_userdb/Makefile.am35
-rw-r--r--modules/pam_userdb/Makefile.in1155
-rw-r--r--modules/pam_userdb/README76
-rw-r--r--modules/pam_userdb/README.xml41
-rw-r--r--modules/pam_userdb/create.pl21
-rw-r--r--modules/pam_userdb/pam_userdb.8158
-rw-r--r--modules/pam_userdb/pam_userdb.8.xml294
-rw-r--r--modules/pam_userdb/pam_userdb.c517
-rw-r--r--modules/pam_userdb/pam_userdb.h59
-rwxr-xr-xmodules/pam_userdb/tst-pam_userdb2
-rw-r--r--modules/pam_usertype/Makefile.am34
-rw-r--r--modules/pam_usertype/Makefile.in1151
-rw-r--r--modules/pam_usertype/README48
-rw-r--r--modules/pam_usertype/README.xml41
-rw-r--r--modules/pam_usertype/pam_usertype.8135
-rw-r--r--modules/pam_usertype/pam_usertype.8.xml199
-rw-r--r--modules/pam_usertype/pam_usertype.c311
-rwxr-xr-xmodules/pam_usertype/tst-pam_usertype2
-rw-r--r--modules/pam_warn/Makefile.am36
-rw-r--r--modules/pam_warn/Makefile.in1180
-rw-r--r--modules/pam_warn/README36
-rw-r--r--modules/pam_warn/README.xml41
-rw-r--r--modules/pam_warn/pam_warn.889
-rw-r--r--modules/pam_warn/pam_warn.8.xml105
-rw-r--r--modules/pam_warn/pam_warn.c92
-rwxr-xr-xmodules/pam_warn/tst-pam_warn2
-rw-r--r--modules/pam_warn/tst-pam_warn-retval.c88
-rw-r--r--modules/pam_wheel/Makefile.am33
-rw-r--r--modules/pam_wheel/Makefile.in1150
-rw-r--r--modules/pam_wheel/README61
-rw-r--r--modules/pam_wheel/README.xml41
-rw-r--r--modules/pam_wheel/pam_wheel.8147
-rw-r--r--modules/pam_wheel/pam_wheel.8.xml243
-rw-r--r--modules/pam_wheel/pam_wheel.c301
-rwxr-xr-xmodules/pam_wheel/tst-pam_wheel2
-rw-r--r--modules/pam_xauth/Makefile.am33
-rw-r--r--modules/pam_xauth/Makefile.in1150
-rw-r--r--modules/pam_xauth/README90
-rw-r--r--modules/pam_xauth/README.xml46
-rw-r--r--modules/pam_xauth/pam_xauth.8183
-rw-r--r--modules/pam_xauth/pam_xauth.8.xml293
-rw-r--r--modules/pam_xauth/pam_xauth.c803
-rwxr-xr-xmodules/pam_xauth/tst-pam_xauth2
457 files changed, 113972 insertions, 0 deletions
diff --git a/modules/Makefile.am b/modules/Makefile.am
new file mode 100644
index 0000000..8da4641
--- /dev/null
+++ b/modules/Makefile.am
@@ -0,0 +1,94 @@
+#
+# Copyright (c) 2005, 2006, 2008 Thorsten Kukuk <kukuk@thkukuk.de>
+#
+
+if COND_BUILD_PAM_KEYINIT
+ MAYBE_PAM_KEYINIT = pam_keyinit
+endif
+
+if COND_BUILD_PAM_LASTLOG
+ MAYBE_PAM_LASTLOG = pam_lastlog
+endif
+
+if COND_BUILD_PAM_NAMESPACE
+ MAYBE_PAM_NAMESPACE = pam_namespace
+endif
+
+if COND_BUILD_PAM_RHOSTS
+ MAYBE_PAM_RHOSTS = pam_rhosts
+endif
+
+if COND_BUILD_PAM_SELINUX
+ MAYBE_PAM_SELINUX = pam_selinux
+endif
+
+if COND_BUILD_PAM_SEPERMIT
+ MAYBE_PAM_SEPERMIT = pam_sepermit
+endif
+
+if COND_BUILD_PAM_SETQUOTA
+ MAYBE_PAM_SETQUOTA = pam_setquota
+endif
+
+if COND_BUILD_PAM_TTY_AUDIT
+ MAYBE_PAM_TTY_AUDIT = pam_tty_audit
+endif
+
+if COND_BUILD_PAM_UNIX
+ MAYBE_PAM_UNIX = pam_unix
+endif
+
+if COND_BUILD_PAM_USERDB
+ MAYBE_PAM_USERDB = pam_userdb
+endif
+
+SUBDIRS := \
+ pam_access \
+ pam_debug \
+ pam_deny \
+ pam_echo \
+ pam_env \
+ pam_exec \
+ pam_faildelay \
+ pam_faillock \
+ pam_filter \
+ pam_ftp \
+ pam_group \
+ pam_issue \
+ $(MAYBE_PAM_KEYINIT) \
+ $(MAYBE_PAM_LASTLOG) \
+ pam_limits \
+ pam_listfile \
+ pam_localuser \
+ pam_loginuid \
+ pam_mail \
+ pam_mkhomedir \
+ pam_motd \
+ $(MAYBE_PAM_NAMESPACE) \
+ pam_nologin \
+ pam_permit \
+ pam_pwhistory \
+ $(MAYBE_PAM_RHOSTS) \
+ pam_rootok \
+ pam_securetty \
+ $(MAYBE_PAM_SELINUX) \
+ $(MAYBE_PAM_SEPERMIT) \
+ $(MAYBE_PAM_SETQUOTA) \
+ pam_shells \
+ pam_stress \
+ pam_succeed_if \
+ pam_time \
+ pam_timestamp \
+ $(MAYBE_PAM_TTY_AUDIT) \
+ pam_umask \
+ $(MAYBE_PAM_UNIX) \
+ $(MAYBE_PAM_USERDB) \
+ pam_usertype \
+ pam_warn \
+ pam_wheel \
+ pam_xauth \
+ #
+
+CLEANFILES = *~
+
+EXTRA_DIST = modules.map
diff --git a/modules/Makefile.in b/modules/Makefile.in
new file mode 100644
index 0000000..98436b0
--- /dev/null
+++ b/modules/Makefile.in
@@ -0,0 +1,767 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2008 Thorsten Kukuk <kukuk@thkukuk.de>
+#
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = modules
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ distdir distdir-am
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = pam_access pam_debug pam_deny pam_echo pam_env pam_exec \
+ pam_faildelay pam_faillock pam_filter pam_ftp pam_group \
+ pam_issue pam_keyinit pam_lastlog pam_limits pam_listfile \
+ pam_localuser pam_loginuid pam_mail pam_mkhomedir pam_motd \
+ pam_namespace pam_nologin pam_permit pam_pwhistory pam_rhosts \
+ pam_rootok pam_securetty pam_selinux pam_sepermit pam_setquota \
+ pam_shells pam_stress pam_succeed_if pam_time pam_timestamp \
+ pam_tty_audit pam_umask pam_unix pam_userdb pam_usertype \
+ pam_warn pam_wheel pam_xauth
+am__DIST_COMMON = $(srcdir)/Makefile.in
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+@COND_BUILD_PAM_KEYINIT_TRUE@MAYBE_PAM_KEYINIT = pam_keyinit
+@COND_BUILD_PAM_LASTLOG_TRUE@MAYBE_PAM_LASTLOG = pam_lastlog
+@COND_BUILD_PAM_NAMESPACE_TRUE@MAYBE_PAM_NAMESPACE = pam_namespace
+@COND_BUILD_PAM_RHOSTS_TRUE@MAYBE_PAM_RHOSTS = pam_rhosts
+@COND_BUILD_PAM_SELINUX_TRUE@MAYBE_PAM_SELINUX = pam_selinux
+@COND_BUILD_PAM_SEPERMIT_TRUE@MAYBE_PAM_SEPERMIT = pam_sepermit
+@COND_BUILD_PAM_SETQUOTA_TRUE@MAYBE_PAM_SETQUOTA = pam_setquota
+@COND_BUILD_PAM_TTY_AUDIT_TRUE@MAYBE_PAM_TTY_AUDIT = pam_tty_audit
+@COND_BUILD_PAM_UNIX_TRUE@MAYBE_PAM_UNIX = pam_unix
+@COND_BUILD_PAM_USERDB_TRUE@MAYBE_PAM_USERDB = pam_userdb
+SUBDIRS := \
+ pam_access \
+ pam_debug \
+ pam_deny \
+ pam_echo \
+ pam_env \
+ pam_exec \
+ pam_faildelay \
+ pam_faillock \
+ pam_filter \
+ pam_ftp \
+ pam_group \
+ pam_issue \
+ $(MAYBE_PAM_KEYINIT) \
+ $(MAYBE_PAM_LASTLOG) \
+ pam_limits \
+ pam_listfile \
+ pam_localuser \
+ pam_loginuid \
+ pam_mail \
+ pam_mkhomedir \
+ pam_motd \
+ $(MAYBE_PAM_NAMESPACE) \
+ pam_nologin \
+ pam_permit \
+ pam_pwhistory \
+ $(MAYBE_PAM_RHOSTS) \
+ pam_rootok \
+ pam_securetty \
+ $(MAYBE_PAM_SELINUX) \
+ $(MAYBE_PAM_SEPERMIT) \
+ $(MAYBE_PAM_SETQUOTA) \
+ pam_shells \
+ pam_stress \
+ pam_succeed_if \
+ pam_time \
+ pam_timestamp \
+ $(MAYBE_PAM_TTY_AUDIT) \
+ pam_umask \
+ $(MAYBE_PAM_UNIX) \
+ $(MAYBE_PAM_USERDB) \
+ pam_usertype \
+ pam_warn \
+ pam_wheel \
+ pam_xauth \
+ #
+
+CLEANFILES = *~
+EXTRA_DIST = modules.map
+all: all-recursive
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-recursive
+all-am: Makefile
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \
+ check-am clean clean-generic clean-libtool cscopelist-am ctags \
+ ctags-am distclean distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ installdirs-am maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags tags-am uninstall uninstall-am
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/modules.map b/modules/modules.map
new file mode 100644
index 0000000..369b047
--- /dev/null
+++ b/modules/modules.map
@@ -0,0 +1,10 @@
+{
+ global:
+ pam_sm_acct_mgmt;
+ pam_sm_authenticate;
+ pam_sm_chauthtok;
+ pam_sm_close_session;
+ pam_sm_open_session;
+ pam_sm_setcred;
+ local: *;
+};
diff --git a/modules/pam_access/Makefile.am b/modules/pam_access/Makefile.am
new file mode 100644
index 0000000..5723dd5
--- /dev/null
+++ b/modules/pam_access/Makefile.am
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@thkukuk.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = access.conf.5 pam_access.8
+endif
+XMLS = README.xml access.conf.5.xml pam_access.8.xml
+dist_check_SCRIPTS = tst-pam_access
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DPAM_ACCESS_CONFIG=\"$(SCONFIGDIR)/access.conf\" \
+ -DACCESS_CONF_GLOB=\"$(SCONFIGDIR)/access.d/*.conf\" $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_access.la
+pam_access_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+dist_secureconf_DATA = access.conf
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_access/Makefile.in b/modules/pam_access/Makefile.in
new file mode 100644
index 0000000..6f9abf4
--- /dev/null
+++ b/modules/pam_access/Makefile.in
@@ -0,0 +1,1222 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@thkukuk.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_access
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(dist_secureconf_DATA) \
+ $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man5dir)" \
+ "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(secureconfdir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_access_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_access_la_SOURCES = pam_access.c
+pam_access_la_OBJECTS = pam_access.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_access.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_access.c
+DIST_SOURCES = pam_access.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man5dir = $(mandir)/man5
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA) $(dist_secureconf_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = access.conf.5 pam_access.8
+XMLS = README.xml access.conf.5.xml pam_access.8.xml
+dist_check_SCRIPTS = tst-pam_access
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DPAM_ACCESS_CONFIG=\"$(SCONFIGDIR)/access.conf\" \
+ -DACCESS_CONF_GLOB=\"$(SCONFIGDIR)/access.d/*.conf\" $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_access.la
+pam_access_la_LIBADD = $(top_builddir)/libpam/libpam.la
+dist_secureconf_DATA = access.conf
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_access/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_access/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_access.la: $(pam_access_la_OBJECTS) $(pam_access_la_DEPENDENCIES) $(EXTRA_pam_access_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_access_la_OBJECTS) $(pam_access_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_access.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man5: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man5dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.5[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man5:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man5dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.5[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir)
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+install-dist_secureconfDATA: $(dist_secureconf_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_secureconf_DATA)'; test -n "$(secureconfdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(secureconfdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(secureconfdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(secureconfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(secureconfdir)" || exit $$?; \
+ done
+
+uninstall-dist_secureconfDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_secureconf_DATA)'; test -n "$(secureconfdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(secureconfdir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_access.log: tst-pam_access
+ @p='tst-pam_access'; \
+ b='tst-pam_access'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(secureconfdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_access.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-dist_secureconfDATA install-man \
+ install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man5 install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_access.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-dist_secureconfDATA uninstall-man \
+ uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man5 uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dist_secureconfDATA install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-man5 install-man8 install-pdf install-pdf-am \
+ install-ps install-ps-am install-securelibLTLIBRARIES \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am recheck tags tags-am uninstall \
+ uninstall-am uninstall-dist_secureconfDATA uninstall-man \
+ uninstall-man5 uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_access/README b/modules/pam_access/README
new file mode 100644
index 0000000..26aad33
--- /dev/null
+++ b/modules/pam_access/README
@@ -0,0 +1,131 @@
+pam_access — PAM module for logdaemon style login access control
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+The pam_access PAM module is mainly for access management. It provides
+logdaemon style login access control based on login names, host or domain
+names, internet addresses or network numbers, or on terminal line names, X
+$DISPLAY values, or PAM service names in case of non-networked logins.
+
+By default rules for access management are taken from config file /etc/security
+/access.conf if you don't specify another file. Then individual *.conf files
+from the /etc/security/access.d/ directory are read. The files are parsed one
+after another in the order of the system locale. The effect of the individual
+files is the same as if all the files were concatenated together in the order
+of parsing. This means that once a pattern is matched in some file no further
+files are parsed. If a config file is explicitly specified with the accessfile
+option the files in the above directory are not parsed.
+
+If Linux PAM is compiled with audit support the module will report when it
+denies access based on origin (host, tty, etc.).
+
+OPTIONS
+
+accessfile=/path/to/access.conf
+
+ Indicate an alternative access.conf style configuration file to override
+ the default. This can be useful when different services need different
+ access lists.
+
+debug
+
+ A lot of debug information is printed with syslog(3).
+
+noaudit
+
+ Do not report logins from disallowed hosts and ttys to the audit subsystem.
+
+fieldsep=separators
+
+ This option modifies the field separator character that pam_access will
+ recognize when parsing the access configuration file. For example: fieldsep
+ =| will cause the default `:' character to be treated as part of a field
+ value and `|' becomes the field separator. Doing this may be useful in
+ conjunction with a system that wants to use pam_access with X based
+ applications, since the PAM_TTY item is likely to be of the form
+ "hostname:0" which includes a `:' character in its value. But you should
+ not need this.
+
+listsep=separators
+
+ This option modifies the list separator character that pam_access will
+ recognize when parsing the access configuration file. For example: listsep
+ =, will cause the default ` ' (space) and `\t' (tab) characters to be
+ treated as part of a list element value and `,' becomes the only list
+ element separator. Doing this may be useful on a system with group
+ information obtained from a Windows domain, where the default built-in
+ groups "Domain Users", "Domain Admins" contain a space.
+
+nodefgroup
+
+ User tokens which are not enclosed in parentheses will not be matched
+ against the group database. The backwards compatible default is to try the
+ group database match even for tokens not enclosed in parentheses.
+
+EXAMPLES
+
+These are some example lines which might be specified in /etc/security/
+access.conf.
+
+User root should be allowed to get access via cron, X11 terminal :0, tty1, ...,
+tty5, tty6.
+
++:root:crond :0 tty1 tty2 tty3 tty4 tty5 tty6
+
+User root should be allowed to get access from hosts which own the IPv4
+addresses. This does not mean that the connection have to be a IPv4 one, a IPv6
+connection from a host with one of this IPv4 addresses does work, too.
+
++:root:192.168.200.1 192.168.200.4 192.168.200.9
+
++:root:127.0.0.1
+
+User root should get access from network 192.168.201. where the term will be
+evaluated by string matching. But it might be better to use network/netmask
+instead. The same meaning of 192.168.201. is 192.168.201.0/24 or 192.168.201.0/
+255.255.255.0.
+
++:root:192.168.201.
+
+User root should be able to have access from hosts foo1.bar.org and
+foo2.bar.org (uses string matching also).
+
++:root:foo1.bar.org foo2.bar.org
+
+User root should be able to have access from domain foo.bar.org (uses string
+matching also).
+
++:root:.foo.bar.org
+
+User root should be denied to get access from all other sources.
+
+-:root:ALL
+
+User foo and members of netgroup admins should be allowed to get access from
+all sources. This will only work if netgroup service is available.
+
++:@admins foo:ALL
+
+User john and foo should get access from IPv6 host address.
+
++:john foo:2001:db8:0:101::1
+
+User john should get access from IPv6 net/mask.
+
++:john:2001:db8:0:101::/64
+
+Members of group wheel should be allowed to get access from all sources.
+
++:(wheel):ALL
+
+Disallow console logins to all but the shutdown, sync and all other accounts,
+which are a member of the wheel group.
+
+-:ALL EXCEPT (wheel) shutdown sync:LOCAL
+
+All other users should be denied to get access from all sources.
+
+-:ALL:ALL
+
diff --git a/modules/pam_access/README.xml b/modules/pam_access/README.xml
new file mode 100644
index 0000000..8c7d078
--- /dev/null
+++ b/modules/pam_access/README.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_access.8.xml">
+-->
+<!--
+<!ENTITY accessconf SYSTEM "access.conf.5.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_access.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_access-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_access.8.xml" xpointer='xpointer(//refsect1[@id = "pam_access-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_access.8.xml" xpointer='xpointer(//refsect1[@id = "pam_access-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="access.conf.5.xml" xpointer='xpointer(//refsect1[@id = "access.conf-examples"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_access/access.conf b/modules/pam_access/access.conf
new file mode 100644
index 0000000..47b6b84
--- /dev/null
+++ b/modules/pam_access/access.conf
@@ -0,0 +1,122 @@
+# Login access control table.
+#
+# Comment line must start with "#", no space at front.
+# Order of lines is important.
+#
+# When someone logs in, the table is scanned for the first entry that
+# matches the (user, host) combination, or, in case of non-networked
+# logins, the first entry that matches the (user, tty) combination. The
+# permissions field of that table entry determines whether the login will
+# be accepted or refused.
+#
+# Format of the login access control table is three fields separated by a
+# ":" character:
+#
+# [Note, if you supply a 'fieldsep=|' argument to the pam_access.so
+# module, you can change the field separation character to be
+# '|'. This is useful for configurations where you are trying to use
+# pam_access with X applications that provide PAM_TTY values that are
+# the display variable like "host:0".]
+#
+# permission:users:origins
+#
+# The first field should be a "+" (access granted) or "-" (access denied)
+# character.
+#
+# The second field should be a list of one or more login names, group
+# names, or ALL (always matches). A pattern of the form user@host is
+# matched when the login name matches the "user" part, and when the
+# "host" part matches the local machine name.
+#
+# The third field should be a list of one or more tty names (for
+# non-networked logins), host names, domain names (begin with "."), host
+# addresses, internet network numbers (end with "."), ALL (always
+# matches), NONE (matches no tty on non-networked logins) or
+# LOCAL (matches any string that does not contain a "." character).
+#
+# You can use @netgroupname in host or user patterns; this even works
+# for @usergroup@@hostgroup patterns.
+#
+# The EXCEPT operator makes it possible to write very compact rules.
+#
+# The group file is searched only when a name does not match that of the
+# logged-in user. Both the user's primary group is matched, as well as
+# groups in which users are explicitly listed.
+# To avoid problems with accounts, which have the same name as a group,
+# you can use brackets around group names '(group)' to differentiate.
+# In this case, you should also set the "nodefgroup" option.
+#
+# TTY NAMES: Must be in the form returned by ttyname(3) less the initial
+# "/dev" (e.g. tty1 or vc/1)
+#
+##############################################################################
+#
+# Disallow non-root logins on tty1
+#
+#-:ALL EXCEPT root:tty1
+#
+# Disallow console logins to all but a few accounts.
+#
+#-:ALL EXCEPT wheel shutdown sync:LOCAL
+#
+# Same, but make sure that really the group wheel and not the user
+# wheel is used (use nodefgroup argument, too):
+#
+#-:ALL EXCEPT (wheel) shutdown sync:LOCAL
+#
+# Disallow non-local logins to privileged accounts (group wheel).
+#
+#-:wheel:ALL EXCEPT LOCAL .win.tue.nl
+#
+# Some accounts are not allowed to login from anywhere:
+#
+#-:wsbscaro wsbsecr wsbspac wsbsym wscosor wstaiwde:ALL
+#
+# All other accounts are allowed to login from anywhere.
+#
+##############################################################################
+# All lines from here up to the end are building a more complex example.
+##############################################################################
+#
+# User "root" should be allowed to get access via cron .. tty5 tty6.
+#+:root:cron crond :0 tty1 tty2 tty3 tty4 tty5 tty6
+#
+# User "root" should be allowed to get access from hosts with ip addresses.
+#+:root:192.168.200.1 192.168.200.4 192.168.200.9
+#+:root:127.0.0.1
+#
+# User "root" should get access from network 192.168.201.
+# This term will be evaluated by string matching.
+# comment: It might be better to use network/netmask instead.
+# The same is 192.168.201.0/24 or 192.168.201.0/255.255.255.0
+#+:root:192.168.201.
+#
+# User "root" should be able to have access from domain.
+# Uses string matching also.
+#+:root:.foo.bar.org
+#
+# User "root" should be denied to get access from all other sources.
+#-:root:ALL
+#
+# User "foo" and members of netgroup "nis_group" should be
+# allowed to get access from all sources.
+# This will only work if netgroup service is available.
+#+:@nis_group foo:ALL
+#
+# User "john" should get access from ipv4 net/mask
+#+:john:127.0.0.0/24
+#
+# User "john" should get access from ipv4 as ipv6 net/mask
+#+:john:::ffff:127.0.0.0/127
+#
+# User "john" should get access from ipv6 host address
+#+:john:2001:4ca0:0:101::1
+#
+# User "john" should get access from ipv6 host address (same as above)
+#+:john:2001:4ca0:0:101:0:0:0:1
+#
+# User "john" should get access from ipv6 net/mask
+#+:john:2001:4ca0:0:101::/64
+#
+# All other users should be denied to get access from all sources.
+#-:ALL:ALL
diff --git a/modules/pam_access/access.conf.5 b/modules/pam_access/access.conf.5
new file mode 100644
index 0000000..3204aed
--- /dev/null
+++ b/modules/pam_access/access.conf.5
@@ -0,0 +1,222 @@
+'\" t
+.\" Title: access.conf
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "ACCESS\&.CONF" "5" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+access.conf \- the login access control table file
+.SH "DESCRIPTION"
+.PP
+The
+/etc/security/access\&.conf
+file specifies (\fIuser/group\fR,
+\fIhost\fR), (\fIuser/group\fR,
+\fInetwork/netmask\fR), (\fIuser/group\fR,
+\fItty\fR), (\fIuser/group\fR,
+\fIX\-$DISPLAY\-value\fR), or (\fIuser/group\fR,
+\fIpam\-service\-name\fR) combinations for which a login will be either accepted or refused\&.
+.PP
+When someone logs in, the file
+access\&.conf
+is scanned for the first entry that matches the (\fIuser/group\fR,
+\fIhost\fR) or (\fIuser/group\fR,
+\fInetwork/netmask\fR) combination, or, in case of non\-networked logins, the first entry that matches the (\fIuser/group\fR,
+\fItty\fR) combination, or in the case of non\-networked logins without a tty, the first entry that matches the (\fIuser/group\fR,
+\fIX\-$DISPLAY\-value\fR) or (\fIuser/group\fR,
+\fIpam\-service\-name/\fR) combination\&. The permissions field of that table entry determines whether the login will be accepted or refused\&.
+.PP
+Each line of the login access control table has three fields separated by a ":" character (colon):
+.PP
+\fIpermission\fR:\fIusers/groups\fR:\fIorigins\fR
+.PP
+The first field, the
+\fIpermission\fR
+field, can be either a "\fI+\fR" character (plus) for access granted or a "\fI\-\fR" character (minus) for access denied\&.
+.PP
+The second field, the
+\fIusers\fR/\fIgroup\fR
+field, should be a list of one or more login names, group names, or
+\fIALL\fR
+(which always matches)\&. To differentiate user entries from group entries, group entries should be written with brackets, e\&.g\&.
+\fI(group)\fR\&.
+.PP
+The third field, the
+\fIorigins\fR
+field, should be a list of one or more tty names (for non\-networked logins), X
+\fI$DISPLAY\fR
+values or PAM service names (for non\-networked logins without a tty), host names, domain names (begin with "\&."), host addresses, internet network numbers (end with "\&."), internet network addresses with network mask (where network mask can be a decimal number or an internet address also),
+\fIALL\fR
+(which always matches) or
+\fILOCAL\fR\&. The
+\fILOCAL\fR
+keyword matches if and only if
+\fBpam_get_item\fR(3), when called with an
+\fIitem_type\fR
+of
+\fIPAM_RHOST\fR, returns
+NULL
+or an empty string (and therefore the
+\fIorigins\fR
+field is compared against the return value of
+\fBpam_get_item\fR(3)
+called with an
+\fIitem_type\fR
+of
+\fIPAM_TTY\fR
+or, absent that,
+\fIPAM_SERVICE\fR)\&.
+.PP
+If supported by the system you can use
+\fI@netgroupname\fR
+in host or user patterns\&. The
+\fI@@netgroupname\fR
+syntax is supported in the user pattern only and it makes the local system hostname to be passed to the netgroup match call in addition to the user name\&. This might not work correctly on some libc implementations causing the match to always fail\&.
+.PP
+The
+\fIEXCEPT\fR
+operator makes it possible to write very compact rules\&.
+.PP
+If the
+\fBnodefgroup\fR
+is not set, the group file is searched when a name does not match that of the logged\-in user\&. Only groups are matched in which users are explicitly listed\&. However the PAM module does not look at the primary group id of a user\&.
+.PP
+The "\fI#\fR" character at start of line (no space at front) can be used to mark this line as a comment line\&.
+.SH "EXAMPLES"
+.PP
+These are some example lines which might be specified in
+/etc/security/access\&.conf\&.
+.PP
+User
+\fIroot\fR
+should be allowed to get access via
+\fIcron\fR, X11 terminal
+\fI:0\fR,
+\fItty1\fR, \&.\&.\&.,
+\fItty5\fR,
+\fItty6\fR\&.
+.PP
++:root:crond :0 tty1 tty2 tty3 tty4 tty5 tty6
+.PP
+User
+\fIroot\fR
+should be allowed to get access from hosts which own the IPv4 addresses\&. This does not mean that the connection have to be a IPv4 one, a IPv6 connection from a host with one of this IPv4 addresses does work, too\&.
+.PP
++:root:192\&.168\&.200\&.1 192\&.168\&.200\&.4 192\&.168\&.200\&.9
+.PP
++:root:127\&.0\&.0\&.1
+.PP
+User
+\fIroot\fR
+should get access from network
+192\&.168\&.201\&.
+where the term will be evaluated by string matching\&. But it might be better to use network/netmask instead\&. The same meaning of
+192\&.168\&.201\&.
+is
+\fI192\&.168\&.201\&.0/24\fR
+or
+\fI192\&.168\&.201\&.0/255\&.255\&.255\&.0\fR\&.
+.PP
++:root:192\&.168\&.201\&.
+.PP
+User
+\fIroot\fR
+should be able to have access from hosts
+\fIfoo1\&.bar\&.org\fR
+and
+\fIfoo2\&.bar\&.org\fR
+(uses string matching also)\&.
+.PP
++:root:foo1\&.bar\&.org foo2\&.bar\&.org
+.PP
+User
+\fIroot\fR
+should be able to have access from domain
+\fIfoo\&.bar\&.org\fR
+(uses string matching also)\&.
+.PP
++:root:\&.foo\&.bar\&.org
+.PP
+User
+\fIroot\fR
+should be denied to get access from all other sources\&.
+.PP
+\-:root:ALL
+.PP
+User
+\fIfoo\fR
+and members of netgroup
+\fIadmins\fR
+should be allowed to get access from all sources\&. This will only work if netgroup service is available\&.
+.PP
++:@admins foo:ALL
+.PP
+User
+\fIjohn\fR
+and
+\fIfoo\fR
+should get access from IPv6 host address\&.
+.PP
++:john foo:2001:db8:0:101::1
+.PP
+User
+\fIjohn\fR
+should get access from IPv6 net/mask\&.
+.PP
++:john:2001:db8:0:101::/64
+.PP
+Members of group
+\fIwheel\fR
+should be allowed to get access from all sources\&.
+.PP
++:(wheel):ALL
+.PP
+Disallow console logins to all but the shutdown, sync and all other accounts, which are a member of the wheel group\&.
+.PP
+\-:ALL EXCEPT (wheel) shutdown sync:LOCAL
+.PP
+All other users should be denied to get access from all sources\&.
+.PP
+\-:ALL:ALL
+.SH "NOTES"
+.PP
+The default separators of list items in a field are space, \*(Aq,\*(Aq, and tabulator characters\&. Thus conveniently if spaces are put at the beginning and the end of the fields they are ignored\&. However if the list separator is changed with the
+\fIlistsep\fR
+option, the spaces will become part of the actual item and the line will be most probably ignored\&. For this reason, it is not recommended to put spaces around the \*(Aq:\*(Aq characters\&.
+.SH "SEE ALSO"
+.PP
+\fBpam_access\fR(8),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHORS"
+.PP
+Original
+\fBlogin.access\fR(5)
+manual was provided by Guido van Rooij which was renamed to
+\fBaccess.conf\fR(5)
+to reflect relation to default config file\&.
+.PP
+Network address / netmask description and example text was introduced by Mike Becher <mike\&.becher@lrz\-muenchen\&.de>\&.
diff --git a/modules/pam_access/access.conf.5.xml b/modules/pam_access/access.conf.5.xml
new file mode 100644
index 0000000..8fdbc31
--- /dev/null
+++ b/modules/pam_access/access.conf.5.xml
@@ -0,0 +1,253 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+ "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
+
+<refentry id="access.conf">
+
+ <refmeta>
+ <refentrytitle>access.conf</refentrytitle>
+ <manvolnum>5</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>access.conf</refname>
+ <refpurpose>the login access control table file</refpurpose>
+ </refnamediv>
+
+
+ <refsect1 id='access.conf-description'>
+ <title>DESCRIPTION</title>
+ <para>
+ The <filename>/etc/security/access.conf</filename> file specifies
+ (<replaceable>user/group</replaceable>, <replaceable>host</replaceable>),
+ (<replaceable>user/group</replaceable>, <replaceable>network/netmask</replaceable>),
+ (<replaceable>user/group</replaceable>, <replaceable>tty</replaceable>),
+ (<replaceable>user/group</replaceable>,
+ <replaceable>X-$DISPLAY-value</replaceable>), or
+ (<replaceable>user/group</replaceable>,
+ <replaceable>pam-service-name</replaceable>)
+ combinations for which a login will be either accepted or refused.
+ </para>
+ <para>
+ When someone logs in, the file <filename>access.conf</filename> is
+ scanned for the first entry that matches the
+ (<replaceable>user/group</replaceable>, <replaceable>host</replaceable>) or
+ (<replaceable>user/group</replaceable>, <replaceable>network/netmask</replaceable>)
+ combination, or, in case of non-networked logins, the first entry
+ that matches the
+ (<replaceable>user/group</replaceable>, <replaceable>tty</replaceable>)
+ combination, or in the case of non-networked logins without a
+ tty, the first entry that matches the
+ (<replaceable>user/group</replaceable>,
+ <replaceable>X-$DISPLAY-value</replaceable>) or
+ (<replaceable>user/group</replaceable>,
+ <replaceable>pam-service-name/</replaceable>)
+ combination. The permissions field of that table entry
+ determines
+ whether the login will be accepted or refused.
+ </para>
+
+ <para>
+ Each line of the login access control table has three fields separated
+ by a ":" character (colon):
+ </para>
+
+ <para>
+ <replaceable>permission</replaceable>:<replaceable>users/groups</replaceable>:<replaceable>origins</replaceable>
+ </para>
+
+
+ <para>
+ The first field, the <replaceable>permission</replaceable> field, can be either a
+ "<emphasis>+</emphasis>" character (plus) for access granted or a
+ "<emphasis>-</emphasis>" character (minus) for access denied.
+ </para>
+
+ <para>
+ The second field, the
+ <replaceable>users</replaceable>/<replaceable>group</replaceable>
+ field, should be a list of one or more login names, group names, or
+ <emphasis>ALL</emphasis> (which always matches). To differentiate
+ user entries from group entries, group entries should be written
+ with brackets, e.g. <emphasis>(group)</emphasis>.
+ </para>
+
+ <para>
+ The third field, the <replaceable>origins</replaceable>
+ field, should be a list of one or more tty names (for non-networked
+ logins), X <varname>$DISPLAY</varname> values or PAM service
+ names (for non-networked logins without a tty), host names,
+ domain names (begin with "."), host addresses,
+ internet network numbers (end with "."), internet network addresses
+ with network mask (where network mask can be a decimal number or an
+ internet address also), <emphasis>ALL</emphasis> (which always matches)
+ or <emphasis>LOCAL</emphasis>. The <emphasis>LOCAL</emphasis>
+ keyword matches if and only if
+ <citerefentry><refentrytitle>pam_get_item</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
+ when called with an <parameter>item_type</parameter> of
+ <emphasis>PAM_RHOST</emphasis>, returns <code>NULL</code> or an
+ empty string (and therefore the
+ <replaceable>origins</replaceable> field is compared against the
+ return value of
+ <citerefentry><refentrytitle>pam_get_item</refentrytitle><manvolnum>3</manvolnum></citerefentry>
+ called with an <parameter>item_type</parameter> of
+ <emphasis>PAM_TTY</emphasis> or, absent that,
+ <emphasis>PAM_SERVICE</emphasis>).
+ </para>
+
+ <para>
+ If supported by the system you can use
+ <emphasis>@netgroupname</emphasis> in host or user patterns. The
+ <emphasis>@@netgroupname</emphasis> syntax is supported in the user
+ pattern only and it makes the local system hostname to be passed
+ to the netgroup match call in addition to the user name. This might not
+ work correctly on some libc implementations causing the match to
+ always fail.
+ </para>
+
+ <para>
+ The <replaceable>EXCEPT</replaceable> operator makes it possible to
+ write very compact rules.
+ </para>
+
+ <para>
+ If the <option>nodefgroup</option> is not set, the group file
+ is searched when a name does not match that of the logged-in
+ user. Only groups are matched in which users are explicitly listed.
+ However the PAM module does not look at the primary group id of a user.
+ </para>
+
+
+ <para>
+ The "<emphasis>#</emphasis>" character at start of line (no space
+ at front) can be used to mark this line as a comment line.
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="access.conf-examples">
+ <title>EXAMPLES</title>
+ <para>
+ These are some example lines which might be specified in
+ <filename>/etc/security/access.conf</filename>.
+ </para>
+
+ <para>
+ User <emphasis>root</emphasis> should be allowed to get access via
+ <emphasis>cron</emphasis>, X11 terminal <emphasis remap='I'>:0</emphasis>,
+ <emphasis>tty1</emphasis>, ..., <emphasis>tty5</emphasis>,
+ <emphasis>tty6</emphasis>.
+ </para>
+ <para>+:root:crond :0 tty1 tty2 tty3 tty4 tty5 tty6</para>
+
+ <para>
+ User <emphasis>root</emphasis> should be allowed to get access from
+ hosts which own the IPv4 addresses. This does not mean that the
+ connection have to be a IPv4 one, a IPv6 connection from a host with
+ one of this IPv4 addresses does work, too.
+ </para>
+ <para>+:root:192.168.200.1 192.168.200.4 192.168.200.9</para>
+ <para>+:root:127.0.0.1</para>
+
+ <para>
+ User <emphasis>root</emphasis> should get access from network
+ <literal>192.168.201.</literal> where the term will be evaluated by
+ string matching. But it might be better to use network/netmask instead.
+ The same meaning of <literal>192.168.201.</literal> is
+ <emphasis>192.168.201.0/24</emphasis> or
+ <emphasis>192.168.201.0/255.255.255.0</emphasis>.
+ </para>
+ <para>+:root:192.168.201.</para>
+
+ <para>
+ User <emphasis>root</emphasis> should be able to have access from hosts
+ <emphasis>foo1.bar.org</emphasis> and <emphasis>foo2.bar.org</emphasis>
+ (uses string matching also).
+ </para>
+ <para>+:root:foo1.bar.org foo2.bar.org</para>
+
+ <para>
+ User <emphasis>root</emphasis> should be able to have access from
+ domain <emphasis>foo.bar.org</emphasis> (uses string matching also).
+ </para>
+ <para>+:root:.foo.bar.org</para>
+
+ <para>
+ User <emphasis>root</emphasis> should be denied to get access
+ from all other sources.
+ </para>
+ <para>-:root:ALL</para>
+
+ <para>
+ User <emphasis>foo</emphasis> and members of netgroup
+ <emphasis>admins</emphasis> should be allowed to get access
+ from all sources. This will only work if netgroup service is available.
+ </para>
+ <para>+:@admins foo:ALL</para>
+
+ <para>
+ User <emphasis>john</emphasis> and <emphasis>foo</emphasis>
+ should get access from IPv6 host address.
+ </para>
+ <para>+:john foo:2001:db8:0:101::1</para>
+
+ <para>
+ User <emphasis>john</emphasis> should get access from IPv6 net/mask.
+ </para>
+ <para>+:john:2001:db8:0:101::/64</para>
+
+ <para>
+ Members of group <emphasis>wheel</emphasis> should be allowed to get access
+ from all sources.
+ </para>
+ <para>+:(wheel):ALL</para>
+
+ <para>
+ Disallow console logins to all but the shutdown, sync and all
+ other accounts, which are a member of the wheel group.
+ </para>
+ <para>-:ALL EXCEPT (wheel) shutdown sync:LOCAL</para>
+
+ <para>
+ All other users should be denied to get access from all sources.
+ </para>
+ <para>-:ALL:ALL</para>
+
+ </refsect1>
+
+ <refsect1 id="access.conf-notes">
+ <title>NOTES</title>
+ <para>
+ The default separators of list items in a field are space, ',', and tabulator
+ characters. Thus conveniently if spaces are put at the beginning and the end of
+ the fields they are ignored. However if the list separator is changed with the
+ <emphasis>listsep</emphasis> option, the spaces will become part of the actual
+ item and the line will be most probably ignored. For this reason, it is not
+ recommended to put spaces around the ':' characters.
+ </para>
+ </refsect1>
+
+ <refsect1 id="access.conf-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry><refentrytitle>pam_access</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id="access.conf-author">
+ <title>AUTHORS</title>
+ <para>
+ Original <citerefentry><refentrytitle>login.access</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ manual was provided by Guido van Rooij which was renamed to
+ <citerefentry><refentrytitle>access.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ to reflect relation to default config file.
+ </para>
+ <para>
+ Network address / netmask description and example text was
+ introduced by Mike Becher &lt;mike.becher@lrz-muenchen.de&gt;.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_access/pam_access.8 b/modules/pam_access/pam_access.8
new file mode 100644
index 0000000..92de516
--- /dev/null
+++ b/modules/pam_access/pam_access.8
@@ -0,0 +1,139 @@
+'\" t
+.\" Title: pam_access
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_ACCESS" "8" "09/03/2021" "Linux-PAM Manual" "Linux-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_access \- PAM module for logdaemon style login access control
+.SH "SYNOPSIS"
+.HP \w'\fBpam_access\&.so\fR\ 'u
+\fBpam_access\&.so\fR [debug] [nodefgroup] [noaudit] [accessfile=\fIfile\fR] [fieldsep=\fIsep\fR] [listsep=\fIsep\fR]
+.SH "DESCRIPTION"
+.PP
+The pam_access PAM module is mainly for access management\&. It provides logdaemon style login access control based on login names, host or domain names, internet addresses or network numbers, or on terminal line names, X
+\fI$DISPLAY\fR
+values, or PAM service names in case of non\-networked logins\&.
+.PP
+By default rules for access management are taken from config file
+/etc/security/access\&.conf
+if you don\*(Aqt specify another file\&. Then individual
+*\&.conf
+files from the
+/etc/security/access\&.d/
+directory are read\&. The files are parsed one after another in the order of the system locale\&. The effect of the individual files is the same as if all the files were concatenated together in the order of parsing\&. This means that once a pattern is matched in some file no further files are parsed\&. If a config file is explicitly specified with the
+\fBaccessfile\fR
+option the files in the above directory are not parsed\&.
+.PP
+If Linux PAM is compiled with audit support the module will report when it denies access based on origin (host, tty, etc\&.)\&.
+.SH "OPTIONS"
+.PP
+\fBaccessfile=\fR\fB\fI/path/to/access\&.conf\fR\fR
+.RS 4
+Indicate an alternative
+access\&.conf
+style configuration file to override the default\&. This can be useful when different services need different access lists\&.
+.RE
+.PP
+\fBdebug\fR
+.RS 4
+A lot of debug information is printed with
+\fBsyslog\fR(3)\&.
+.RE
+.PP
+\fBnoaudit\fR
+.RS 4
+Do not report logins from disallowed hosts and ttys to the audit subsystem\&.
+.RE
+.PP
+\fBfieldsep=\fR\fB\fIseparators\fR\fR
+.RS 4
+This option modifies the field separator character that pam_access will recognize when parsing the access configuration file\&. For example:
+\fBfieldsep=|\fR
+will cause the default `:\*(Aq character to be treated as part of a field value and `|\*(Aq becomes the field separator\&. Doing this may be useful in conjunction with a system that wants to use pam_access with X based applications, since the
+\fBPAM_TTY\fR
+item is likely to be of the form "hostname:0" which includes a `:\*(Aq character in its value\&. But you should not need this\&.
+.RE
+.PP
+\fBlistsep=\fR\fB\fIseparators\fR\fR
+.RS 4
+This option modifies the list separator character that pam_access will recognize when parsing the access configuration file\&. For example:
+\fBlistsep=,\fR
+will cause the default ` \*(Aq (space) and `\et\*(Aq (tab) characters to be treated as part of a list element value and `,\*(Aq becomes the only list element separator\&. Doing this may be useful on a system with group information obtained from a Windows domain, where the default built\-in groups "Domain Users", "Domain Admins" contain a space\&.
+.RE
+.PP
+\fBnodefgroup\fR
+.RS 4
+User tokens which are not enclosed in parentheses will not be matched against the group database\&. The backwards compatible default is to try the group database match even for tokens not enclosed in parentheses\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+All module types (\fBauth\fR,
+\fBaccount\fR,
+\fBpassword\fR
+and
+\fBsession\fR) are provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_SUCCESS
+.RS 4
+Access was granted\&.
+.RE
+.PP
+PAM_PERM_DENIED
+.RS 4
+Access was not granted\&.
+.RE
+.PP
+PAM_IGNORE
+.RS 4
+\fBpam_setcred\fR
+was called which does nothing\&.
+.RE
+.PP
+PAM_ABORT
+.RS 4
+Not all relevant data or options could be gotten\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+The user is not known to the system\&.
+.RE
+.SH "FILES"
+.PP
+/etc/security/access\&.conf
+.RS 4
+Default configuration file
+.RE
+.SH "SEE ALSO"
+.PP
+\fBaccess.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)\&.
+.SH "AUTHORS"
+.PP
+The logdaemon style login access control scheme was designed and implemented by Wietse Venema\&. The pam_access PAM module was developed by Alexei Nogin <alexei@nogin\&.dnttm\&.ru>\&. The IPv6 support and the network(address) / netmask feature was developed and provided by Mike Becher <mike\&.becher@lrz\-muenchen\&.de>\&.
diff --git a/modules/pam_access/pam_access.8.xml b/modules/pam_access/pam_access.8.xml
new file mode 100644
index 0000000..9a6556c
--- /dev/null
+++ b/modules/pam_access/pam_access.8.xml
@@ -0,0 +1,265 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+
+<refentry id='pam_access'>
+
+ <refmeta>
+ <refentrytitle>pam_access</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id='pam_access-name'>
+ <refname>pam_access</refname>
+ <refpurpose>
+ PAM module for logdaemon style login access control
+ </refpurpose>
+ </refnamediv>
+
+<!-- body begins here -->
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_access-cmdsynopsis">
+ <command>pam_access.so</command>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ nodefgroup
+ </arg>
+ <arg choice="opt">
+ noaudit
+ </arg>
+ <arg choice="opt">
+ accessfile=<replaceable>file</replaceable>
+ </arg>
+ <arg choice="opt">
+ fieldsep=<replaceable>sep</replaceable>
+ </arg>
+ <arg choice="opt">
+ listsep=<replaceable>sep</replaceable>
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1 id="pam_access-description">
+ <title>DESCRIPTION</title>
+ <para>
+ The pam_access PAM module is mainly for access management.
+ It provides logdaemon style login access control based on login
+ names, host or domain names, internet addresses or network numbers,
+ or on terminal line names, X <varname>$DISPLAY</varname> values,
+ or PAM service names in case of non-networked logins.
+ </para>
+ <para>
+ By default rules for access management are taken from config file
+ <filename>/etc/security/access.conf</filename> if you don't specify
+ another file.
+ Then individual <filename>*.conf</filename> files from the
+ <filename>/etc/security/access.d/</filename> directory are read.
+ The files are parsed one after another in the order of the system locale.
+ The effect of the individual files is the same as if all the files were
+ concatenated together in the order of parsing. This means that once
+ a pattern is matched in some file no further files are parsed.
+ If a config file is explicitly specified with the <option>accessfile</option>
+ option the files in the above directory are not parsed.
+ </para>
+ <para>
+ If Linux PAM is compiled with audit support the module will report
+ when it denies access based on origin (host, tty, etc.).
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_access-options">
+ <title>OPTIONS</title>
+ <variablelist>
+
+ <varlistentry>
+ <term>
+ <option>accessfile=<replaceable>/path/to/access.conf</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Indicate an alternative <filename>access.conf</filename>
+ style configuration file to override the default. This can
+ be useful when different services need different access lists.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ A lot of debug information is printed with
+ <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>noaudit</option>
+ </term>
+ <listitem>
+ <para>
+ Do not report logins from disallowed hosts and ttys to the audit subsystem.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>fieldsep=<replaceable>separators</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ This option modifies the field separator character that
+ pam_access will recognize when parsing the access
+ configuration file. For example:
+ <emphasis remap='B'>fieldsep=|</emphasis> will cause the
+ default `:' character to be treated as part of a field value
+ and `|' becomes the field separator. Doing this may be
+ useful in conjunction with a system that wants to use
+ pam_access with X based applications, since the
+ <emphasis remap='B'>PAM_TTY</emphasis> item is likely to be
+ of the form "hostname:0" which includes a `:' character in
+ its value. But you should not need this.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>listsep=<replaceable>separators</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ This option modifies the list separator character that
+ pam_access will recognize when parsing the access
+ configuration file. For example:
+ <emphasis remap='B'>listsep=,</emphasis> will cause the
+ default ` ' (space) and `\t' (tab) characters to be treated
+ as part of a list element value and `,' becomes the only
+ list element separator. Doing this may be useful on a system
+ with group information obtained from a Windows domain,
+ where the default built-in groups "Domain Users",
+ "Domain Admins" contain a space.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>nodefgroup</option>
+ </term>
+ <listitem>
+ <para>
+ User tokens which are not enclosed in parentheses will not be
+ matched against the group database. The backwards compatible default is
+ to try the group database match even for tokens not enclosed
+ in parentheses.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_access-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ All module types (<option>auth</option>, <option>account</option>,
+ <option>password</option> and <option>session</option>) are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_access-return_values">
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Access was granted.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_PERM_DENIED</term>
+ <listitem>
+ <para>
+ Access was not granted.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ <function>pam_setcred</function> was called which does nothing.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_ABORT</term>
+ <listitem>
+ <para>
+ Not all relevant data or options could be gotten.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ The user is not known to the system.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_access-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/security/access.conf</filename></term>
+ <listitem>
+ <para>Default configuration file</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_access-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>access.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_access-authors">
+ <title>AUTHORS</title>
+ <para>
+ The logdaemon style login access control scheme was designed and implemented by
+ Wietse Venema.
+ The pam_access PAM module was developed by
+ Alexei Nogin &lt;alexei@nogin.dnttm.ru&gt;.
+ The IPv6 support and the network(address) / netmask feature
+ was developed and provided by Mike Becher &lt;mike.becher@lrz-muenchen.de&gt;.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c
new file mode 100644
index 0000000..277192b
--- /dev/null
+++ b/modules/pam_access/pam_access.c
@@ -0,0 +1,985 @@
+/*
+ * pam_access module
+ *
+ * Written by Alexei Nogin <alexei@nogin.dnttm.ru> 1997/06/15
+ * (I took login_access from logdaemon-5.6 and converted it to PAM
+ * using parts of pam_time code.)
+ *
+ ************************************************************************
+ * Copyright message from logdaemon-5.6 (original file name DISCLAIMER)
+ ************************************************************************
+ * Copyright 1995 by Wietse Venema. All rights reserved. Individual files
+ * may be covered by other copyrights (as noted in the file itself.)
+ *
+ * This material was originally written and compiled by Wietse Venema at
+ * Eindhoven University of Technology, The Netherlands, in 1990, 1991,
+ * 1992, 1993, 1994 and 1995.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this entire copyright notice is duplicated in all such
+ * copies.
+ *
+ * This software is provided "as is" and without any expressed or implied
+ * warranties, including, without limitation, the implied warranties of
+ * merchantability and fitness for any particular purpose.
+ *************************************************************************
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <stdarg.h>
+#include <syslog.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <pwd.h>
+#include <grp.h>
+#include <errno.h>
+#include <ctype.h>
+#include <sys/utsname.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <glob.h>
+#ifdef HAVE_LIBAUDIT
+#include <libaudit.h>
+#endif
+
+#include <security/_pam_macros.h>
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+#include "pam_cc_compat.h"
+#include "pam_inline.h"
+
+/* login_access.c from logdaemon-5.6 with several changes by A.Nogin: */
+
+ /*
+ * This module implements a simple but effective form of login access
+ * control based on login names and on host (or domain) names, internet
+ * addresses (or network numbers), or on terminal line names in case of
+ * non-networked logins. Diagnostics are reported through syslog(3).
+ *
+ * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
+ */
+
+#if !defined(MAXHOSTNAMELEN) || (MAXHOSTNAMELEN < 64)
+#undef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN 256
+#endif
+
+ /* Delimiters for fields and for lists of users, ttys or hosts. */
+
+
+#define ALL 2
+#define YES 1
+#define NO 0
+#define NOMATCH -1
+
+ /*
+ * A structure to bundle up all login-related information to keep the
+ * functional interfaces as generic as possible.
+ */
+struct login_info {
+ const struct passwd *user;
+ const char *from;
+ const char *config_file;
+ const char *hostname;
+ int debug; /* Print debugging messages. */
+ int only_new_group_syntax; /* Only allow group entries of the form "(xyz)" */
+ int noaudit; /* Do not audit denials */
+ const char *fs; /* field separator */
+ const char *sep; /* list-element separator */
+ int from_remote_host; /* If PAM_RHOST was used for from */
+ struct addrinfo *res; /* Cached DNS resolution of from */
+ int gai_rv; /* Cached retval of getaddrinfo */
+};
+
+/* Parse module config arguments */
+
+static int
+parse_args(pam_handle_t *pamh, struct login_info *loginfo,
+ int argc, const char **argv)
+{
+ int i;
+
+ loginfo->noaudit = NO;
+ loginfo->debug = NO;
+ loginfo->only_new_group_syntax = NO;
+ loginfo->fs = ":";
+ loginfo->sep = ", \t";
+ for (i=0; i<argc; ++i) {
+ const char *str;
+
+ if ((str = pam_str_skip_prefix(argv[i], "fieldsep=")) != NULL) {
+
+ /* the admin wants to override the default field separators */
+ loginfo->fs = str;
+
+ } else if ((str = pam_str_skip_prefix(argv[i], "listsep=")) != NULL) {
+
+ /* the admin wants to override the default list separators */
+ loginfo->sep = str;
+
+ } else if ((str = pam_str_skip_prefix(argv[i], "accessfile=")) != NULL) {
+ FILE *fp = fopen(str, "r");
+
+ if (fp) {
+ loginfo->config_file = str;
+ fclose(fp);
+ } else {
+ pam_syslog(pamh, LOG_ERR,
+ "failed to open accessfile=[%s]: %m", str);
+ return 0;
+ }
+
+ } else if (strcmp (argv[i], "debug") == 0) {
+ loginfo->debug = YES;
+ } else if (strcmp (argv[i], "nodefgroup") == 0) {
+ loginfo->only_new_group_syntax = YES;
+ } else if (strcmp (argv[i], "noaudit") == 0) {
+ loginfo->noaudit = YES;
+ } else {
+ pam_syslog(pamh, LOG_ERR, "unrecognized option [%s]", argv[i]);
+ }
+ }
+
+ return 1; /* OK */
+}
+
+/* --- static functions for checking whether the user should be let in --- */
+
+typedef int match_func (pam_handle_t *, char *, struct login_info *);
+
+static int list_match (pam_handle_t *, char *, char *, struct login_info *,
+ match_func *);
+static int user_match (pam_handle_t *, char *, struct login_info *);
+static int group_match (pam_handle_t *, const char *, const char *, int);
+static int from_match (pam_handle_t *, char *, struct login_info *);
+static int remote_match (pam_handle_t *, char *, struct login_info *);
+static int string_match (pam_handle_t *, const char *, const char *, int);
+static int network_netmask_match (pam_handle_t *, const char *, const char *, struct login_info *);
+
+
+/* isipaddr - find out if string provided is an IP address or not */
+
+static int
+isipaddr (const char *string, int *addr_type,
+ struct sockaddr_storage *addr)
+{
+ struct sockaddr_storage local_addr;
+ int is_ip;
+
+ /* We use struct sockaddr_storage addr because
+ * struct in_addr/in6_addr is an integral part
+ * of struct sockaddr and we doesn't want to
+ * use its value.
+ */
+
+ if (addr == NULL)
+ addr = &local_addr;
+
+ memset(addr, 0, sizeof(struct sockaddr_storage));
+
+ /* first ipv4 */
+ if (inet_pton(AF_INET, string, addr) > 0)
+ {
+ if (addr_type != NULL)
+ *addr_type = AF_INET;
+
+ is_ip = YES;
+ }
+ else if (inet_pton(AF_INET6, string, addr) > 0)
+ { /* then ipv6 */
+ if (addr_type != NULL) {
+ *addr_type = AF_INET6;
+ }
+ is_ip = YES;
+ }
+ else
+ is_ip = NO;
+
+ return is_ip;
+}
+
+
+/* are_addresses_equal - translate IP address strings to real IP
+ * addresses and compare them to find out if they are equal.
+ * If netmask was provided it will be used to focus comparison to
+ * relevant bits.
+ */
+static int
+are_addresses_equal (const char *ipaddr0, const char *ipaddr1,
+ const char *netmask)
+{
+ struct sockaddr_storage addr0;
+ struct sockaddr_storage addr1;
+ int addr_type0 = 0;
+ int addr_type1 = 0;
+
+ if (isipaddr (ipaddr0, &addr_type0, &addr0) == NO)
+ return NO;
+
+ if (isipaddr (ipaddr1, &addr_type1, &addr1) == NO)
+ return NO;
+
+ if (addr_type0 != addr_type1)
+ /* different address types */
+ return NO;
+
+ if (netmask != NULL) {
+ /* Got a netmask, so normalize addresses? */
+ struct sockaddr_storage nmask;
+ unsigned char *byte_a, *byte_nm;
+
+ memset(&nmask, 0, sizeof(struct sockaddr_storage));
+ if (inet_pton(addr_type0, netmask, (void *)&nmask) > 0) {
+ unsigned int i;
+ byte_a = (unsigned char *)(&addr0);
+ byte_nm = (unsigned char *)(&nmask);
+ for (i=0; i<sizeof(struct sockaddr_storage); i++) {
+ byte_a[i] = byte_a[i] & byte_nm[i];
+ }
+
+ byte_a = (unsigned char *)(&addr1);
+ byte_nm = (unsigned char *)(&nmask);
+ for (i=0; i<sizeof(struct sockaddr_storage); i++) {
+ byte_a[i] = byte_a[i] & byte_nm[i];
+ }
+ }
+ }
+
+
+ /* Are the two addresses equal? */
+ if (memcmp((void *)&addr0, (void *)&addr1,
+ sizeof(struct sockaddr_storage)) == 0) {
+ return(YES);
+ }
+
+ return(NO);
+}
+
+static char *
+number_to_netmask (long netmask, int addr_type,
+ char *ipaddr_buf, size_t ipaddr_buf_len)
+{
+ /* We use struct sockaddr_storage addr because
+ * struct in_addr/in6_addr is an integral part
+ * of struct sockaddr and we doesn't want to
+ * use its value.
+ */
+ struct sockaddr_storage nmask;
+ unsigned char *byte_nm;
+ const char *ipaddr_dst = NULL;
+ int i, ip_bytes;
+
+ if (netmask == 0) {
+ /* mask 0 is the same like no mask */
+ return(NULL);
+ }
+
+ memset(&nmask, 0, sizeof(struct sockaddr_storage));
+ if (addr_type == AF_INET6) {
+ /* ipv6 address mask */
+ ip_bytes = 16;
+ } else {
+ /* default might be an ipv4 address mask */
+ addr_type = AF_INET;
+ ip_bytes = 4;
+ }
+
+ byte_nm = (unsigned char *)(&nmask);
+ /* translate number to mask */
+ for (i=0; i<ip_bytes; i++) {
+ if (netmask >= 8) {
+ byte_nm[i] = 0xff;
+ netmask -= 8;
+ } else
+ if (netmask > 0) {
+ byte_nm[i] = 0xff << (8 - netmask);
+ break;
+ } else
+ if (netmask <= 0) {
+ break;
+ }
+ }
+
+ /* now generate netmask address string */
+ ipaddr_dst = inet_ntop(addr_type, &nmask, ipaddr_buf, ipaddr_buf_len);
+ if (ipaddr_dst == ipaddr_buf) {
+ return (ipaddr_buf);
+ }
+
+ return (NULL);
+}
+
+/* login_access - match username/group and host/tty with access control file */
+
+static int
+login_access (pam_handle_t *pamh, struct login_info *item)
+{
+ FILE *fp;
+ char line[BUFSIZ];
+ char *perm; /* becomes permission field */
+ char *users; /* becomes list of login names */
+ char *froms; /* becomes list of terminals or hosts */
+ int match = NO;
+#ifdef HAVE_LIBAUDIT
+ int nonall_match = NO;
+#endif
+ int end;
+ int lineno = 0; /* for diagnostics */
+ char *sptr;
+
+ if (item->debug)
+ pam_syslog (pamh, LOG_DEBUG,
+ "login_access: user=%s, from=%s, file=%s",
+ item->user->pw_name,
+ item->from, item->config_file);
+
+ /*
+ * Process the table one line at a time and stop at the first match.
+ * Blank lines and lines that begin with a '#' character are ignored.
+ * Non-comment lines are broken at the ':' character. All fields are
+ * mandatory. The first field should be a "+" or "-" character. A
+ * non-existing table means no access control.
+ */
+
+ if ((fp = fopen(item->config_file, "r"))!=NULL) {
+ while (!match && fgets(line, sizeof(line), fp)) {
+ lineno++;
+ if (line[end = strlen(line) - 1] != '\n') {
+ pam_syslog(pamh, LOG_ERR,
+ "%s: line %d: missing newline or line too long",
+ item->config_file, lineno);
+ continue;
+ }
+ if (line[0] == '#')
+ continue; /* comment line */
+ while (end > 0 && isspace(line[end - 1]))
+ end--;
+ line[end] = 0; /* strip trailing whitespace */
+ if (line[0] == 0) /* skip blank lines */
+ continue;
+
+ /* Allow field separator in last field of froms */
+ if (!(perm = strtok_r(line, item->fs, &sptr))
+ || !(users = strtok_r(NULL, item->fs, &sptr))
+ || !(froms = strtok_r(NULL, "\n", &sptr))) {
+ pam_syslog(pamh, LOG_ERR, "%s: line %d: bad field count",
+ item->config_file, lineno);
+ continue;
+ }
+ if (perm[0] != '+' && perm[0] != '-') {
+ pam_syslog(pamh, LOG_ERR, "%s: line %d: bad first field",
+ item->config_file, lineno);
+ continue;
+ }
+ if (item->debug)
+ pam_syslog (pamh, LOG_DEBUG,
+ "line %d: %s : %s : %s", lineno, perm, users, froms);
+ match = list_match(pamh, users, NULL, item, user_match);
+ if (item->debug)
+ pam_syslog (pamh, LOG_DEBUG, "user_match=%d, \"%s\"",
+ match, item->user->pw_name);
+ if (match) {
+ match = list_match(pamh, froms, NULL, item, from_match);
+#ifdef HAVE_LIBAUDIT
+ if (!match && perm[0] == '+') {
+ nonall_match = YES;
+ }
+#endif
+ if (item->debug)
+ pam_syslog (pamh, LOG_DEBUG,
+ "from_match=%d, \"%s\"", match, item->from);
+ }
+ }
+ (void) fclose(fp);
+ } else if (errno == ENOENT) {
+ /* This is no error. */
+ pam_syslog(pamh, LOG_WARNING, "warning: cannot open %s: %m",
+ item->config_file);
+ } else {
+ pam_syslog(pamh, LOG_ERR, "cannot open %s: %m", item->config_file);
+ return NO;
+ }
+#ifdef HAVE_LIBAUDIT
+ if (!item->noaudit && (match == YES || (match == ALL &&
+ nonall_match == YES)) && line[0] == '-') {
+ pam_modutil_audit_write(pamh, AUDIT_ANOM_LOGIN_LOCATION,
+ "pam_access", 0);
+ }
+#endif
+ if (match == NO)
+ return NOMATCH;
+ if (line[0] == '+')
+ return YES;
+ return NO;
+}
+
+
+/* list_match - match an item against a list of tokens with exceptions */
+
+static int
+list_match(pam_handle_t *pamh, char *list, char *sptr,
+ struct login_info *item, match_func *match_fn)
+{
+ char *tok;
+ int match = NO;
+
+ if (item->debug && list != NULL)
+ pam_syslog (pamh, LOG_DEBUG,
+ "list_match: list=%s, item=%s", list, item->user->pw_name);
+
+ /*
+ * Process tokens one at a time. We have exhausted all possible matches
+ * when we reach an "EXCEPT" token or the end of the list. If we do find
+ * a match, look for an "EXCEPT" list and recurse to determine whether
+ * the match is affected by any exceptions.
+ */
+
+ for (tok = strtok_r(list, item->sep, &sptr); tok != 0;
+ tok = strtok_r(NULL, item->sep, &sptr)) {
+ if (strcasecmp(tok, "EXCEPT") == 0) /* EXCEPT: give up */
+ break;
+ if ((match = (*match_fn) (pamh, tok, item))) /* YES */
+ break;
+ }
+ /* Process exceptions to matches. */
+
+ if (match != NO) {
+ while ((tok = strtok_r(NULL, item->sep, &sptr)) && strcasecmp(tok, "EXCEPT"))
+ /* VOID */ ;
+ if (tok == 0)
+ return match;
+ if (list_match(pamh, NULL, sptr, item, match_fn) == NO)
+ return YES; /* drop special meaning of ALL */
+ }
+ return (NO);
+}
+
+/* netgroup_match - match group against machine or user */
+
+static int
+netgroup_match (pam_handle_t *pamh, const char *netgroup,
+ const char *machine, const char *user, int debug)
+{
+ int retval;
+ char *mydomain = NULL;
+
+#ifdef HAVE_GETDOMAINNAME
+ char domainname_res[256];
+
+ if (getdomainname (domainname_res, sizeof (domainname_res)) == 0)
+ {
+ if (domainname_res[0] != '\0' && strcmp (domainname_res, "(none)") != 0)
+ {
+ mydomain = domainname_res;
+ }
+ }
+#endif
+
+#ifdef HAVE_INNETGR
+ retval = innetgr (netgroup, machine, user, mydomain);
+#else
+ retval = 0;
+ pam_syslog (pamh, LOG_ERR, "pam_access does not have netgroup support");
+#endif
+ if (debug == YES)
+ pam_syslog (pamh, LOG_DEBUG,
+ "netgroup_match: %d (netgroup=%s, machine=%s, user=%s, domain=%s)",
+ retval, netgroup ? netgroup : "NULL",
+ machine ? machine : "NULL",
+ user ? user : "NULL", mydomain ? mydomain : "NULL");
+ return retval;
+}
+
+/* user_match - match a username against one token */
+
+static int
+user_match (pam_handle_t *pamh, char *tok, struct login_info *item)
+{
+ char *string = item->user->pw_name;
+ struct login_info fake_item;
+ char *at;
+ int rv;
+
+ if (item->debug)
+ pam_syslog (pamh, LOG_DEBUG,
+ "user_match: tok=%s, item=%s", tok, string);
+
+ /*
+ * If a token has the magic value "ALL" the match always succeeds.
+ * Otherwise, return YES if the token fully matches the username, if the
+ * token is a group that contains the username, or if the token is the
+ * name of the user's primary group.
+ */
+
+ /* Try to split on a pattern (@*[^@]+)(@+.*) */
+ for (at = tok; *at == '@'; ++at);
+
+ if (tok[0] == '(' && tok[strlen(tok) - 1] == ')') {
+ return (group_match (pamh, tok, string, item->debug));
+ } else if ((at = strchr(at, '@')) != NULL) {
+ /* split user@host pattern */
+ if (item->hostname == NULL)
+ return NO;
+ memcpy (&fake_item, item, sizeof(fake_item));
+ fake_item.from = item->hostname;
+ fake_item.gai_rv = 0;
+ fake_item.res = NULL;
+ fake_item.from_remote_host = 1; /* hostname should be resolvable */
+ *at = 0;
+ if (!user_match (pamh, tok, item))
+ return NO;
+ rv = from_match (pamh, at + 1, &fake_item);
+ if (fake_item.gai_rv == 0 && fake_item.res)
+ freeaddrinfo(fake_item.res);
+ return rv;
+ } else if (tok[0] == '@') { /* netgroup */
+ const char *hostname = NULL;
+ if (tok[1] == '@') { /* add hostname to netgroup match */
+ if (item->hostname == NULL)
+ return NO;
+ ++tok;
+ hostname = item->hostname;
+ }
+ return (netgroup_match (pamh, tok + 1, hostname, string, item->debug));
+ } else if ((rv=string_match (pamh, tok, string, item->debug)) != NO) /* ALL or exact match */
+ return rv;
+ else if (item->only_new_group_syntax == NO &&
+ pam_modutil_user_in_group_nam_nam (pamh,
+ item->user->pw_name, tok))
+ /* try group membership */
+ return YES;
+
+ return NO;
+}
+
+
+/* group_match - match a username against token named group */
+
+static int
+group_match (pam_handle_t *pamh, const char *tok, const char* usr,
+ int debug)
+{
+ char grptok[BUFSIZ];
+
+ if (debug)
+ pam_syslog (pamh, LOG_DEBUG,
+ "group_match: grp=%s, user=%s", tok, usr);
+
+ if (strlen(tok) < 3)
+ return NO;
+
+ /* token is received under the format '(...)' */
+ memset(grptok, 0, BUFSIZ);
+ strncpy(grptok, tok + 1, strlen(tok) - 2);
+
+ if (pam_modutil_user_in_group_nam_nam(pamh, usr, grptok))
+ return YES;
+
+ return NO;
+}
+
+
+/* from_match - match a host or tty against a list of tokens */
+
+static int
+from_match (pam_handle_t *pamh, char *tok, struct login_info *item)
+{
+ const char *string = item->from;
+ int rv;
+
+ if (item->debug)
+ pam_syslog (pamh, LOG_DEBUG,
+ "from_match: tok=%s, item=%s", tok, string);
+
+ /*
+ * If a token has the magic value "ALL" the match always succeeds. Return
+ * YES if the token fully matches the string. If the token is a domain
+ * name, return YES if it matches the last fields of the string. If the
+ * token has the magic value "LOCAL", return YES if the from field was
+ * not taken by PAM_RHOST. If the token is a network number, return YES
+ * if it matches the head of the string.
+ */
+
+ if (string == NULL) {
+ return NO;
+ } else if (tok[0] == '@') { /* netgroup */
+ return (netgroup_match (pamh, tok + 1, string, (char *) 0, item->debug));
+ } else if ((rv = string_match(pamh, tok, string, item->debug)) != NO) {
+ /* ALL or exact match */
+ return rv;
+ } else if (strcasecmp(tok, "LOCAL") == 0) {
+ /* LOCAL matches only local accesses */
+ if (!item->from_remote_host)
+ return YES;
+ return NO;
+ } else if (item->from_remote_host) {
+ return remote_match(pamh, tok, item);
+ }
+ return NO;
+}
+
+static int
+remote_match (pam_handle_t *pamh, char *tok, struct login_info *item)
+{
+ const char *string = item->from;
+ size_t tok_len = strlen(tok);
+ size_t str_len;
+
+ if (tok[0] == '.') { /* domain: match last fields */
+ if ((str_len = strlen(string)) > tok_len
+ && strcasecmp(tok, string + str_len - tok_len) == 0)
+ return YES;
+ } else if (tok[tok_len - 1] == '.') {
+ struct addrinfo hint;
+
+ memset (&hint, '\0', sizeof (hint));
+ hint.ai_flags = AI_CANONNAME;
+ hint.ai_family = AF_INET;
+
+ if (item->gai_rv != 0)
+ return NO;
+ else if (!item->res &&
+ (item->gai_rv = getaddrinfo (string, NULL, &hint, &item->res)) != 0)
+ return NO;
+ else
+ {
+ struct addrinfo *runp = item->res;
+
+ while (runp != NULL)
+ {
+ char buf[INET_ADDRSTRLEN+2];
+
+ if (runp->ai_family == AF_INET)
+ {
+ DIAG_PUSH_IGNORE_CAST_ALIGN;
+ inet_ntop (runp->ai_family,
+ &((struct sockaddr_in *) runp->ai_addr)->sin_addr,
+ buf, sizeof (buf));
+ DIAG_POP_IGNORE_CAST_ALIGN;
+
+ strcat (buf, ".");
+
+ if (strncmp(tok, buf, tok_len) == 0)
+ {
+ return YES;
+ }
+ }
+ runp = runp->ai_next;
+ }
+ }
+ return NO;
+ }
+
+ /* Assume network/netmask with an IP of a host. */
+ return network_netmask_match(pamh, tok, string, item);
+}
+
+/* string_match - match a string against one token */
+
+static int
+string_match (pam_handle_t *pamh, const char *tok, const char *string,
+ int debug)
+{
+
+ if (debug)
+ pam_syslog (pamh, LOG_DEBUG,
+ "string_match: tok=%s, item=%s", tok, string);
+
+ /*
+ * If the token has the magic value "ALL" the match always succeeds.
+ * Otherwise, return YES if the token fully matches the string.
+ * "NONE" token matches NULL string.
+ */
+
+ if (strcasecmp(tok, "ALL") == 0) { /* all: always matches */
+ return (ALL);
+ } else if (string != NULL) {
+ if (strcasecmp(tok, string) == 0) { /* try exact match */
+ return (YES);
+ }
+ } else if (strcasecmp(tok, "NONE") == 0) {
+ return (YES);
+ }
+ return (NO);
+}
+
+
+/* network_netmask_match - match a string against one token
+ * where string is a hostname or ip (v4,v6) address and tok
+ * represents either a single ip (v4,v6) address or a network/netmask
+ */
+static int
+network_netmask_match (pam_handle_t *pamh,
+ const char *tok, const char *string, struct login_info *item)
+{
+ char *netmask_ptr;
+ char netmask_string[MAXHOSTNAMELEN + 1];
+ int addr_type;
+
+ if (item->debug)
+ pam_syslog (pamh, LOG_DEBUG,
+ "network_netmask_match: tok=%s, item=%s", tok, string);
+ /* OK, check if tok is of type addr/mask */
+ if ((netmask_ptr = strchr(tok, '/')) != NULL)
+ {
+ long netmask = 0;
+
+ /* YES */
+ *netmask_ptr = 0;
+ netmask_ptr++;
+
+ if (isipaddr(tok, &addr_type, NULL) == NO)
+ { /* no netaddr */
+ return NO;
+ }
+
+ /* check netmask */
+ if (isipaddr(netmask_ptr, NULL, NULL) == NO)
+ { /* netmask as integre value */
+ char *endptr = NULL;
+ netmask = strtol(netmask_ptr, &endptr, 0);
+ if ((endptr == netmask_ptr) || (*endptr != '\0'))
+ { /* invalid netmask value */
+ return NO;
+ }
+ if ((netmask < 0)
+ || (addr_type == AF_INET && netmask > 32)
+ || (addr_type == AF_INET6 && netmask > 128))
+ { /* netmask value out of range */
+ return NO;
+ }
+
+ netmask_ptr = number_to_netmask(netmask, addr_type,
+ netmask_string, MAXHOSTNAMELEN);
+ }
+ }
+ else
+ /* NO, then check if it is only an addr */
+ if (isipaddr(tok, NULL, NULL) != YES)
+ {
+ return NO;
+ }
+
+ if (isipaddr(string, NULL, NULL) != YES)
+ {
+ /* Assume network/netmask with a name of a host. */
+ struct addrinfo hint;
+
+ memset (&hint, '\0', sizeof (hint));
+ hint.ai_flags = AI_CANONNAME;
+ hint.ai_family = AF_UNSPEC;
+
+ if (item->gai_rv != 0)
+ return NO;
+ else if (!item->res &&
+ (item->gai_rv = getaddrinfo (string, NULL, &hint, &item->res)) != 0)
+ return NO;
+ else
+ {
+ struct addrinfo *runp = item->res;
+
+ while (runp != NULL)
+ {
+ char buf[INET6_ADDRSTRLEN];
+
+ DIAG_PUSH_IGNORE_CAST_ALIGN;
+ inet_ntop (runp->ai_family,
+ runp->ai_family == AF_INET
+ ? (void *) &((struct sockaddr_in *) runp->ai_addr)->sin_addr
+ : (void *) &((struct sockaddr_in6 *) runp->ai_addr)->sin6_addr,
+ buf, sizeof (buf));
+ DIAG_POP_IGNORE_CAST_ALIGN;
+
+ if (are_addresses_equal(buf, tok, netmask_ptr))
+ {
+ return YES;
+ }
+ runp = runp->ai_next;
+ }
+ }
+ }
+ else
+ return (are_addresses_equal(string, tok, netmask_ptr));
+
+ return NO;
+}
+
+
+/* --- public PAM management functions --- */
+
+int
+pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ struct login_info loginfo;
+ const char *user=NULL;
+ const void *void_from=NULL;
+ const char *from;
+ const char *default_config = PAM_ACCESS_CONFIG;
+ struct passwd *user_pw;
+ char hostname[MAXHOSTNAMELEN + 1];
+ int rv;
+
+
+ /* set username */
+
+ if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE, "cannot determine user name");
+ return PAM_USER_UNKNOWN;
+ }
+
+ if ((user_pw=pam_modutil_getpwnam(pamh, user))==NULL)
+ return (PAM_USER_UNKNOWN);
+
+ /*
+ * Bundle up the arguments to avoid unnecessary clumsiness later on.
+ */
+ memset(&loginfo, '\0', sizeof(loginfo));
+ loginfo.user = user_pw;
+ loginfo.config_file = default_config;
+
+ /* parse the argument list */
+
+ if (!parse_args(pamh, &loginfo, argc, argv)) {
+ pam_syslog(pamh, LOG_ERR, "failed to parse the module arguments");
+ return PAM_ABORT;
+ }
+
+ /* remote host name */
+
+ if (pam_get_item(pamh, PAM_RHOST, &void_from)
+ != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR, "cannot find the remote host name");
+ return PAM_ABORT;
+ }
+ from = void_from;
+
+ if ((from==NULL) || (*from=='\0')) {
+
+ /* local login, set tty name */
+
+ loginfo.from_remote_host = 0;
+
+ if (pam_get_item(pamh, PAM_TTY, &void_from) != PAM_SUCCESS
+ || void_from == NULL) {
+ D(("PAM_TTY not set, probing stdin"));
+ from = ttyname(STDIN_FILENO);
+ if (from != NULL) {
+ if (pam_set_item(pamh, PAM_TTY, from) != PAM_SUCCESS)
+ pam_syslog(pamh, LOG_WARNING, "couldn't set tty name");
+ } else {
+ if (pam_get_item(pamh, PAM_SERVICE, &void_from) != PAM_SUCCESS
+ || void_from == NULL) {
+ pam_syslog (pamh, LOG_ERR,
+ "cannot determine remote host, tty or service name");
+ return PAM_ABORT;
+ }
+ from = void_from;
+ if (loginfo.debug)
+ pam_syslog (pamh, LOG_DEBUG,
+ "cannot determine tty or remote hostname, using service %s",
+ from);
+ }
+ }
+ else
+ from = void_from;
+
+ if (from[0] == '/') { /* full path, remove device path. */
+ const char *f;
+ from++;
+ if ((f = strchr(from, '/')) != NULL) {
+ from = f + 1;
+ }
+ }
+ }
+ else
+ loginfo.from_remote_host = 1;
+
+ loginfo.from = from;
+
+ hostname[sizeof(hostname)-1] = '\0';
+ if (gethostname(hostname, sizeof(hostname)-1) == 0)
+ loginfo.hostname = hostname;
+ else {
+ pam_syslog (pamh, LOG_ERR, "gethostname failed: %m");
+ loginfo.hostname = NULL;
+ }
+
+ rv = login_access(pamh, &loginfo);
+
+ if (rv == NOMATCH && loginfo.config_file == default_config) {
+ glob_t globbuf;
+ int i, glob_rv;
+
+ /* We do not manipulate locale as setlocale() is not
+ * thread safe. We could use uselocale() in future.
+ */
+ glob_rv = glob(ACCESS_CONF_GLOB, GLOB_ERR, NULL, &globbuf);
+ if (!glob_rv) {
+ /* Parse the *.conf files. */
+ for (i = 0; globbuf.gl_pathv[i] != NULL; i++) {
+ loginfo.config_file = globbuf.gl_pathv[i];
+ rv = login_access(pamh, &loginfo);
+ if (rv != NOMATCH)
+ break;
+ }
+ globfree(&globbuf);
+ }
+ }
+
+ if (loginfo.gai_rv == 0 && loginfo.res)
+ freeaddrinfo(loginfo.res);
+
+ if (rv) {
+ return (PAM_SUCCESS);
+ } else {
+ pam_syslog(pamh, LOG_ERR,
+ "access denied for user `%s' from `%s'",user,from);
+ return (PAM_PERM_DENIED);
+ }
+}
+
+int
+pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_IGNORE;
+}
+
+int
+pam_sm_acct_mgmt (pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ return pam_sm_authenticate (pamh, flags, argc, argv);
+}
+
+int
+pam_sm_open_session(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+int
+pam_sm_close_session(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+int
+pam_sm_chauthtok(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+/* end of module definition */
diff --git a/modules/pam_access/tst-pam_access b/modules/pam_access/tst-pam_access
new file mode 100755
index 0000000..271e69f
--- /dev/null
+++ b/modules/pam_access/tst-pam_access
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_access.so
diff --git a/modules/pam_debug/Makefile.am b/modules/pam_debug/Makefile.am
new file mode 100644
index 0000000..8aa6305
--- /dev/null
+++ b/modules/pam_debug/Makefile.am
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@thkukuk.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_debug.8
+endif
+XMLS = README.xml pam_debug.8.xml
+dist_check_SCRIPTS = tst-pam_debug
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_debug.la
+pam_debug_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+check_PROGRAMS = tst-pam_debug-retval
+tst_pam_debug_retval_LDADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_debug/Makefile.in b/modules/pam_debug/Makefile.in
new file mode 100644
index 0000000..ba2cc79
--- /dev/null
+++ b/modules/pam_debug/Makefile.in
@@ -0,0 +1,1180 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@thkukuk.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+check_PROGRAMS = tst-pam_debug-retval$(EXEEXT)
+subdir = modules/pam_debug
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_debug_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_debug_la_SOURCES = pam_debug.c
+pam_debug_la_OBJECTS = pam_debug.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+tst_pam_debug_retval_SOURCES = tst-pam_debug-retval.c
+tst_pam_debug_retval_OBJECTS = tst-pam_debug-retval.$(OBJEXT)
+tst_pam_debug_retval_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_debug.Plo \
+ ./$(DEPDIR)/tst-pam_debug-retval.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_debug.c tst-pam_debug-retval.c
+DIST_SOURCES = pam_debug.c tst-pam_debug-retval.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_debug.8
+XMLS = README.xml pam_debug.8.xml
+dist_check_SCRIPTS = tst-pam_debug
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_debug.la
+pam_debug_la_LIBADD = $(top_builddir)/libpam/libpam.la
+tst_pam_debug_retval_LDADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_debug/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_debug/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_debug.la: $(pam_debug_la_OBJECTS) $(pam_debug_la_DEPENDENCIES) $(EXTRA_pam_debug_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_debug_la_OBJECTS) $(pam_debug_la_LIBADD) $(LIBS)
+
+tst-pam_debug-retval$(EXEEXT): $(tst_pam_debug_retval_OBJECTS) $(tst_pam_debug_retval_DEPENDENCIES) $(EXTRA_tst_pam_debug_retval_DEPENDENCIES)
+ @rm -f tst-pam_debug-retval$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tst_pam_debug_retval_OBJECTS) $(tst_pam_debug_retval_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_debug.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-pam_debug-retval.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_debug.log: tst-pam_debug
+ @p='tst-pam_debug'; \
+ b='tst-pam_debug'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+tst-pam_debug-retval.log: tst-pam_debug-retval$(EXEEXT)
+ @p='tst-pam_debug-retval$(EXEEXT)'; \
+ b='tst-pam_debug-retval'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) \
+ $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_debug.Plo
+ -rm -f ./$(DEPDIR)/tst-pam_debug-retval.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_debug.Plo
+ -rm -f ./$(DEPDIR)/tst-pam_debug-retval.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_debug/README b/modules/pam_debug/README
new file mode 100644
index 0000000..4afff11
--- /dev/null
+++ b/modules/pam_debug/README
@@ -0,0 +1,64 @@
+pam_debug — PAM module to debug the PAM stack
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+The pam_debug PAM module is intended as a debugging aide for determining how
+the PAM stack is operating. This module returns what its module arguments tell
+it to return.
+
+OPTIONS
+
+auth=value
+
+ The pam_sm_authenticate(3) function will return value.
+
+cred=value
+
+ The pam_sm_setcred(3) function will return value.
+
+acct=value
+
+ The pam_sm_acct_mgmt(3) function will return value.
+
+prechauthtok=value
+
+ The pam_sm_chauthtok(3) function will return value if the PAM_PRELIM_CHECK
+ flag is set.
+
+chauthtok=value
+
+ The pam_sm_chauthtok(3) function will return value if the PAM_PRELIM_CHECK
+ flag is not set.
+
+open_session=value
+
+ The pam_sm_open_session(3) function will return value.
+
+close_session=value
+
+ The pam_sm_close_session(3) function will return value.
+
+Where value can be one of: success, open_err, symbol_err, service_err,
+system_err, buf_err, perm_denied, auth_err, cred_insufficient,
+authinfo_unavail, user_unknown, maxtries, new_authtok_reqd, acct_expired,
+session_err, cred_unavail, cred_expired, cred_err, no_module_data, conv_err,
+authtok_err, authtok_recover_err, authtok_lock_busy, authtok_disable_aging,
+try_again, ignore, abort, authtok_expired, module_unknown, bad_item,
+conv_again, incomplete.
+
+EXAMPLES
+
+auth requisite pam_permit.so
+auth [success=2 default=ok] pam_debug.so auth=perm_denied cred=success
+auth [default=reset] pam_debug.so auth=success cred=perm_denied
+auth [success=done default=die] pam_debug.so
+auth optional pam_debug.so auth=perm_denied cred=perm_denied
+auth sufficient pam_debug.so auth=success cred=success
+
+
+AUTHOR
+
+pam_debug was written by Andrew G. Morgan <morgan@kernel.org>.
+
diff --git a/modules/pam_debug/README.xml b/modules/pam_debug/README.xml
new file mode 100644
index 0000000..ef41911
--- /dev/null
+++ b/modules/pam_debug/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_debug.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_debug.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_debug-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_debug.8.xml" xpointer='xpointer(//refsect1[@id = "pam_debug-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_debug.8.xml" xpointer='xpointer(//refsect1[@id = "pam_debug-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_debug.8.xml" xpointer='xpointer(//refsect1[@id = "pam_debug-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_debug.8.xml" xpointer='xpointer(//refsect1[@id = "pam_debug-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_debug/pam_debug.8 b/modules/pam_debug/pam_debug.8
new file mode 100644
index 0000000..b3e68e2
--- /dev/null
+++ b/modules/pam_debug/pam_debug.8
@@ -0,0 +1,144 @@
+'\" t
+.\" Title: pam_debug
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_DEBUG" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_debug \- PAM module to debug the PAM stack
+.SH "SYNOPSIS"
+.HP \w'\fBpam_debug\&.so\fR\ 'u
+\fBpam_debug\&.so\fR [auth=\fIvalue\fR] [cred=\fIvalue\fR] [acct=\fIvalue\fR] [prechauthtok=\fIvalue\fR] [chauthtok=\fIvalue\fR] [auth=\fIvalue\fR] [open_session=\fIvalue\fR] [close_session=\fIvalue\fR]
+.SH "DESCRIPTION"
+.PP
+The pam_debug PAM module is intended as a debugging aide for determining how the PAM stack is operating\&. This module returns what its module arguments tell it to return\&.
+.SH "OPTIONS"
+.PP
+\fBauth=\fR\fB\fIvalue\fR\fR
+.RS 4
+The
+\fBpam_sm_authenticate\fR(3)
+function will return
+\fIvalue\fR\&.
+.RE
+.PP
+\fBcred=\fR\fB\fIvalue\fR\fR
+.RS 4
+The
+\fBpam_sm_setcred\fR(3)
+function will return
+\fIvalue\fR\&.
+.RE
+.PP
+\fBacct=\fR\fB\fIvalue\fR\fR
+.RS 4
+The
+\fBpam_sm_acct_mgmt\fR(3)
+function will return
+\fIvalue\fR\&.
+.RE
+.PP
+\fBprechauthtok=\fR\fB\fIvalue\fR\fR
+.RS 4
+The
+\fBpam_sm_chauthtok\fR(3)
+function will return
+\fIvalue\fR
+if the
+\fIPAM_PRELIM_CHECK\fR
+flag is set\&.
+.RE
+.PP
+\fBchauthtok=\fR\fB\fIvalue\fR\fR
+.RS 4
+The
+\fBpam_sm_chauthtok\fR(3)
+function will return
+\fIvalue\fR
+if the
+\fIPAM_PRELIM_CHECK\fR
+flag is
+\fBnot\fR
+set\&.
+.RE
+.PP
+\fBopen_session=\fR\fB\fIvalue\fR\fR
+.RS 4
+The
+\fBpam_sm_open_session\fR(3)
+function will return
+\fIvalue\fR\&.
+.RE
+.PP
+\fBclose_session=\fR\fB\fIvalue\fR\fR
+.RS 4
+The
+\fBpam_sm_close_session\fR(3)
+function will return
+\fIvalue\fR\&.
+.RE
+.PP
+Where
+\fIvalue\fR
+can be one of: success, open_err, symbol_err, service_err, system_err, buf_err, perm_denied, auth_err, cred_insufficient, authinfo_unavail, user_unknown, maxtries, new_authtok_reqd, acct_expired, session_err, cred_unavail, cred_expired, cred_err, no_module_data, conv_err, authtok_err, authtok_recover_err, authtok_lock_busy, authtok_disable_aging, try_again, ignore, abort, authtok_expired, module_unknown, bad_item, conv_again, incomplete\&.
+.SH "MODULE TYPES PROVIDED"
+.PP
+All module types (\fBauth\fR,
+\fBaccount\fR,
+\fBpassword\fR
+and
+\fBsession\fR) are provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_SUCCESS
+.RS 4
+Default return code if no other value was specified, else specified return value\&.
+.RE
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+auth requisite pam_permit\&.so
+auth [success=2 default=ok] pam_debug\&.so auth=perm_denied cred=success
+auth [default=reset] pam_debug\&.so auth=success cred=perm_denied
+auth [success=done default=die] pam_debug\&.so
+auth optional pam_debug\&.so auth=perm_denied cred=perm_denied
+auth sufficient pam_debug\&.so auth=success cred=success
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+.PP
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_debug was written by Andrew G\&. Morgan <morgan@kernel\&.org>\&.
diff --git a/modules/pam_debug/pam_debug.8.xml b/modules/pam_debug/pam_debug.8.xml
new file mode 100644
index 0000000..3d85f4d
--- /dev/null
+++ b/modules/pam_debug/pam_debug.8.xml
@@ -0,0 +1,231 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_debug">
+
+ <refmeta>
+ <refentrytitle>pam_debug</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_debug-name">
+ <refname>pam_debug</refname>
+ <refpurpose>PAM module to debug the PAM stack</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_debug-cmdsynopsis">
+ <command>pam_debug.so</command>
+ <arg choice="opt">
+ auth=<replaceable>value</replaceable>
+ </arg>
+ <arg choice="opt">
+ cred=<replaceable>value</replaceable>
+ </arg>
+ <arg choice="opt">
+ acct=<replaceable>value</replaceable>
+ </arg>
+ <arg choice="opt">
+ prechauthtok=<replaceable>value</replaceable>
+ </arg>
+ <arg choice="opt">
+ chauthtok=<replaceable>value</replaceable>
+ </arg>
+ <arg choice="opt">
+ auth=<replaceable>value</replaceable>
+ </arg>
+ <arg choice="opt">
+ open_session=<replaceable>value</replaceable>
+ </arg>
+ <arg choice="opt">
+ close_session=<replaceable>value</replaceable>
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_debug-description">
+ <title>DESCRIPTION</title>
+ <para>
+ The pam_debug PAM module is intended as a debugging aide for
+ determining how the PAM stack is operating. This module returns
+ what its module arguments tell it to return.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_debug-options">
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>auth=<replaceable>value</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The
+ <citerefentry>
+ <refentrytitle>pam_sm_authenticate</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry> function will return
+ <replaceable>value</replaceable>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>cred=<replaceable>value</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The
+ <citerefentry>
+ <refentrytitle>pam_sm_setcred</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry> function will return
+ <replaceable>value</replaceable>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>acct=<replaceable>value</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The
+ <citerefentry>
+ <refentrytitle>pam_sm_acct_mgmt</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry> function will return
+ <replaceable>value</replaceable>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>prechauthtok=<replaceable>value</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The
+ <citerefentry>
+ <refentrytitle>pam_sm_chauthtok</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry> function will return
+ <replaceable>value</replaceable> if the
+ <emphasis>PAM_PRELIM_CHECK</emphasis> flag is set.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>chauthtok=<replaceable>value</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The
+ <citerefentry>
+ <refentrytitle>pam_sm_chauthtok</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry> function will return
+ <replaceable>value</replaceable> if the
+ <emphasis>PAM_PRELIM_CHECK</emphasis> flag is
+ <emphasis remap='B'>not</emphasis> set.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>open_session=<replaceable>value</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The
+ <citerefentry>
+ <refentrytitle>pam_sm_open_session</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry> function will return
+ <replaceable>value</replaceable>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>close_session=<replaceable>value</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The
+ <citerefentry>
+ <refentrytitle>pam_sm_close_session</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry> function will return
+ <replaceable>value</replaceable>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+ Where <replaceable>value</replaceable> can be one of: success,
+ open_err, symbol_err, service_err, system_err, buf_err, perm_denied,
+ auth_err, cred_insufficient, authinfo_unavail, user_unknown,
+ maxtries, new_authtok_reqd, acct_expired, session_err, cred_unavail,
+ cred_expired, cred_err, no_module_data, conv_err, authtok_err,
+ authtok_recover_err, authtok_lock_busy, authtok_disable_aging,
+ try_again, ignore, abort, authtok_expired, module_unknown,
+ bad_item, conv_again, incomplete.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_debug-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ All module types (<option>auth</option>, <option>account</option>,
+ <option>password</option> and <option>session</option>) are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_debug-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Default return code if no other value was specified,
+ else specified return value.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_debug-examples'>
+ <title>EXAMPLES</title>
+ <programlisting>
+auth requisite pam_permit.so
+auth [success=2 default=ok] pam_debug.so auth=perm_denied cred=success
+auth [default=reset] pam_debug.so auth=success cred=perm_denied
+auth [success=done default=die] pam_debug.so
+auth optional pam_debug.so auth=perm_denied cred=perm_denied
+auth sufficient pam_debug.so auth=success cred=success
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id='pam_debug-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_debug-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_debug was written by Andrew G. Morgan &lt;morgan@kernel.org&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_debug/pam_debug.c b/modules/pam_debug/pam_debug.c
new file mode 100644
index 0000000..414806b
--- /dev/null
+++ b/modules/pam_debug/pam_debug.c
@@ -0,0 +1,108 @@
+/*
+ * pam_debug module
+ *
+ * Written by Andrew Morgan <morgan@kernel.org> 2001/02/04
+ *
+ * This module is intended as a debugging aide for determining how
+ * the PAM stack is operating.
+ */
+
+#include "config.h"
+#include <stdio.h>
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+#include <security/pam_ext.h>
+
+#define _PAM_ACTION_UNDEF (-10)
+#include "../../libpam/pam_tokens.h"
+
+#define DEFAULT_USER "nobody"
+
+/* --- authentication management functions --- */
+
+static int state(pam_handle_t *pamh, const char *text)
+{
+ int retval;
+
+ retval = pam_info (pamh, "%s", text);
+
+ if (retval != PAM_SUCCESS) {
+ D(("pam_info failed"));
+ }
+
+ return retval;
+}
+
+static int parse_args(int retval, const char *event,
+ pam_handle_t *pamh, int argc, const char **argv)
+{
+ int i;
+
+ for (i=0; i<argc; ++i) {
+ int length = strlen(event);
+ if (!strncmp(event, argv[i], length) && (argv[i][length] == '=')) {
+ int j;
+ const char *return_string = argv[i] + (length+1);
+
+ for (j=0; j<_PAM_RETURN_VALUES; ++j) {
+ if (!strcmp(return_string, _pam_token_returns[j])) {
+ retval = j;
+ state(pamh, argv[i]);
+ break;
+ }
+ }
+ break;
+ }
+ }
+
+ return retval;
+}
+
+int pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ return parse_args(PAM_SUCCESS, "auth", pamh, argc, argv);
+}
+
+int pam_sm_setcred(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ return parse_args(PAM_SUCCESS, "cred", pamh, argc, argv);
+}
+
+/* --- account management functions --- */
+
+int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ return parse_args(PAM_SUCCESS, "acct", pamh, argc, argv);
+}
+
+/* --- password management --- */
+
+int pam_sm_chauthtok(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ if (flags & PAM_PRELIM_CHECK) {
+ return parse_args(PAM_SUCCESS, "prechauthtok", pamh, argc, argv);
+ } else {
+ return parse_args(PAM_SUCCESS, "chauthtok", pamh, argc, argv);
+ }
+}
+
+/* --- session management --- */
+
+int pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ return parse_args(PAM_SUCCESS, "open_session", pamh, argc, argv);
+}
+
+int pam_sm_close_session(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ return parse_args(PAM_SUCCESS, "close_session", pamh, argc, argv);
+}
+
+/* end of module definition */
diff --git a/modules/pam_debug/tst-pam_debug b/modules/pam_debug/tst-pam_debug
new file mode 100755
index 0000000..f07ff64
--- /dev/null
+++ b/modules/pam_debug/tst-pam_debug
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_debug.so
diff --git a/modules/pam_debug/tst-pam_debug-retval.c b/modules/pam_debug/tst-pam_debug-retval.c
new file mode 100644
index 0000000..6d3edf8
--- /dev/null
+++ b/modules/pam_debug/tst-pam_debug-retval.c
@@ -0,0 +1,65 @@
+/*
+ * Check pam_debug return values.
+ *
+ * Copyright (c) 2020 Dmitry V. Levin <ldv@altlinux.org>
+ */
+
+#include "test_assert.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <security/pam_appl.h>
+
+#define MODULE_NAME "pam_debug"
+#define TEST_NAME "tst-" MODULE_NAME "-retval"
+
+static const char service_file[] = TEST_NAME ".service";
+static const char user_name[] = "";
+static const char args[] = " auth=perm_denied"
+ " cred=cred_unavail"
+ " acct=acct_expired"
+ " prechauthtok=success"
+ " chauthtok=service_err"
+ " open_session=buf_err"
+ " close_session=system_err";
+static struct pam_conv conv;
+
+int
+main(void)
+{
+ pam_handle_t *pamh = NULL;
+ FILE *fp;
+ char cwd[PATH_MAX];
+
+ ASSERT_NE(NULL, getcwd(cwd, sizeof(cwd)));
+
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so %s\n"
+ "account required %s/.libs/%s.so %s\n"
+ "password required %s/.libs/%s.so %s\n"
+ "session required %s/.libs/%s.so %s\n",
+ cwd, MODULE_NAME, args,
+ cwd, MODULE_NAME, args,
+ cwd, MODULE_NAME, args,
+ cwd, MODULE_NAME, args));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, user_name, &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_PERM_DENIED, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_CRED_UNAVAIL, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_ACCT_EXPIRED, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_SERVICE_ERR, pam_chauthtok(pamh, 0));
+ ASSERT_EQ(PAM_BUF_ERR, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_SYSTEM_ERR, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ ASSERT_EQ(0, unlink(service_file));
+
+ return 0;
+}
diff --git a/modules/pam_deny/Makefile.am b/modules/pam_deny/Makefile.am
new file mode 100644
index 0000000..fa9b9c8
--- /dev/null
+++ b/modules/pam_deny/Makefile.am
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2005, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_deny.8
+endif
+XMLS = README.xml pam_deny.8.xml
+dist_check_SCRIPTS = tst-pam_deny
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_deny.la
+pam_deny_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+check_PROGRAMS = tst-pam_deny-retval
+tst_pam_deny_retval_LDADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_deny/Makefile.in b/modules/pam_deny/Makefile.in
new file mode 100644
index 0000000..612ee69
--- /dev/null
+++ b/modules/pam_deny/Makefile.in
@@ -0,0 +1,1180 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+check_PROGRAMS = tst-pam_deny-retval$(EXEEXT)
+subdir = modules/pam_deny
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_deny_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_deny_la_SOURCES = pam_deny.c
+pam_deny_la_OBJECTS = pam_deny.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+tst_pam_deny_retval_SOURCES = tst-pam_deny-retval.c
+tst_pam_deny_retval_OBJECTS = tst-pam_deny-retval.$(OBJEXT)
+tst_pam_deny_retval_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_deny.Plo \
+ ./$(DEPDIR)/tst-pam_deny-retval.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_deny.c tst-pam_deny-retval.c
+DIST_SOURCES = pam_deny.c tst-pam_deny-retval.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_deny.8
+XMLS = README.xml pam_deny.8.xml
+dist_check_SCRIPTS = tst-pam_deny
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_deny.la
+pam_deny_la_LIBADD = $(top_builddir)/libpam/libpam.la
+tst_pam_deny_retval_LDADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_deny/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_deny/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_deny.la: $(pam_deny_la_OBJECTS) $(pam_deny_la_DEPENDENCIES) $(EXTRA_pam_deny_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_deny_la_OBJECTS) $(pam_deny_la_LIBADD) $(LIBS)
+
+tst-pam_deny-retval$(EXEEXT): $(tst_pam_deny_retval_OBJECTS) $(tst_pam_deny_retval_DEPENDENCIES) $(EXTRA_tst_pam_deny_retval_DEPENDENCIES)
+ @rm -f tst-pam_deny-retval$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tst_pam_deny_retval_OBJECTS) $(tst_pam_deny_retval_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_deny.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-pam_deny-retval.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_deny.log: tst-pam_deny
+ @p='tst-pam_deny'; \
+ b='tst-pam_deny'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+tst-pam_deny-retval.log: tst-pam_deny-retval$(EXEEXT)
+ @p='tst-pam_deny-retval$(EXEEXT)'; \
+ b='tst-pam_deny-retval'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) \
+ $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_deny.Plo
+ -rm -f ./$(DEPDIR)/tst-pam_deny-retval.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_deny.Plo
+ -rm -f ./$(DEPDIR)/tst-pam_deny-retval.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_deny/README b/modules/pam_deny/README
new file mode 100644
index 0000000..6b3a86f
--- /dev/null
+++ b/modules/pam_deny/README
@@ -0,0 +1,31 @@
+pam_deny — The locking-out PAM module
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+This module can be used to deny access. It always indicates a failure to the
+application through the PAM framework. It might be suitable for using for
+default (the OTHER) entries.
+
+EXAMPLES
+
+#%PAM-1.0
+#
+# If we don't have config entries for a service, the
+# OTHER entries are used. To be secure, warn and deny
+# access to everything.
+other auth required pam_warn.so
+other auth required pam_deny.so
+other account required pam_warn.so
+other account required pam_deny.so
+other password required pam_warn.so
+other password required pam_deny.so
+other session required pam_warn.so
+other session required pam_deny.so
+
+
+AUTHOR
+
+pam_deny was written by Andrew G. Morgan <morgan@kernel.org>
+
diff --git a/modules/pam_deny/README.xml b/modules/pam_deny/README.xml
new file mode 100644
index 0000000..ff2e82b
--- /dev/null
+++ b/modules/pam_deny/README.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_deny.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_deny.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_deny-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_deny.8.xml" xpointer='xpointer(//refsect1[@id = "pam_deny-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_deny.8.xml" xpointer='xpointer(//refsect1[@id = "pam_deny-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_deny.8.xml" xpointer='xpointer(//refsect1[@id = "pam_deny-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_deny/pam_deny.8 b/modules/pam_deny/pam_deny.8
new file mode 100644
index 0000000..7f47433
--- /dev/null
+++ b/modules/pam_deny/pam_deny.8
@@ -0,0 +1,102 @@
+'\" t
+.\" Title: pam_deny
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_DENY" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_deny \- The locking\-out PAM module
+.SH "SYNOPSIS"
+.HP \w'\fBpam_deny\&.so\fR\ 'u
+\fBpam_deny\&.so\fR
+.SH "DESCRIPTION"
+.PP
+This module can be used to deny access\&. It always indicates a failure to the application through the PAM framework\&. It might be suitable for using for default (the
+\fIOTHER\fR) entries\&.
+.SH "OPTIONS"
+.PP
+This module does not recognise any options\&.
+.SH "MODULE TYPES PROVIDED"
+.PP
+All module types (\fBaccount\fR,
+\fBauth\fR,
+\fBpassword\fR
+and
+\fBsession\fR) are provided\&.
+.SH "RETURN VALUES"
+.PP
+.PP
+PAM_AUTH_ERR
+.RS 4
+This is returned by the account and auth services\&.
+.RE
+.PP
+PAM_CRED_ERR
+.RS 4
+This is returned by the setcred function\&.
+.RE
+.PP
+PAM_AUTHTOK_ERR
+.RS 4
+This is returned by the password service\&.
+.RE
+.PP
+PAM_SESSION_ERR
+.RS 4
+This is returned by the session service\&.
+.RE
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+#%PAM\-1\&.0
+#
+# If we don\*(Aqt have config entries for a service, the
+# OTHER entries are used\&. To be secure, warn and deny
+# access to everything\&.
+other auth required pam_warn\&.so
+other auth required pam_deny\&.so
+other account required pam_warn\&.so
+other account required pam_deny\&.so
+other password required pam_warn\&.so
+other password required pam_deny\&.so
+other session required pam_warn\&.so
+other session required pam_deny\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+.PP
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_deny was written by Andrew G\&. Morgan <morgan@kernel\&.org>
diff --git a/modules/pam_deny/pam_deny.8.xml b/modules/pam_deny/pam_deny.8.xml
new file mode 100644
index 0000000..a928358
--- /dev/null
+++ b/modules/pam_deny/pam_deny.8.xml
@@ -0,0 +1,135 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_deny">
+
+ <refmeta>
+ <refentrytitle>pam_deny</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_deny-name">
+ <refname>pam_deny</refname>
+ <refpurpose>The locking-out PAM module</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_deny-cmdsynopsis">
+ <command>pam_deny.so</command>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_deny-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ This module can be used to deny access. It always indicates a failure
+ to the application through the PAM framework. It might be suitable
+ for using for default (the <emphasis>OTHER</emphasis>) entries.
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="pam_deny-options">
+ <title>OPTIONS</title>
+ <para>This module does not recognise any options.</para>
+ </refsect1>
+
+ <refsect1 id="pam_deny-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ All module types (<option>account</option>, <option>auth</option>,
+ <option>password</option> and <option>session</option>) are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_deny-return_values'>
+ <title>RETURN VALUES</title>
+ <para>
+ <variablelist>
+
+ <varlistentry>
+ <term>PAM_AUTH_ERR</term>
+ <listitem>
+ <para>
+ This is returned by the account and auth services.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_CRED_ERR</term>
+ <listitem>
+ <para>
+ This is returned by the setcred function.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_AUTHTOK_ERR</term>
+ <listitem>
+ <para>
+ This is returned by the password service.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SESSION_ERR</term>
+ <listitem>
+ <para>
+ This is returned by the session service.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_deny-examples'>
+ <title>EXAMPLES</title>
+ <programlisting>
+#%PAM-1.0
+#
+# If we don't have config entries for a service, the
+# OTHER entries are used. To be secure, warn and deny
+# access to everything.
+other auth required pam_warn.so
+other auth required pam_deny.so
+other account required pam_warn.so
+other account required pam_deny.so
+other password required pam_warn.so
+other password required pam_deny.so
+other session required pam_warn.so
+other session required pam_deny.so
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id='pam_deny-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_deny-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_deny was written by Andrew G. Morgan &lt;morgan@kernel.org&gt;
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_deny/pam_deny.c b/modules/pam_deny/pam_deny.c
new file mode 100644
index 0000000..a2fe0c2
--- /dev/null
+++ b/modules/pam_deny/pam_deny.c
@@ -0,0 +1,60 @@
+/*
+ * pam_deny module
+ *
+ * Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11
+ */
+
+#include "config.h"
+#include <security/pam_modules.h>
+
+/* --- authentication management functions --- */
+
+int
+pam_sm_authenticate(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_AUTH_ERR;
+}
+
+int
+pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_CRED_ERR;
+}
+
+/* --- account management functions --- */
+
+int
+pam_sm_acct_mgmt(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_AUTH_ERR;
+}
+
+/* --- password management --- */
+
+int
+pam_sm_chauthtok(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_AUTHTOK_ERR;
+}
+
+/* --- session management --- */
+
+int
+pam_sm_open_session(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SESSION_ERR;
+}
+
+int
+pam_sm_close_session(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SESSION_ERR;
+}
+
+/* end of module definition */
diff --git a/modules/pam_deny/tst-pam_deny b/modules/pam_deny/tst-pam_deny
new file mode 100755
index 0000000..7d9d6ba
--- /dev/null
+++ b/modules/pam_deny/tst-pam_deny
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_deny.so
diff --git a/modules/pam_deny/tst-pam_deny-retval.c b/modules/pam_deny/tst-pam_deny-retval.c
new file mode 100644
index 0000000..356ca1f
--- /dev/null
+++ b/modules/pam_deny/tst-pam_deny-retval.c
@@ -0,0 +1,58 @@
+/*
+ * Check pam_deny return values.
+ *
+ * Copyright (c) 2020 Dmitry V. Levin <ldv@altlinux.org>
+ */
+
+#include "test_assert.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <security/pam_appl.h>
+
+#define MODULE_NAME "pam_deny"
+#define TEST_NAME "tst-" MODULE_NAME "-retval"
+
+static const char service_file[] = TEST_NAME ".service";
+static const char user_name[] = "";
+static struct pam_conv conv;
+
+int
+main(void)
+{
+ pam_handle_t *pamh = NULL;
+ FILE *fp;
+ char cwd[PATH_MAX];
+
+ ASSERT_NE(NULL, getcwd(cwd, sizeof(cwd)));
+
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so\n"
+ "account required %s/.libs/%s.so\n"
+ "password required %s/.libs/%s.so\n"
+ "session required %s/.libs/%s.so\n",
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, user_name, &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_AUTH_ERR, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_CRED_ERR, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_AUTH_ERR, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_AUTHTOK_ERR, pam_chauthtok(pamh, 0));
+ ASSERT_EQ(PAM_SESSION_ERR, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_SESSION_ERR, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ ASSERT_EQ(0, unlink(service_file));
+
+ return 0;
+}
diff --git a/modules/pam_echo/Makefile.am b/modules/pam_echo/Makefile.am
new file mode 100644
index 0000000..b855e62
--- /dev/null
+++ b/modules/pam_echo/Makefile.am
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@thkukuk.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_echo.8
+endif
+XMLS = README.xml pam_echo.8.xml
+dist_check_SCRIPTS = tst-pam_echo
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_echo.la
+pam_echo_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+check_PROGRAMS = tst-pam_echo-retval
+tst_pam_echo_retval_LDADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_echo/Makefile.in b/modules/pam_echo/Makefile.in
new file mode 100644
index 0000000..7b591fa
--- /dev/null
+++ b/modules/pam_echo/Makefile.in
@@ -0,0 +1,1180 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@thkukuk.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+check_PROGRAMS = tst-pam_echo-retval$(EXEEXT)
+subdir = modules/pam_echo
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_echo_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_echo_la_SOURCES = pam_echo.c
+pam_echo_la_OBJECTS = pam_echo.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+tst_pam_echo_retval_SOURCES = tst-pam_echo-retval.c
+tst_pam_echo_retval_OBJECTS = tst-pam_echo-retval.$(OBJEXT)
+tst_pam_echo_retval_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_echo.Plo \
+ ./$(DEPDIR)/tst-pam_echo-retval.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_echo.c tst-pam_echo-retval.c
+DIST_SOURCES = pam_echo.c tst-pam_echo-retval.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_echo.8
+XMLS = README.xml pam_echo.8.xml
+dist_check_SCRIPTS = tst-pam_echo
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_echo.la
+pam_echo_la_LIBADD = $(top_builddir)/libpam/libpam.la
+tst_pam_echo_retval_LDADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_echo/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_echo/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_echo.la: $(pam_echo_la_OBJECTS) $(pam_echo_la_DEPENDENCIES) $(EXTRA_pam_echo_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_echo_la_OBJECTS) $(pam_echo_la_LIBADD) $(LIBS)
+
+tst-pam_echo-retval$(EXEEXT): $(tst_pam_echo_retval_OBJECTS) $(tst_pam_echo_retval_DEPENDENCIES) $(EXTRA_tst_pam_echo_retval_DEPENDENCIES)
+ @rm -f tst-pam_echo-retval$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tst_pam_echo_retval_OBJECTS) $(tst_pam_echo_retval_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_echo.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-pam_echo-retval.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_echo.log: tst-pam_echo
+ @p='tst-pam_echo'; \
+ b='tst-pam_echo'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+tst-pam_echo-retval.log: tst-pam_echo-retval$(EXEEXT)
+ @p='tst-pam_echo-retval$(EXEEXT)'; \
+ b='tst-pam_echo-retval'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) \
+ $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_echo.Plo
+ -rm -f ./$(DEPDIR)/tst-pam_echo-retval.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_echo.Plo
+ -rm -f ./$(DEPDIR)/tst-pam_echo-retval.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_echo/README b/modules/pam_echo/README
new file mode 100644
index 0000000..626b34a
--- /dev/null
+++ b/modules/pam_echo/README
@@ -0,0 +1,50 @@
+pam_echo — PAM module for printing text messages
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+The pam_echo PAM module is for printing text messages to inform user about
+special things. Sequences starting with the % character are interpreted in the
+following way:
+
+%H
+
+ The name of the remote host (PAM_RHOST).
+
+%h
+
+ The name of the local host.
+
+%s
+
+ The service name (PAM_SERVICE).
+
+%t
+
+ The name of the controlling terminal (PAM_TTY).
+
+%U
+
+ The remote user name (PAM_RUSER).
+
+%u
+
+ The local user name (PAM_USER).
+
+All other sequences beginning with % expands to the characters following the %
+character.
+
+EXAMPLES
+
+For an example of the use of this module, we show how it may be used to print
+information about good passwords:
+
+password optional pam_echo.so file=/usr/share/doc/good-password.txt
+password required pam_unix.so
+
+
+AUTHOR
+
+Thorsten Kukuk <kukuk@thkukuk.de>
+
diff --git a/modules/pam_echo/README.xml b/modules/pam_echo/README.xml
new file mode 100644
index 0000000..b1556e3
--- /dev/null
+++ b/modules/pam_echo/README.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_echo.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_echo.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_echo-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_echo.8.xml" xpointer='xpointer(//refsect1[@id = "pam_echo-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_echo.8.xml" xpointer='xpointer(//refsect1[@id = "pam_echo-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_echo.8.xml" xpointer='xpointer(//refsect1[@id = "pam_echo-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_echo/pam_echo.8 b/modules/pam_echo/pam_echo.8
new file mode 100644
index 0000000..ba46e06
--- /dev/null
+++ b/modules/pam_echo/pam_echo.8
@@ -0,0 +1,132 @@
+'\" t
+.\" Title: pam_echo
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_ECHO" "8" "09/03/2021" "Linux-PAM Manual" "Linux-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_echo \- PAM module for printing text messages
+.SH "SYNOPSIS"
+.HP \w'\fBpam_echo\&.so\fR\ 'u
+\fBpam_echo\&.so\fR [file=\fI/path/message\fR]
+.SH "DESCRIPTION"
+.PP
+The
+\fIpam_echo\fR
+PAM module is for printing text messages to inform user about special things\&. Sequences starting with the
+\fI%\fR
+character are interpreted in the following way:
+.PP
+\fI%H\fR
+.RS 4
+The name of the remote host (PAM_RHOST)\&.
+.RE
+.PP
+\fI%h\fR
+.RS 4
+The name of the local host\&.
+.RE
+.PP
+\fI%s\fR
+.RS 4
+The service name (PAM_SERVICE)\&.
+.RE
+.PP
+\fI%t\fR
+.RS 4
+The name of the controlling terminal (PAM_TTY)\&.
+.RE
+.PP
+\fI%U\fR
+.RS 4
+The remote user name (PAM_RUSER)\&.
+.RE
+.PP
+\fI%u\fR
+.RS 4
+The local user name (PAM_USER)\&.
+.RE
+.PP
+All other sequences beginning with
+\fI%\fR
+expands to the characters following the
+\fI%\fR
+character\&.
+.SH "OPTIONS"
+.PP
+\fBfile=\fR\fB\fI/path/message\fR\fR
+.RS 4
+The content of the file
+/path/message
+will be printed with the PAM conversion function as PAM_TEXT_INFO\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+All module types (\fBauth\fR,
+\fBaccount\fR,
+\fBpassword\fR
+and
+\fBsession\fR) are provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_SUCCESS
+.RS 4
+Message was successful printed\&.
+.RE
+.PP
+PAM_IGNORE
+.RS 4
+PAM_SILENT flag was given or message file does not exist, no message printed\&.
+.RE
+.SH "EXAMPLES"
+.PP
+For an example of the use of this module, we show how it may be used to print information about good passwords:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+password optional pam_echo\&.so file=/usr/share/doc/good\-password\&.txt
+password required pam_unix\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.PP
+\fBpam.conf\fR(8),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+Thorsten Kukuk <kukuk@thkukuk\&.de>
diff --git a/modules/pam_echo/pam_echo.8.xml b/modules/pam_echo/pam_echo.8.xml
new file mode 100644
index 0000000..ef76b02
--- /dev/null
+++ b/modules/pam_echo/pam_echo.8.xml
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+
+<refentry id='pam_echo'>
+ <refmeta>
+ <refentrytitle>pam_echo</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id='pam_echo-name'>
+ <refname>pam_echo</refname>
+ <refpurpose>PAM module for printing text messages</refpurpose>
+ </refnamediv>
+
+<!-- body begins here -->
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_echo-cmdsynopsis">
+ <command>pam_echo.so</command>
+ <arg choice="opt">
+ file=<replaceable>/path/message</replaceable>
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id='pam_echo-description'>
+ <title>DESCRIPTION</title>
+ <para>
+ The <emphasis>pam_echo</emphasis> PAM module is for printing
+ text messages to inform user about special things. Sequences
+ starting with the <emphasis>%</emphasis> character are
+ interpreted in the following way:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term><emphasis>%H</emphasis></term>
+ <listitem>
+ <para>The name of the remote host (PAM_RHOST).</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis>%h</emphasis></term>
+ <listitem>
+ <para>The name of the local host.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis>%s</emphasis></term>
+ <listitem>
+ <para>The service name (PAM_SERVICE).</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis>%t</emphasis></term>
+ <listitem>
+ <para>The name of the controlling terminal (PAM_TTY).</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis>%U</emphasis></term>
+ <listitem>
+ <para>The remote user name (PAM_RUSER).</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis>%u</emphasis></term>
+ <listitem>
+ <para>The local user name (PAM_USER).</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ All other sequences beginning with <emphasis>%</emphasis>
+ expands to the characters following the <emphasis>%</emphasis>
+ character.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_echo-options'>
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>file=<replaceable>/path/message</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The content of the file <filename>/path/message</filename>
+ will be printed with the PAM conversion function as PAM_TEXT_INFO.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_echo-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ All module types (<option>auth</option>, <option>account</option>,
+ <option>password</option> and <option>session</option>) are provided.
+
+ </para>
+ </refsect1>
+
+
+ <refsect1 id="pam_echo-return_values">
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory buffer error.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Message was successful printed.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ PAM_SILENT flag was given or message file does not
+ exist, no message printed.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_echo-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ For an example of the use of this module, we show how it may be
+ used to print information about good passwords:
+ <programlisting>
+password optional pam_echo.so file=/usr/share/doc/good-password.txt
+password required pam_unix.so
+ </programlisting>
+ </para>
+ </refsect1>
+
+
+ <refsect1 id='pam_echo-see_also'><title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry></para>
+ </refsect1>
+
+ <refsect1 id='pam_echo-author'>
+ <title>AUTHOR</title>
+ <para>Thorsten Kukuk &lt;kukuk@thkukuk.de&gt;</para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_echo/pam_echo.c b/modules/pam_echo/pam_echo.c
new file mode 100644
index 0000000..181aeb4
--- /dev/null
+++ b/modules/pam_echo/pam_echo.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifndef HOST_NAME_MAX
+#define HOST_NAME_MAX 255
+#endif
+
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+#include <security/_pam_macros.h>
+#include <security/pam_ext.h>
+#include "pam_inline.h"
+
+static int
+replace_and_print (pam_handle_t *pamh, const char *mesg)
+{
+ char *output;
+ size_t length = strlen (mesg) + PAM_MAX_MSG_SIZE;
+ char myhostname[HOST_NAME_MAX+1];
+ const void *str = NULL;
+ const char *p, *q;
+ int item;
+ size_t len;
+
+ output = malloc (length);
+ if (output == NULL)
+ {
+ pam_syslog (pamh, LOG_CRIT, "running out of memory");
+ return PAM_BUF_ERR;
+ }
+
+ for (p = mesg, len = 0; *p != '\0' && len < length - 1; ++p)
+ {
+ if (*p != '%' || p[1] == '\0')
+ {
+ output[len++] = *p;
+ continue;
+ }
+ switch (*++p)
+ {
+ case 'H':
+ item = PAM_RHOST;
+ break;
+ case 'h':
+ item = -2; /* aka PAM_LOCALHOST */
+ break;
+ case 's':
+ item = PAM_SERVICE;
+ break;
+ case 't':
+ item = PAM_TTY;
+ break;
+ case 'U':
+ item = PAM_RUSER;
+ break;
+ case 'u':
+ item = PAM_USER;
+ break;
+ default:
+ output[len++] = *p;
+ continue;
+ }
+ if (item == -2)
+ {
+ if (gethostname (myhostname, sizeof (myhostname)) == -1)
+ str = NULL;
+ else
+ str = &myhostname;
+ }
+ else
+ {
+ if (pam_get_item (pamh, item, &str) != PAM_SUCCESS)
+ str = NULL;
+ }
+ if (str == NULL)
+ str = "(null)";
+ for (q = str; *q != '\0' && len < length - 1; ++q)
+ output[len++] = *q;
+ }
+ output[len] = '\0';
+
+ pam_info (pamh, "%s", output);
+ free (output);
+
+ return PAM_SUCCESS;
+}
+
+static int
+pam_echo (pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ int fd;
+ int orig_argc = argc;
+ const char **orig_argv = argv;
+ const char *file = NULL;
+ int retval;
+
+ if (flags & PAM_SILENT)
+ return PAM_IGNORE;
+
+ for (; argc-- > 0; ++argv)
+ {
+ const char *str = pam_str_skip_prefix(*argv, "file=");
+ if (str != NULL)
+ file = str;
+ }
+
+ /* No file= option, use argument for output. */
+ if (file == NULL || file[0] == '\0')
+ {
+ char msg[PAM_MAX_MSG_SIZE];
+ const char *p;
+ int i;
+ size_t len;
+
+ for (i = 0, len = 0; i < orig_argc && len < sizeof (msg) - 1; ++i)
+ {
+ if (i > 0)
+ msg[len++] = ' ';
+ for (p = orig_argv[i]; *p != '\0' && len < sizeof(msg) - 1; ++p)
+ msg[len++] = *p;
+ }
+ msg[len] = '\0';
+
+ retval = replace_and_print (pamh, msg);
+ }
+ else if ((fd = open (file, O_RDONLY, 0)) >= 0)
+ {
+ char *mtmp = NULL;
+ struct stat st;
+
+ /* load file into message buffer. */
+ if ((fstat (fd, &st) < 0) || !st.st_size)
+ {
+ close (fd);
+ return PAM_IGNORE;
+ }
+
+ mtmp = malloc (st.st_size + 1);
+ if (!mtmp)
+ {
+ close (fd);
+ return PAM_BUF_ERR;
+ }
+
+ if (pam_modutil_read (fd, mtmp, st.st_size) == -1)
+ {
+ pam_syslog (pamh, LOG_ERR, "Error while reading %s: %m", file);
+ free (mtmp);
+ close (fd);
+ return PAM_IGNORE;
+ }
+
+ if (mtmp[st.st_size - 1] == '\n')
+ mtmp[st.st_size - 1] = '\0';
+ else
+ mtmp[st.st_size] = '\0';
+
+ close (fd);
+ retval = replace_and_print (pamh, mtmp);
+ free (mtmp);
+ }
+ else
+ {
+ pam_syslog (pamh, LOG_ERR, "Cannot open %s: %m", file);
+ retval = PAM_IGNORE;
+ }
+ return retval;
+}
+
+int
+pam_sm_authenticate (pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ return pam_echo (pamh, flags, argc, argv);
+}
+
+int
+pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_IGNORE;
+}
+
+int
+pam_sm_acct_mgmt (pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ return pam_echo (pamh, flags, argc, argv);
+}
+
+int
+pam_sm_open_session (pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ return pam_echo (pamh, flags, argc, argv);
+}
+
+int
+pam_sm_close_session (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_IGNORE;
+}
+
+int
+pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ if (flags & PAM_PRELIM_CHECK)
+ return pam_echo (pamh, flags, argc, argv);
+ else
+ return PAM_IGNORE;
+}
diff --git a/modules/pam_echo/tst-pam_echo b/modules/pam_echo/tst-pam_echo
new file mode 100755
index 0000000..483a2c2
--- /dev/null
+++ b/modules/pam_echo/tst-pam_echo
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_echo.so
diff --git a/modules/pam_echo/tst-pam_echo-retval.c b/modules/pam_echo/tst-pam_echo-retval.c
new file mode 100644
index 0000000..2374b71
--- /dev/null
+++ b/modules/pam_echo/tst-pam_echo-retval.c
@@ -0,0 +1,101 @@
+/*
+ * Check pam_echo return values.
+ *
+ * Copyright (c) 2020 Dmitry V. Levin <ldv@altlinux.org>
+ */
+
+#include "test_assert.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <security/pam_appl.h>
+
+#define MODULE_NAME "pam_echo"
+#define TEST_NAME "tst-" MODULE_NAME "-retval"
+
+static const char service_file[] = TEST_NAME ".service";
+static const char user_name[] = "";
+static struct pam_conv conv;
+
+int
+main(void)
+{
+ pam_handle_t *pamh = NULL;
+ FILE *fp;
+ char cwd[PATH_MAX];
+
+ ASSERT_NE(NULL, getcwd(cwd, sizeof(cwd)));
+
+ /* PAM_SUCCESS -> PAM_SUCCESS, PAM_IGNORE -> PAM_PERM_DENIED */
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so\n"
+ "account required %s/.libs/%s.so\n"
+ "password required %s/.libs/%s.so\n"
+ "session required %s/.libs/%s.so\n",
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, user_name, &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_chauthtok(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ /* PAM_SILENT: PAM_IGNORE -> PAM_PERM_DENIED */
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, user_name, &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_PERM_DENIED, pam_authenticate(pamh, PAM_SILENT));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_setcred(pamh, PAM_SILENT));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_acct_mgmt(pamh, PAM_SILENT));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_chauthtok(pamh, PAM_SILENT));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_open_session(pamh, PAM_SILENT));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_close_session(pamh, PAM_SILENT));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ /* PAM_IGNORE -> PAM_SUCCESS */
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so\n"
+ "auth required %s/../pam_permit/.libs/pam_permit.so\n"
+ "account required %s/.libs/%s.so\n"
+ "account required %s/../pam_permit/.libs/pam_permit.so\n"
+ "password required %s/.libs/%s.so\n"
+ "password required %s/../pam_permit/.libs/pam_permit.so\n"
+ "session required %s/.libs/%s.so\n"
+ "session required %s/../pam_permit/.libs/pam_permit.so\n",
+ cwd, MODULE_NAME, cwd,
+ cwd, MODULE_NAME, cwd,
+ cwd, MODULE_NAME, cwd,
+ cwd, MODULE_NAME, cwd));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, user_name, &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, PAM_SILENT));
+ ASSERT_EQ(PAM_SUCCESS, pam_setcred(pamh, PAM_SILENT));
+ ASSERT_EQ(PAM_SUCCESS, pam_acct_mgmt(pamh, PAM_SILENT));
+ ASSERT_EQ(PAM_SUCCESS, pam_chauthtok(pamh, PAM_SILENT));
+ ASSERT_EQ(PAM_SUCCESS, pam_open_session(pamh, PAM_SILENT));
+ ASSERT_EQ(PAM_SUCCESS, pam_close_session(pamh, PAM_SILENT));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ ASSERT_EQ(0, unlink(service_file));
+
+ return 0;
+}
diff --git a/modules/pam_env/Makefile.am b/modules/pam_env/Makefile.am
new file mode 100644
index 0000000..c66112d
--- /dev/null
+++ b/modules/pam_env/Makefile.am
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2005, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_env.conf.5 pam_env.8 environment.5
+endif
+XMLS = README.xml pam_env.conf.5.xml pam_env.8.xml
+dist_check_SCRIPTS = tst-pam_env
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DDEFAULT_CONF_FILE=\"$(SCONFIGDIR)/pam_env.conf\" $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_env.la
+pam_env_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+dist_secureconf_DATA = pam_env.conf
+dist_sysconf_DATA = environment
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+environment.5: pam_env.conf.5.xml
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_env/Makefile.in b/modules/pam_env/Makefile.in
new file mode 100644
index 0000000..255458f
--- /dev/null
+++ b/modules/pam_env/Makefile.in
@@ -0,0 +1,1248 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_env
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(dist_secureconf_DATA) \
+ $(dist_sysconf_DATA) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man5dir)" \
+ "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(secureconfdir)" \
+ "$(DESTDIR)$(sysconfdir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_env_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_env_la_SOURCES = pam_env.c
+pam_env_la_OBJECTS = pam_env.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_env.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_env.c
+DIST_SOURCES = pam_env.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man5dir = $(mandir)/man5
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA) $(dist_secureconf_DATA) \
+ $(dist_sysconf_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_env.conf.5 pam_env.8 environment.5
+XMLS = README.xml pam_env.conf.5.xml pam_env.8.xml
+dist_check_SCRIPTS = tst-pam_env
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DDEFAULT_CONF_FILE=\"$(SCONFIGDIR)/pam_env.conf\" $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_env.la
+pam_env_la_LIBADD = $(top_builddir)/libpam/libpam.la
+dist_secureconf_DATA = pam_env.conf
+dist_sysconf_DATA = environment
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_env/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_env/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_env.la: $(pam_env_la_OBJECTS) $(pam_env_la_DEPENDENCIES) $(EXTRA_pam_env_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_env_la_OBJECTS) $(pam_env_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_env.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man5: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man5dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.5[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man5:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man5dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.5[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir)
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+install-dist_secureconfDATA: $(dist_secureconf_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_secureconf_DATA)'; test -n "$(secureconfdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(secureconfdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(secureconfdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(secureconfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(secureconfdir)" || exit $$?; \
+ done
+
+uninstall-dist_secureconfDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_secureconf_DATA)'; test -n "$(secureconfdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(secureconfdir)'; $(am__uninstall_files_from_dir)
+install-dist_sysconfDATA: $(dist_sysconf_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(sysconfdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(sysconfdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sysconfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(sysconfdir)" || exit $$?; \
+ done
+
+uninstall-dist_sysconfDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_sysconf_DATA)'; test -n "$(sysconfdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(sysconfdir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_env.log: tst-pam_env
+ @p='tst-pam_env'; \
+ b='tst-pam_env'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(secureconfdir)" "$(DESTDIR)$(sysconfdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_env.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-dist_secureconfDATA install-man \
+ install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-dist_sysconfDATA
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man5 install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_env.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-dist_secureconfDATA uninstall-dist_sysconfDATA \
+ uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man5 uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dist_secureconfDATA \
+ install-dist_sysconfDATA install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-man5 \
+ install-man8 install-pdf install-pdf-am install-ps \
+ install-ps-am install-securelibLTLIBRARIES install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am \
+ uninstall-dist_secureconfDATA uninstall-dist_sysconfDATA \
+ uninstall-man uninstall-man5 uninstall-man8 \
+ uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@environment.5: pam_env.conf.5.xml
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_env/README b/modules/pam_env/README
new file mode 100644
index 0000000..a040caf
--- /dev/null
+++ b/modules/pam_env/README
@@ -0,0 +1,101 @@
+pam_env — PAM module to set/unset environment variables
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+The pam_env PAM module allows the (un)setting of environment variables.
+Supported is the use of previously set environment variables as well as
+PAM_ITEMs such as PAM_RHOST.
+
+By default rules for (un)setting of variables are taken from the config file /
+etc/security/pam_env.conf. An alternate file can be specified with the conffile
+option.
+
+Second a file (/etc/environment by default) with simple KEY=VAL pairs on
+separate lines will be read. With the envfile option an alternate file can be
+specified. And with the readenv option this can be completely disabled.
+
+Third it will read a user configuration file ($HOME/.pam_environment by
+default). The default file can be changed with the user_envfile option and it
+can be turned on and off with the user_readenv option.
+
+Since setting of PAM environment variables can have side effects to other
+modules, this module should be the last one on the stack.
+
+OPTIONS
+
+conffile=/path/to/pam_env.conf
+
+ Indicate an alternative pam_env.conf style configuration file to override
+ the default. This can be useful when different services need different
+ environments.
+
+debug
+
+ A lot of debug information is printed with syslog(3).
+
+envfile=/path/to/environment
+
+ Indicate an alternative environment file to override the default. The
+ syntax are simple KEY=VAL pairs on separate lines. The export instruction
+ can be specified for bash compatibility, but will be ignored. This can be
+ useful when different services need different environments.
+
+readenv=0|1
+
+ Turns on or off the reading of the file specified by envfile (0 is off, 1
+ is on). By default this option is on.
+
+user_envfile=filename
+
+ Indicate an alternative .pam_environment file to override the default.The
+ syntax is the same as for /etc/security/pam_env.conf. The filename is
+ relative to the user home directory. This can be useful when different
+ services need different environments.
+
+user_readenv=0|1
+
+ Turns on or off the reading of the user specific environment file. 0 is
+ off, 1 is on. By default this option is off as user supplied environment
+ variables in the PAM environment could affect behavior of subsequent
+ modules in the stack without the consent of the system administrator.
+
+ Due to problematic security this functionality is deprecated since the
+ 1.5.0 version and will be removed completely at some point in the future.
+
+EXAMPLES
+
+These are some example lines which might be specified in /etc/security/
+pam_env.conf.
+
+Set the REMOTEHOST variable for any hosts that are remote, default to
+"localhost" rather than not being set at all
+
+ REMOTEHOST DEFAULT=localhost OVERRIDE=@{PAM_RHOST}
+
+
+Set the DISPLAY variable if it seems reasonable
+
+ DISPLAY DEFAULT=${REMOTEHOST}:0.0 OVERRIDE=${DISPLAY}
+
+
+Now some simple variables
+
+ PAGER DEFAULT=less
+ MANPAGER DEFAULT=less
+ LESS DEFAULT="M q e h15 z23 b80"
+ NNTPSERVER DEFAULT=localhost
+ PATH DEFAULT=${HOME}/bin:/usr/local/bin:/bin\
+ :/usr/bin:/usr/local/bin/X11:/usr/bin/X11
+ XDG_DATA_HOME DEFAULT=@{HOME}/share/
+
+
+Silly examples of escaped variables, just to show how they work.
+
+ DOLLAR DEFAULT=\$
+ DOLLARDOLLAR DEFAULT= OVERRIDE=\$${DOLLAR}
+ DOLLARPLUS DEFAULT=\${REMOTEHOST}${REMOTEHOST}
+ ATSIGN DEFAULT="" OVERRIDE=\@
+
+
diff --git a/modules/pam_env/README.xml b/modules/pam_env/README.xml
new file mode 100644
index 0000000..21a9b85
--- /dev/null
+++ b/modules/pam_env/README.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_env.8.xml">
+-->
+<!--
+<!ENTITY accessconf SYSTEM "pam_env.conf.5.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_env.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_env-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_env.8.xml" xpointer='xpointer(//refsect1[@id = "pam_env-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_env.8.xml" xpointer='xpointer(//refsect1[@id = "pam_env-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_env.conf.5.xml" xpointer='xpointer(//refsect1[@id = "pam_env.conf-examples"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_env/environment b/modules/pam_env/environment
new file mode 100644
index 0000000..3e704a6
--- /dev/null
+++ b/modules/pam_env/environment
@@ -0,0 +1,5 @@
+#
+# This file is parsed by pam_env module
+#
+# Syntax: simple "KEY=VAL" pairs on separate lines
+#
diff --git a/modules/pam_env/environment.5 b/modules/pam_env/environment.5
new file mode 100644
index 0000000..aa670e2
--- /dev/null
+++ b/modules/pam_env/environment.5
@@ -0,0 +1 @@
+.so man5/pam_env.conf.5
diff --git a/modules/pam_env/pam_env.8 b/modules/pam_env/pam_env.8
new file mode 100644
index 0000000..8b0d519
--- /dev/null
+++ b/modules/pam_env/pam_env.8
@@ -0,0 +1,160 @@
+'\" t
+.\" Title: pam_env
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_ENV" "8" "09/03/2021" "Linux-PAM Manual" "Linux-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_env \- PAM module to set/unset environment variables
+.SH "SYNOPSIS"
+.HP \w'\fBpam_env\&.so\fR\ 'u
+\fBpam_env\&.so\fR [debug] [conffile=\fIconf\-file\fR] [envfile=\fIenv\-file\fR] [readenv=\fI0|1\fR] [user_envfile=\fIenv\-file\fR] [user_readenv=\fI0|1\fR]
+.SH "DESCRIPTION"
+.PP
+The pam_env PAM module allows the (un)setting of environment variables\&. Supported is the use of previously set environment variables as well as
+\fIPAM_ITEM\fRs such as
+\fIPAM_RHOST\fR\&.
+.PP
+By default rules for (un)setting of variables are taken from the config file
+/etc/security/pam_env\&.conf\&. An alternate file can be specified with the
+\fIconffile\fR
+option\&.
+.PP
+Second a file (/etc/environment
+by default) with simple
+\fIKEY=VAL\fR
+pairs on separate lines will be read\&. With the
+\fIenvfile\fR
+option an alternate file can be specified\&. And with the
+\fIreadenv\fR
+option this can be completely disabled\&.
+.PP
+Third it will read a user configuration file ($HOME/\&.pam_environment
+by default)\&. The default file can be changed with the
+\fIuser_envfile\fR
+option and it can be turned on and off with the
+\fIuser_readenv\fR
+option\&.
+.PP
+Since setting of PAM environment variables can have side effects to other modules, this module should be the last one on the stack\&.
+.SH "OPTIONS"
+.PP
+\fBconffile=\fR\fB\fI/path/to/pam_env\&.conf\fR\fR
+.RS 4
+Indicate an alternative
+pam_env\&.conf
+style configuration file to override the default\&. This can be useful when different services need different environments\&.
+.RE
+.PP
+\fBdebug\fR
+.RS 4
+A lot of debug information is printed with
+\fBsyslog\fR(3)\&.
+.RE
+.PP
+\fBenvfile=\fR\fB\fI/path/to/environment\fR\fR
+.RS 4
+Indicate an alternative
+environment
+file to override the default\&. The syntax are simple
+\fIKEY=VAL\fR
+pairs on separate lines\&. The
+\fIexport\fR
+instruction can be specified for bash compatibility, but will be ignored\&. This can be useful when different services need different environments\&.
+.RE
+.PP
+\fBreadenv=\fR\fB\fI0|1\fR\fR
+.RS 4
+Turns on or off the reading of the file specified by envfile (0 is off, 1 is on)\&. By default this option is on\&.
+.RE
+.PP
+\fBuser_envfile=\fR\fB\fIfilename\fR\fR
+.RS 4
+Indicate an alternative
+\&.pam_environment
+file to override the default\&.The syntax is the same as for
+\fI/etc/security/pam_env\&.conf\fR\&. The filename is relative to the user home directory\&. This can be useful when different services need different environments\&.
+.RE
+.PP
+\fBuser_readenv=\fR\fB\fI0|1\fR\fR
+.RS 4
+Turns on or off the reading of the user specific environment file\&. 0 is off, 1 is on\&. By default this option is off as user supplied environment variables in the PAM environment could affect behavior of subsequent modules in the stack without the consent of the system administrator\&.
+.sp
+Due to problematic security this functionality is deprecated since the 1\&.5\&.0 version and will be removed completely at some point in the future\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+The
+\fBauth\fR
+and
+\fBsession\fR
+module types are provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_ABORT
+.RS 4
+Not all relevant data or options could be gotten\&.
+.RE
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_IGNORE
+.RS 4
+No pam_env\&.conf and environment file was found\&.
+.RE
+.PP
+PAM_SUCCESS
+.RS 4
+Environment variables were set\&.
+.RE
+.SH "FILES"
+.PP
+/etc/security/pam_env\&.conf
+.RS 4
+Default configuration file
+.RE
+.PP
+/etc/environment
+.RS 4
+Default environment file
+.RE
+.PP
+$HOME/\&.pam_environment
+.RS 4
+User specific environment file
+.RE
+.SH "SEE ALSO"
+.PP
+\fBpam_env.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8),
+\fBenviron\fR(7)\&.
+.SH "AUTHOR"
+.PP
+pam_env was written by Dave Kinchlea <kinch@kinch\&.ark\&.com>\&.
diff --git a/modules/pam_env/pam_env.8.xml b/modules/pam_env/pam_env.8.xml
new file mode 100644
index 0000000..75ff862
--- /dev/null
+++ b/modules/pam_env/pam_env.8.xml
@@ -0,0 +1,271 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+
+<refentry id='pam_env'>
+
+ <refmeta>
+ <refentrytitle>pam_env</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id='pam_env-name'>
+ <refname>pam_env</refname>
+ <refpurpose>
+ PAM module to set/unset environment variables
+ </refpurpose>
+ </refnamediv>
+
+<!-- body begins here -->
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_env-cmdsynopsis">
+ <command>pam_env.so</command>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ conffile=<replaceable>conf-file</replaceable>
+ </arg>
+ <arg choice="opt">
+ envfile=<replaceable>env-file</replaceable>
+ </arg>
+ <arg choice="opt">
+ readenv=<replaceable>0|1</replaceable>
+ </arg>
+ <arg choice="opt">
+ user_envfile=<replaceable>env-file</replaceable>
+ </arg>
+ <arg choice="opt">
+ user_readenv=<replaceable>0|1</replaceable>
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1 id="pam_env-description">
+ <title>DESCRIPTION</title>
+ <para>
+ The pam_env PAM module allows the (un)setting of environment
+ variables. Supported is the use of previously set environment
+ variables as well as <emphasis>PAM_ITEM</emphasis>s such as
+ <emphasis>PAM_RHOST</emphasis>.
+ </para>
+ <para>
+ By default rules for (un)setting of variables are taken from the
+ config file <filename>/etc/security/pam_env.conf</filename>. An
+ alternate file can be specified with the <emphasis>conffile</emphasis>
+ option.
+ </para>
+ <para>
+ Second a file (<filename>/etc/environment</filename> by default) with simple
+ <emphasis>KEY=VAL</emphasis> pairs on separate lines will be read.
+ With the <emphasis>envfile</emphasis> option an alternate file can be specified.
+ And with the <emphasis>readenv</emphasis> option this can be completely disabled.
+ </para>
+ <para>
+ Third it will read a user configuration file
+ (<filename>$HOME/.pam_environment</filename> by default).
+ The default file can be changed with the
+ <emphasis>user_envfile</emphasis> option
+ and it can be turned on and off with the <emphasis>user_readenv</emphasis> option.
+ </para>
+ <para>
+ Since setting of PAM environment variables can have side effects
+ to other modules, this module should be the last one on the stack.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_env-options">
+ <title>OPTIONS</title>
+ <variablelist>
+
+ <varlistentry>
+ <term>
+ <option>conffile=<replaceable>/path/to/pam_env.conf</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Indicate an alternative <filename>pam_env.conf</filename>
+ style configuration file to override the default. This can
+ be useful when different services need different environments.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ A lot of debug information is printed with
+ <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>envfile=<replaceable>/path/to/environment</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Indicate an alternative <filename>environment</filename>
+ file to override the default. The syntax are simple
+ <emphasis>KEY=VAL</emphasis> pairs on separate lines. The
+ <emphasis>export</emphasis> instruction can be specified for bash
+ compatibility, but will be ignored.
+ This can be useful when different services need different environments.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>readenv=<replaceable>0|1</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Turns on or off the reading of the file specified by envfile
+ (0 is off, 1 is on). By default this option is on.
+ </para>
+ </listitem>
+ </varlistentry>
+
+
+ <varlistentry>
+ <term>
+ <option>user_envfile=<replaceable>filename</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Indicate an alternative <filename>.pam_environment</filename>
+ file to override the default.The syntax is the same as
+ for <emphasis>/etc/security/pam_env.conf</emphasis>.
+ The filename is relative to the user home directory.
+ This can be useful when different services need different
+ environments.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>user_readenv=<replaceable>0|1</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Turns on or off the reading of the user specific environment
+ file. 0 is off, 1 is on. By default this option is off as user
+ supplied environment variables in the PAM environment could affect
+ behavior of subsequent modules in the stack without the consent
+ of the system administrator.
+ </para>
+ <para>
+ Due to problematic security this functionality is deprecated
+ since the 1.5.0 version and will be removed completely at some
+ point in the future.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_env-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ The <option>auth</option> and <option>session</option> module
+ types are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_env-return_values">
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_ABORT</term>
+ <listitem>
+ <para>
+ Not all relevant data or options could be gotten.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory buffer error.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ No pam_env.conf and environment file was found.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Environment variables were set.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_env-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/security/pam_env.conf</filename></term>
+ <listitem>
+ <para>Default configuration file</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><filename>/etc/environment</filename></term>
+ <listitem>
+ <para>Default environment file</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><filename>$HOME/.pam_environment</filename></term>
+ <listitem>
+ <para>User specific environment file</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_env-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam_env.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum>
+ </citerefentry>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_env-authors">
+ <title>AUTHOR</title>
+ <para>
+ pam_env was written by Dave Kinchlea &lt;kinch@kinch.ark.com&gt;.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_env/pam_env.c b/modules/pam_env/pam_env.c
new file mode 100644
index 0000000..f5f8cea
--- /dev/null
+++ b/modules/pam_env/pam_env.c
@@ -0,0 +1,894 @@
+/*
+ * pam_env module
+ *
+ * Written by Dave Kinchlea <kinch@kinch.ark.com> 1997/01/31
+ * Inspired by Andrew Morgan <morgan@kernel.org>, who also supplied the
+ * template for this file (via pam_mail)
+ */
+
+#define DEFAULT_ETC_ENVFILE "/etc/environment"
+#define DEFAULT_READ_ENVFILE 1
+
+#define DEFAULT_USER_ENVFILE ".pam_environment"
+#define DEFAULT_USER_READ_ENVFILE 0
+
+#include "config.h"
+
+#include <ctype.h>
+#include <errno.h>
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+#include <security/_pam_macros.h>
+#include <security/pam_ext.h>
+#include "pam_inline.h"
+
+/* This little structure makes it easier to keep variables together */
+
+typedef struct var {
+ char *name;
+ char *value;
+ char *defval;
+ char *override;
+} VAR;
+
+#define BUF_SIZE 8192
+#define MAX_ENV 8192
+
+#define GOOD_LINE 0
+#define BAD_LINE 100 /* This must be > the largest PAM_* error code */
+
+#define DEFINE_VAR 101
+#define UNDEFINE_VAR 102
+#define ILLEGAL_VAR 103
+
+static int _assemble_line(FILE *, char *, int);
+static int _parse_line(const pam_handle_t *, const char *, VAR *);
+static int _check_var(pam_handle_t *, VAR *); /* This is the real meat */
+static void _clean_var(VAR *);
+static int _expand_arg(pam_handle_t *, char **);
+static const char * _pam_get_item_byname(pam_handle_t *, const char *);
+static int _define_var(pam_handle_t *, int, VAR *);
+static int _undefine_var(pam_handle_t *, int, VAR *);
+
+/* This is a special value used to designate an empty string */
+static char quote='\0';
+
+/* argument parsing */
+
+#define PAM_DEBUG_ARG 0x01
+
+static int
+_pam_parse (const pam_handle_t *pamh, int argc, const char **argv,
+ const char **conffile, const char **envfile, int *readenv,
+ const char **user_envfile, int *user_readenv)
+{
+ int ctrl=0;
+
+ *user_envfile = DEFAULT_USER_ENVFILE;
+ *envfile = DEFAULT_ETC_ENVFILE;
+ *readenv = DEFAULT_READ_ENVFILE;
+ *user_readenv = DEFAULT_USER_READ_ENVFILE;
+ *conffile = DEFAULT_CONF_FILE;
+
+ /* step through arguments */
+ for (; argc-- > 0; ++argv) {
+ const char *str;
+
+ /* generic options */
+
+ if (!strcmp(*argv,"debug"))
+ ctrl |= PAM_DEBUG_ARG;
+ else if ((str = pam_str_skip_prefix(*argv, "conffile=")) != NULL) {
+ if (str[0] == '\0') {
+ pam_syslog(pamh, LOG_ERR,
+ "conffile= specification missing argument - ignored");
+ } else {
+ *conffile = str;
+ D(("new Configuration File: %s", *conffile));
+ }
+ } else if ((str = pam_str_skip_prefix(*argv, "envfile=")) != NULL) {
+ if (str[0] == '\0') {
+ pam_syslog (pamh, LOG_ERR,
+ "envfile= specification missing argument - ignored");
+ } else {
+ *envfile = str;
+ D(("new Env File: %s", *envfile));
+ }
+ } else if ((str = pam_str_skip_prefix(*argv, "user_envfile=")) != NULL) {
+ if (str[0] == '\0') {
+ pam_syslog (pamh, LOG_ERR,
+ "user_envfile= specification missing argument - ignored");
+ } else {
+ *user_envfile = str;
+ D(("new User Env File: %s", *user_envfile));
+ }
+ } else if ((str = pam_str_skip_prefix(*argv, "readenv=")) != NULL) {
+ *readenv = atoi(str);
+ } else if ((str = pam_str_skip_prefix(*argv, "user_readenv=")) != NULL) {
+ *user_readenv = atoi(str);
+ } else
+ pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
+ }
+
+ if (*user_readenv)
+ pam_syslog(pamh, LOG_DEBUG, "deprecated reading of user environment enabled");
+
+ return ctrl;
+}
+
+static int
+_parse_config_file(pam_handle_t *pamh, int ctrl, const char *file)
+{
+ int retval;
+ char buffer[BUF_SIZE];
+ FILE *conf;
+ VAR Var, *var=&Var;
+
+ D(("Called."));
+
+ var->name=NULL; var->defval=NULL; var->override=NULL;
+
+ D(("Config file name is: %s", file));
+
+ /*
+ * Lets try to open the config file, parse it and process
+ * any variables found.
+ */
+
+ if ((conf = fopen(file,"r")) == NULL) {
+ pam_syslog(pamh, LOG_ERR, "Unable to open config file: %s: %m", file);
+ return PAM_IGNORE;
+ }
+
+ /* _pam_assemble_line will provide a complete line from the config file,
+ * with all comments removed and any escaped newlines fixed up
+ */
+
+ while (( retval = _assemble_line(conf, buffer, BUF_SIZE)) > 0) {
+ D(("Read line: %s", buffer));
+
+ if ((retval = _parse_line(pamh, buffer, var)) == GOOD_LINE) {
+ retval = _check_var(pamh, var);
+
+ if (DEFINE_VAR == retval) {
+ retval = _define_var(pamh, ctrl, var);
+
+ } else if (UNDEFINE_VAR == retval) {
+ retval = _undefine_var(pamh, ctrl, var);
+ }
+ }
+ if (PAM_SUCCESS != retval && ILLEGAL_VAR != retval
+ && BAD_LINE != retval && PAM_BAD_ITEM != retval) break;
+
+ _clean_var(var);
+
+ } /* while */
+
+ (void) fclose(conf);
+
+ /* tidy up */
+ _clean_var(var); /* We could have got here prematurely,
+ * this is safe though */
+ D(("Exit."));
+ return (retval != 0 ? PAM_ABORT : PAM_SUCCESS);
+}
+
+static int
+_parse_env_file(pam_handle_t *pamh, int ctrl, const char *file)
+{
+ int retval=PAM_SUCCESS, i, t;
+ char buffer[BUF_SIZE], *key, *mark;
+ FILE *conf;
+
+ D(("Env file name is: %s", file));
+
+ if ((conf = fopen(file,"r")) == NULL) {
+ pam_syslog(pamh, LOG_ERR, "Unable to open env file: %s: %m", file);
+ return PAM_IGNORE;
+ }
+
+ while (_assemble_line(conf, buffer, BUF_SIZE) > 0) {
+ D(("Read line: %s", buffer));
+ key = buffer;
+
+ /* skip leading white space */
+ key += strspn(key, " \n\t");
+
+ /* skip blanks lines and comments */
+ if (key[0] == '#')
+ continue;
+
+ /* skip over "export " if present so we can be compat with
+ bash type declarations */
+ if (strncmp(key, "export ", (size_t) 7) == 0)
+ key += 7;
+
+ /* now find the end of value */
+ mark = key;
+ while(mark[0] != '\n' && mark[0] != '#' && mark[0] != '\0')
+ mark++;
+ if (mark[0] != '\0')
+ mark[0] = '\0';
+
+ /*
+ * sanity check, the key must be alphanumeric
+ */
+
+ if (key[0] == '=') {
+ pam_syslog(pamh, LOG_ERR,
+ "missing key name '%s' in %s', ignoring",
+ key, file);
+ continue;
+ }
+
+ for ( i = 0 ; key[i] != '=' && key[i] != '\0' ; i++ )
+ if (!isalnum(key[i]) && key[i] != '_') {
+ pam_syslog(pamh, LOG_ERR,
+ "non-alphanumeric key '%s' in %s', ignoring",
+ key, file);
+ break;
+ }
+ /* non-alphanumeric key, ignore this line */
+ if (key[i] != '=' && key[i] != '\0')
+ continue;
+
+ /* now we try to be smart about quotes around the value,
+ but not too smart, we can't get all fancy with escaped
+ values like bash */
+ if (key[i] == '=' && (key[++i] == '\"' || key[i] == '\'')) {
+ for ( t = i+1 ; key[t] != '\0' ; t++)
+ if (key[t] != '\"' && key[t] != '\'')
+ key[i++] = key[t];
+ else if (key[t+1] != '\0')
+ key[i++] = key[t];
+ key[i] = '\0';
+ }
+
+ /* if this is a request to delete a variable, check that it's
+ actually set first, so we don't get a vague error back from
+ pam_putenv() */
+ for (i = 0; key[i] != '=' && key[i] != '\0'; i++);
+
+ if (key[i] == '\0' && !pam_getenv(pamh,key))
+ continue;
+
+ /* set the env var, if it fails, we break out of the loop */
+ retval = pam_putenv(pamh, key);
+ if (retval != PAM_SUCCESS) {
+ D(("error setting env \"%s\"", key));
+ break;
+ } else if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "pam_putenv(\"%s\")", key);
+ }
+ }
+
+ (void) fclose(conf);
+
+ /* tidy up */
+ D(("Exit."));
+ return retval;
+}
+
+/*
+ * This is where we read a line of the PAM config file. The line may be
+ * preceded by lines of comments and also extended with "\\\n"
+ */
+
+static int _assemble_line(FILE *f, char *buffer, int buf_len)
+{
+ char *p = buffer;
+ char *s, *os;
+ int used = 0;
+ int whitespace;
+
+ /* loop broken with a 'break' when a non-'\\n' ended line is read */
+
+ D(("called."));
+ for (;;) {
+ if (used >= buf_len) {
+ /* Overflow */
+ D(("_assemble_line: overflow"));
+ return -1;
+ }
+ if (fgets(p, buf_len - used, f) == NULL) {
+ if (used) {
+ /* Incomplete read */
+ return -1;
+ } else {
+ /* EOF */
+ return 0;
+ }
+ }
+ if (p[0] == '\0') {
+ D(("_assemble_line: corrupted or binary file"));
+ return -1;
+ }
+ if (p[strlen(p)-1] != '\n' && !feof(f)) {
+ D(("_assemble_line: line too long"));
+ return -1;
+ }
+
+ /* skip leading spaces --- line may be blank */
+
+ whitespace = strspn(p, " \n\t");
+ s = p + whitespace;
+ if (*s && (*s != '#')) {
+ used += whitespace;
+ os = s;
+
+ /*
+ * we are only interested in characters before the first '#'
+ * character
+ */
+
+ while (*s && *s != '#')
+ ++s;
+ if (*s == '#') {
+ *s = '\0';
+ used += strlen(os);
+ break; /* the line has been read */
+ }
+
+ s = os;
+
+ /*
+ * Check for backslash by scanning back from the end of
+ * the entered line, the '\n' has been included since
+ * normally a line is terminated with this
+ * character. fgets() should only return one though!
+ */
+
+ s += strlen(s);
+ while (s > os && ((*--s == ' ') || (*s == '\t')
+ || (*s == '\n')));
+
+ /* check if it ends with a backslash */
+ if (*s == '\\') {
+ *s = '\0'; /* truncate the line here */
+ used += strlen(os);
+ p = s; /* there is more ... */
+ } else {
+ /* End of the line! */
+ used += strlen(os);
+ break; /* this is the complete line */
+ }
+
+ } else {
+ /* Nothing in this line */
+ /* Don't move p */
+ }
+ }
+
+ return used;
+}
+
+static int
+_parse_line (const pam_handle_t *pamh, const char *buffer, VAR *var)
+{
+ /*
+ * parse buffer into var, legal syntax is
+ * VARIABLE [DEFAULT=[[string]] [OVERRIDE=[value]]
+ *
+ * Any other options defined make this a bad line,
+ * error logged and no var set
+ */
+
+ int length, quoteflg=0;
+ const char *ptr, *tmpptr;
+ char **valptr;
+
+ D(("Called buffer = <%s>", buffer));
+
+ length = strcspn(buffer," \t\n");
+
+ if ((var->name = malloc(length + 1)) == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "Couldn't malloc %d bytes", length+1);
+ return PAM_BUF_ERR;
+ }
+
+ /*
+ * The first thing on the line HAS to be the variable name,
+ * it may be the only thing though.
+ */
+ strncpy(var->name, buffer, length);
+ var->name[length] = '\0';
+ D(("var->name = <%s>, length = %d", var->name, length));
+
+ /*
+ * Now we check for arguments, we only support two kinds and ('cause I am lazy)
+ * each one can actually be listed any number of times
+ */
+
+ ptr = buffer+length;
+ while ((length = strspn(ptr, " \t")) > 0) {
+ ptr += length; /* remove leading whitespace */
+ D((ptr));
+ if ((tmpptr = pam_str_skip_prefix(ptr, "DEFAULT=")) != NULL) {
+ ptr = tmpptr;
+ D(("Default arg found: <%s>", ptr));
+ valptr=&(var->defval);
+ } else if ((tmpptr = pam_str_skip_prefix(ptr, "OVERRIDE=")) != NULL) {
+ ptr = tmpptr;
+ D(("Override arg found: <%s>", ptr));
+ valptr=&(var->override);
+ } else {
+ D(("Unrecognized options: <%s> - ignoring line", ptr));
+ pam_syslog(pamh, LOG_ERR, "Unrecognized Option: %s - ignoring line", ptr);
+ return BAD_LINE;
+ }
+
+ if ('"' != *ptr) { /* Escaped quotes not supported */
+ length = strcspn(ptr, " \t\n");
+ tmpptr = ptr+length;
+ } else {
+ tmpptr = strchr(++ptr, '"');
+ if (!tmpptr) {
+ D(("Unterminated quoted string: %s", ptr-1));
+ pam_syslog(pamh, LOG_ERR, "Unterminated quoted string: %s", ptr-1);
+ return BAD_LINE;
+ }
+ length = tmpptr - ptr;
+ if (*++tmpptr && ' ' != *tmpptr && '\t' != *tmpptr && '\n' != *tmpptr) {
+ D(("Quotes must cover the entire string: <%s>", ptr));
+ pam_syslog(pamh, LOG_ERR, "Quotes must cover the entire string: <%s>", ptr);
+ return BAD_LINE;
+ }
+ quoteflg++;
+ }
+ if (length) {
+ if ((*valptr = malloc(length + 1)) == NULL) {
+ D(("Couldn't malloc %d bytes", length+1));
+ pam_syslog(pamh, LOG_CRIT, "Couldn't malloc %d bytes", length+1);
+ return PAM_BUF_ERR;
+ }
+ (void)strncpy(*valptr,ptr,length);
+ (*valptr)[length]='\0';
+ } else if (quoteflg--) {
+ *valptr = &quote; /* a quick hack to handle the empty string */
+ }
+ ptr = tmpptr; /* Start the search where we stopped */
+ } /* while */
+
+ /*
+ * The line is parsed, all is well.
+ */
+
+ D(("Exit."));
+ ptr = NULL; tmpptr = NULL; valptr = NULL;
+ return GOOD_LINE;
+}
+
+static int _check_var(pam_handle_t *pamh, VAR *var)
+{
+ /*
+ * Examine the variable and determine what action to take.
+ * Returns DEFINE_VAR, UNDEFINE_VAR depending on action to take
+ * or a PAM_* error code if passed back from other routines
+ *
+ * if no DEFAULT provided, the empty string is assumed
+ * if no OVERRIDE provided, the empty string is assumed
+ * if DEFAULT= and OVERRIDE evaluates to the empty string,
+ * this variable should be undefined
+ * if DEFAULT="" and OVERRIDE evaluates to the empty string,
+ * this variable should be defined with no value
+ * if OVERRIDE=value and value turns into the empty string, DEFAULT is used
+ *
+ * If DEFINE_VAR is to be returned, the correct value to define will
+ * be pointed to by var->value
+ */
+
+ int retval;
+
+ D(("Called."));
+
+ /*
+ * First thing to do is to expand any arguments, but only
+ * if they are not the special quote values (cause expand_arg
+ * changes memory).
+ */
+
+ if (var->defval && (&quote != var->defval) &&
+ ((retval = _expand_arg(pamh, &(var->defval))) != PAM_SUCCESS)) {
+ return retval;
+ }
+ if (var->override && (&quote != var->override) &&
+ ((retval = _expand_arg(pamh, &(var->override))) != PAM_SUCCESS)) {
+ return retval;
+ }
+
+ /* Now its easy */
+
+ if (var->override && *(var->override)) {
+ /* if there is a non-empty string in var->override, we use it */
+ D(("OVERRIDE variable <%s> being used: <%s>", var->name, var->override));
+ var->value = var->override;
+ retval = DEFINE_VAR;
+ } else {
+
+ var->value = var->defval;
+ if (&quote == var->defval) {
+ /*
+ * This means that the empty string was given for defval value
+ * which indicates that a variable should be defined with no value
+ */
+ D(("An empty variable: <%s>", var->name));
+ retval = DEFINE_VAR;
+ } else if (var->defval) {
+ D(("DEFAULT variable <%s> being used: <%s>", var->name, var->defval));
+ retval = DEFINE_VAR;
+ } else {
+ D(("UNDEFINE variable <%s>", var->name));
+ retval = UNDEFINE_VAR;
+ }
+ }
+
+ D(("Exit."));
+ return retval;
+}
+
+static int _expand_arg(pam_handle_t *pamh, char **value)
+{
+ const char *orig=*value, *tmpptr=NULL;
+ char *ptr; /*
+ * Sure would be nice to use tmpptr but it needs to be
+ * a constant so that the compiler will shut up when I
+ * call pam_getenv and _pam_get_item_byname -- sigh
+ */
+
+ /* No unexpanded variable can be bigger than BUF_SIZE */
+ char type, tmpval[BUF_SIZE];
+
+ /* I know this shouldn't be hard-coded but it's so much easier this way */
+ char tmp[MAX_ENV];
+ size_t idx;
+
+ D(("Remember to initialize tmp!"));
+ memset(tmp, 0, MAX_ENV);
+ idx = 0;
+
+ /*
+ * (possibly non-existent) environment variables can be used as values
+ * by prepending a "$" and wrapping in {} (ie: ${HOST}), can escape with "\"
+ * (possibly non-existent) PAM items can be used as values
+ * by prepending a "@" and wrapping in {} (ie: @{PAM_RHOST}, can escape
+ *
+ */
+ D(("Expanding <%s>",orig));
+ while (*orig) { /* while there is some input to deal with */
+ if ('\\' == *orig) {
+ ++orig;
+ if ('$' != *orig && '@' != *orig) {
+ D(("Unrecognized escaped character: <%c> - ignoring", *orig));
+ pam_syslog(pamh, LOG_ERR,
+ "Unrecognized escaped character: <%c> - ignoring",
+ *orig);
+ } else if (idx + 1 < MAX_ENV) {
+ tmp[idx++] = *orig++; /* Note the increment */
+ } else {
+ /* is it really a good idea to try to log this? */
+ D(("Variable buffer overflow: <%s> + <%s>", tmp, tmpptr));
+ pam_syslog (pamh, LOG_ERR, "Variable buffer overflow: <%s> + <%s>",
+ tmp, tmpptr);
+ return PAM_BUF_ERR;
+ }
+ continue;
+ }
+ if ('$' == *orig || '@' == *orig) {
+ if ('{' != *(orig+1)) {
+ D(("Expandable variables must be wrapped in {}"
+ " <%s> - ignoring", orig));
+ pam_syslog(pamh, LOG_ERR, "Expandable variables must be wrapped in {}"
+ " <%s> - ignoring", orig);
+ if (idx + 1 < MAX_ENV) {
+ tmp[idx++] = *orig++; /* Note the increment */
+ }
+ continue;
+ } else {
+ D(("Expandable argument: <%s>", orig));
+ type = *orig;
+ orig+=2; /* skip the ${ or @{ characters */
+ ptr = strchr(orig, '}');
+ if (ptr) {
+ *ptr++ = '\0';
+ } else {
+ D(("Unterminated expandable variable: <%s>", orig-2));
+ pam_syslog(pamh, LOG_ERR,
+ "Unterminated expandable variable: <%s>", orig-2);
+ return PAM_ABORT;
+ }
+ strncpy(tmpval, orig, sizeof(tmpval));
+ tmpval[sizeof(tmpval)-1] = '\0';
+ orig=ptr;
+ /*
+ * so, we know we need to expand tmpval, it is either
+ * an environment variable or a PAM_ITEM. type will tell us which
+ */
+ switch (type) {
+
+ case '$':
+ D(("Expanding env var: <%s>",tmpval));
+ tmpptr = pam_getenv(pamh, tmpval);
+ D(("Expanded to <%s>", tmpptr));
+ break;
+
+ case '@':
+ D(("Expanding pam item: <%s>",tmpval));
+ tmpptr = _pam_get_item_byname(pamh, tmpval);
+ D(("Expanded to <%s>", tmpptr));
+ break;
+
+ default:
+ D(("Impossible error, type == <%c>", type));
+ pam_syslog(pamh, LOG_CRIT, "Impossible error, type == <%c>", type);
+ return PAM_ABORT;
+ } /* switch */
+
+ if (tmpptr) {
+ size_t len = strlen(tmpptr);
+ if (idx + len < MAX_ENV) {
+ strcpy(tmp + idx, tmpptr);
+ idx += len;
+ } else {
+ /* is it really a good idea to try to log this? */
+ D(("Variable buffer overflow: <%s> + <%s>", tmp, tmpptr));
+ pam_syslog (pamh, LOG_ERR,
+ "Variable buffer overflow: <%s> + <%s>", tmp, tmpptr);
+ return PAM_BUF_ERR;
+ }
+ }
+ } /* if ('{' != *orig++) */
+ } else { /* if ( '$' == *orig || '@' == *orig) */
+ if (idx + 1 < MAX_ENV) {
+ tmp[idx++] = *orig++; /* Note the increment */
+ } else {
+ /* is it really a good idea to try to log this? */
+ D(("Variable buffer overflow: <%s> + <%s>", tmp, tmpptr));
+ pam_syslog(pamh, LOG_ERR,
+ "Variable buffer overflow: <%s> + <%s>", tmp, tmpptr);
+ return PAM_BUF_ERR;
+ }
+ }
+ } /* for (;*orig;) */
+
+ if (idx > strlen(*value)) {
+ free(*value);
+ if ((*value = malloc(idx + 1)) == NULL) {
+ D(("Couldn't malloc %d bytes for expanded var", idx + 1));
+ pam_syslog (pamh, LOG_CRIT, "Couldn't malloc %lu bytes for expanded var",
+ (unsigned long)idx+1);
+ return PAM_BUF_ERR;
+ }
+ }
+ strcpy(*value, tmp);
+ memset(tmp, '\0', sizeof(tmp));
+ D(("Exit."));
+
+ return PAM_SUCCESS;
+}
+
+static const char * _pam_get_item_byname(pam_handle_t *pamh, const char *name)
+{
+ /*
+ * This function just allows me to use names as given in the config
+ * file and translate them into the appropriate PAM_ITEM macro
+ */
+
+ int item;
+ const void *itemval;
+
+ D(("Called."));
+ if (strcmp(name, "PAM_USER") == 0 || strcmp(name, "HOME") == 0 || strcmp(name, "SHELL") == 0) {
+ item = PAM_USER;
+ } else if (strcmp(name, "PAM_USER_PROMPT") == 0) {
+ item = PAM_USER_PROMPT;
+ } else if (strcmp(name, "PAM_TTY") == 0) {
+ item = PAM_TTY;
+ } else if (strcmp(name, "PAM_RUSER") == 0) {
+ item = PAM_RUSER;
+ } else if (strcmp(name, "PAM_RHOST") == 0) {
+ item = PAM_RHOST;
+ } else {
+ D(("Unknown PAM_ITEM: <%s>", name));
+ pam_syslog (pamh, LOG_ERR, "Unknown PAM_ITEM: <%s>", name);
+ return NULL;
+ }
+
+ if (pam_get_item(pamh, item, &itemval) != PAM_SUCCESS) {
+ D(("pam_get_item failed"));
+ return NULL; /* let pam_get_item() log the error */
+ }
+
+ if (itemval && (strcmp(name, "HOME") == 0 || strcmp(name, "SHELL") == 0)) {
+ struct passwd *user_entry;
+ user_entry = pam_modutil_getpwnam (pamh, itemval);
+ if (!user_entry) {
+ pam_syslog(pamh, LOG_ERR, "No such user!?");
+ return NULL;
+ }
+ return (strcmp(name, "SHELL") == 0) ?
+ user_entry->pw_shell :
+ user_entry->pw_dir;
+ }
+
+ D(("Exit."));
+ return itemval;
+}
+
+static int _define_var(pam_handle_t *pamh, int ctrl, VAR *var)
+{
+ /* We have a variable to define, this is a simple function */
+
+ char *envvar;
+ int retval = PAM_SUCCESS;
+
+ D(("Called."));
+ if (asprintf(&envvar, "%s=%s", var->name, var->value) < 0) {
+ pam_syslog(pamh, LOG_CRIT, "out of memory");
+ return PAM_BUF_ERR;
+ }
+
+ retval = pam_putenv(pamh, envvar);
+ if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_DEBUG, "pam_putenv(\"%s\")", envvar);
+ }
+ _pam_drop(envvar);
+ D(("Exit."));
+ return retval;
+}
+
+static int _undefine_var(pam_handle_t *pamh, int ctrl, VAR *var)
+{
+ /* We have a variable to undefine, this is a simple function */
+
+ D(("Called and exit."));
+ if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_DEBUG, "remove variable \"%s\"", var->name);
+ }
+ return pam_putenv(pamh, var->name);
+}
+
+static void _clean_var(VAR *var)
+{
+ if (var->name) {
+ free(var->name);
+ }
+ if (var->defval && (&quote != var->defval)) {
+ free(var->defval);
+ }
+ if (var->override && (&quote != var->override)) {
+ free(var->override);
+ }
+ var->name = NULL;
+ var->value = NULL; /* never has memory specific to it */
+ var->defval = NULL;
+ var->override = NULL;
+ return;
+}
+
+
+
+/* --- authentication management functions (only) --- */
+
+int
+pam_sm_authenticate (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_IGNORE;
+}
+
+static int
+handle_env (pam_handle_t *pamh, int argc, const char **argv)
+{
+ int retval, ctrl, readenv=DEFAULT_READ_ENVFILE;
+ int user_readenv = DEFAULT_USER_READ_ENVFILE;
+ const char *conf_file = NULL, *env_file = NULL, *user_env_file = NULL;
+
+ /*
+ * this module sets environment variables read in from a file
+ */
+
+ D(("Called."));
+ ctrl = _pam_parse(pamh, argc, argv, &conf_file, &env_file,
+ &readenv, &user_env_file, &user_readenv);
+
+ retval = _parse_config_file(pamh, ctrl, conf_file);
+
+ if(readenv && retval == PAM_SUCCESS) {
+ retval = _parse_env_file(pamh, ctrl, env_file);
+ if (retval == PAM_IGNORE)
+ retval = PAM_SUCCESS;
+ }
+
+ if(user_readenv && retval == PAM_SUCCESS) {
+ char *envpath = NULL;
+ struct passwd *user_entry = NULL;
+ const char *username;
+ struct stat statbuf;
+
+ username = _pam_get_item_byname(pamh, "PAM_USER");
+
+ if (username)
+ user_entry = pam_modutil_getpwnam (pamh, username);
+ if (!user_entry) {
+ pam_syslog(pamh, LOG_ERR, "No such user!?");
+ }
+ else {
+ if (asprintf(&envpath, "%s/%s", user_entry->pw_dir, user_env_file) < 0)
+ {
+ pam_syslog(pamh, LOG_CRIT, "Out of memory");
+ return PAM_BUF_ERR;
+ }
+ if (stat(envpath, &statbuf) == 0) {
+ PAM_MODUTIL_DEF_PRIVS(privs);
+
+ if (pam_modutil_drop_priv(pamh, &privs, user_entry)) {
+ retval = PAM_SESSION_ERR;
+ } else {
+ retval = _parse_config_file(pamh, ctrl, envpath);
+ if (pam_modutil_regain_priv(pamh, &privs))
+ retval = PAM_SESSION_ERR;
+ }
+ if (retval == PAM_IGNORE)
+ retval = PAM_SUCCESS;
+ }
+ free(envpath);
+ }
+ }
+
+ /* indicate success or failure */
+ D(("Exit."));
+ return retval;
+}
+
+int
+pam_sm_acct_mgmt (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ pam_syslog (pamh, LOG_NOTICE, "pam_sm_acct_mgmt called inappropriately");
+ return PAM_SERVICE_ERR;
+}
+
+int
+pam_sm_setcred (pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ D(("Called"));
+ return handle_env (pamh, argc, argv);
+}
+
+int
+pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ D(("Called"));
+ return handle_env (pamh, argc, argv);
+}
+
+int
+pam_sm_close_session (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ D(("Called and Exit"));
+ return PAM_SUCCESS;
+}
+
+int
+pam_sm_chauthtok (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ pam_syslog (pamh, LOG_NOTICE, "pam_sm_chauthtok called inappropriately");
+ return PAM_SERVICE_ERR;
+}
+
+/* end of module definition */
diff --git a/modules/pam_env/pam_env.conf b/modules/pam_env/pam_env.conf
new file mode 100644
index 0000000..2549e43
--- /dev/null
+++ b/modules/pam_env/pam_env.conf
@@ -0,0 +1,73 @@
+#
+# This is the configuration file for pam_env, a PAM module to load in
+# a configurable list of environment variables for a
+#
+# The original idea for this came from Andrew G. Morgan ...
+#<quote>
+# Mmm. Perhaps you might like to write a pam_env module that reads a
+# default environment from a file? I can see that as REALLY
+# useful... Note it would be an "auth" module that returns PAM_IGNORE
+# for the auth part and sets the environment returning PAM_SUCCESS in
+# the setcred function...
+#</quote>
+#
+# What I wanted was the REMOTEHOST variable set, purely for selfish
+# reasons, and AGM didn't want it added to the SimpleApps login
+# program (which is where I added the patch). So, my first concern is
+# that variable, from there there are numerous others that might/would
+# be useful to be set: NNTPSERVER, LESS, PATH, PAGER, MANPAGER .....
+#
+# Of course, these are a different kind of variable than REMOTEHOST in
+# that they are things that are likely to be configured by
+# administrators rather than set by logging in, how to treat them both
+# in the same config file?
+#
+# Here is my idea:
+#
+# Each line starts with the variable name, there are then two possible
+# options for each variable DEFAULT and OVERRIDE.
+# DEFAULT allows an administrator to set the value of the
+# variable to some default value, if none is supplied then the empty
+# string is assumed. The OVERRIDE option tells pam_env that it should
+# enter in its value (overriding the default value) if there is one
+# to use. OVERRIDE is not used, "" is assumed and no override will be
+# done.
+#
+# VARIABLE [DEFAULT=[value]] [OVERRIDE=[value]]
+#
+# (Possibly non-existent) environment variables may be used in values
+# using the ${string} syntax and (possibly non-existent) PAM_ITEMs may
+# be used in values using the @{string} syntax. Both the $ and @
+# characters can be backslash escaped to be used as literal values
+# values can be delimited with "", escaped " not supported.
+# Note that many environment variables that you would like to use
+# may not be set by the time the module is called.
+# For example, HOME is used below several times, but
+# many PAM applications don't make it available by the time you need it.
+#
+#
+# First, some special variables
+#
+# Set the REMOTEHOST variable for any hosts that are remote, default
+# to "localhost" rather than not being set at all
+#REMOTEHOST DEFAULT=localhost OVERRIDE=@{PAM_RHOST}
+#
+# Set the DISPLAY variable if it seems reasonable
+#DISPLAY DEFAULT=${REMOTEHOST}:0.0 OVERRIDE=${DISPLAY}
+#
+#
+# Now some simple variables
+#
+#PAGER DEFAULT=less
+#MANPAGER DEFAULT=less
+#LESS DEFAULT="M q e h15 z23 b80"
+#NNTPSERVER DEFAULT=localhost
+#PATH DEFAULT=${HOME}/bin:/usr/local/bin:/bin\
+#:/usr/bin:/usr/local/bin/X11:/usr/bin/X11
+#
+# silly examples of escaped variables, just to show how they work.
+#
+#DOLLAR DEFAULT=\$
+#DOLLARDOLLAR DEFAULT= OVERRIDE=\$${DOLLAR}
+#DOLLARPLUS DEFAULT=\${REMOTEHOST}${REMOTEHOST}
+#ATSIGN DEFAULT="" OVERRIDE=\@
diff --git a/modules/pam_env/pam_env.conf.5 b/modules/pam_env/pam_env.conf.5
new file mode 100644
index 0000000..40fd118
--- /dev/null
+++ b/modules/pam_env/pam_env.conf.5
@@ -0,0 +1,132 @@
+'\" t
+.\" Title: pam_env.conf
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_ENV\&.CONF" "5" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_env.conf, environment \- the environment variables config files
+.SH "DESCRIPTION"
+.PP
+The
+/etc/security/pam_env\&.conf
+file specifies the environment variables to be set, unset or modified by
+\fBpam_env\fR(8)\&. When someone logs in, this file is read and the environment variables are set according\&.
+.PP
+Each line starts with the variable name, there are then two possible options for each variable DEFAULT and OVERRIDE\&. DEFAULT allows an administrator to set the value of the variable to some default value, if none is supplied then the empty string is assumed\&. The OVERRIDE option tells pam_env that it should enter in its value (overriding the default value) if there is one to use\&. OVERRIDE is not used, "" is assumed and no override will be done\&.
+.PP
+\fIVARIABLE\fR
+[\fIDEFAULT=[value]\fR] [\fIOVERRIDE=[value]\fR]
+.PP
+(Possibly non\-existent) environment variables may be used in values using the ${string} syntax and (possibly non\-existent) PAM_ITEMs as well as HOME and SHELL may be used in values using the @{string} syntax\&. Both the $ and @ characters can be backslash escaped to be used as literal values values can be delimited with "", escaped " not supported\&. Note that many environment variables that you would like to use may not be set by the time the module is called\&. For example, ${HOME} is used below several times, but many PAM applications don\*(Aqt make it available by the time you need it\&. The special variables @{HOME} and @{SHELL} are expanded to the values for the user from his
+\fIpasswd\fR
+entry\&.
+.PP
+The "\fI#\fR" character at start of line (no space at front) can be used to mark this line as a comment line\&.
+.PP
+The
+/etc/environment
+file specifies the environment variables to be set\&. The file must consist of simple
+\fINAME=VALUE\fR
+pairs on separate lines\&. The
+\fBpam_env\fR(8)
+module will read the file after the
+pam_env\&.conf
+file\&.
+.SH "EXAMPLES"
+.PP
+These are some example lines which might be specified in
+/etc/security/pam_env\&.conf\&.
+.PP
+Set the REMOTEHOST variable for any hosts that are remote, default to "localhost" rather than not being set at all
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ REMOTEHOST DEFAULT=localhost OVERRIDE=@{PAM_RHOST}
+
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Set the DISPLAY variable if it seems reasonable
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ DISPLAY DEFAULT=${REMOTEHOST}:0\&.0 OVERRIDE=${DISPLAY}
+
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Now some simple variables
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ PAGER DEFAULT=less
+ MANPAGER DEFAULT=less
+ LESS DEFAULT="M q e h15 z23 b80"
+ NNTPSERVER DEFAULT=localhost
+ PATH DEFAULT=${HOME}/bin:/usr/local/bin:/bin\e
+ :/usr/bin:/usr/local/bin/X11:/usr/bin/X11
+ XDG_DATA_HOME DEFAULT=@{HOME}/share/
+
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Silly examples of escaped variables, just to show how they work\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ DOLLAR DEFAULT=\e$
+ DOLLARDOLLAR DEFAULT= OVERRIDE=\e$${DOLLAR}
+ DOLLARPLUS DEFAULT=\e${REMOTEHOST}${REMOTEHOST}
+ ATSIGN DEFAULT="" OVERRIDE=\e@
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+.PP
+\fBpam_env\fR(8),
+\fBpam.d\fR(5),
+\fBpam\fR(8),
+\fBenviron\fR(7)
+.SH "AUTHOR"
+.PP
+pam_env was written by Dave Kinchlea <kinch@kinch\&.ark\&.com>\&.
diff --git a/modules/pam_env/pam_env.conf.5.xml b/modules/pam_env/pam_env.conf.5.xml
new file mode 100644
index 0000000..fca046f
--- /dev/null
+++ b/modules/pam_env/pam_env.conf.5.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_env.conf">
+
+ <refmeta>
+ <refentrytitle>pam_env.conf</refentrytitle>
+ <manvolnum>5</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>pam_env.conf</refname>
+ <refname>environment</refname>
+ <refpurpose>the environment variables config files</refpurpose>
+ </refnamediv>
+
+
+ <refsect1 id='pam_env.conf-description'>
+ <title>DESCRIPTION</title>
+
+ <para>
+ The <filename>/etc/security/pam_env.conf</filename> file specifies
+ the environment variables to be set, unset or modified by
+ <citerefentry><refentrytitle>pam_env</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+ When someone logs in, this file is read and the environment
+ variables are set according.
+ </para>
+ <para>
+ Each line starts with the variable name, there are then two possible
+ options for each variable DEFAULT and OVERRIDE. DEFAULT allows an
+ administrator to set the value of the variable to some default
+ value, if none is supplied then the empty string is assumed. The
+ OVERRIDE option tells pam_env that it should enter in its value
+ (overriding the default value) if there is one to use. OVERRIDE is
+ not used, "" is assumed and no override will be done.
+ </para>
+ <para>
+ <replaceable>VARIABLE</replaceable>
+ [<replaceable>DEFAULT=[value]</replaceable>]
+ [<replaceable>OVERRIDE=[value]</replaceable>]
+ </para>
+
+ <para>
+ (Possibly non-existent) environment variables may be used in values
+ using the ${string} syntax and (possibly non-existent) PAM_ITEMs as well
+ as HOME and SHELL may be used in values using the @{string} syntax. Both
+ the $ and @ characters can be backslash escaped to be used as literal values
+ values can be delimited with "", escaped " not supported.
+ Note that many environment variables that you would like to use
+ may not be set by the time the module is called.
+ For example, ${HOME} is used below several times, but
+ many PAM applications don't make it available by the time you need it.
+ The special variables @{HOME} and @{SHELL} are expanded to the values
+ for the user from his <emphasis>passwd</emphasis> entry.
+ </para>
+
+ <para>
+ The "<emphasis>#</emphasis>" character at start of line (no space
+ at front) can be used to mark this line as a comment line.
+ </para>
+
+ <para>
+ The <filename>/etc/environment</filename> file specifies
+ the environment variables to be set. The file must consist of simple
+ <emphasis>NAME=VALUE</emphasis> pairs on separate lines.
+ The <citerefentry><refentrytitle>pam_env</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ module will read the file after the <filename>pam_env.conf</filename>
+ file.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_env.conf-examples">
+ <title>EXAMPLES</title>
+ <para>
+ These are some example lines which might be specified in
+ <filename>/etc/security/pam_env.conf</filename>.
+ </para>
+
+ <para>
+ Set the REMOTEHOST variable for any hosts that are remote, default
+ to "localhost" rather than not being set at all
+ </para>
+ <programlisting>
+ REMOTEHOST DEFAULT=localhost OVERRIDE=@{PAM_RHOST}
+ </programlisting>
+
+ <para>
+ Set the DISPLAY variable if it seems reasonable
+ </para>
+ <programlisting>
+ DISPLAY DEFAULT=${REMOTEHOST}:0.0 OVERRIDE=${DISPLAY}
+ </programlisting>
+
+ <para>
+ Now some simple variables
+ </para>
+ <programlisting>
+ PAGER DEFAULT=less
+ MANPAGER DEFAULT=less
+ LESS DEFAULT="M q e h15 z23 b80"
+ NNTPSERVER DEFAULT=localhost
+ PATH DEFAULT=${HOME}/bin:/usr/local/bin:/bin\
+ :/usr/bin:/usr/local/bin/X11:/usr/bin/X11
+ XDG_DATA_HOME DEFAULT=@{HOME}/share/
+ </programlisting>
+
+ <para>
+ Silly examples of escaped variables, just to show how they work.
+ </para>
+ <programlisting>
+ DOLLAR DEFAULT=\$
+ DOLLARDOLLAR DEFAULT= OVERRIDE=\$${DOLLAR}
+ DOLLARPLUS DEFAULT=\${REMOTEHOST}${REMOTEHOST}
+ ATSIGN DEFAULT="" OVERRIDE=\@
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id="pam_env.conf-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry><refentrytitle>pam_env</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_env.conf-author">
+ <title>AUTHOR</title>
+ <para>
+ pam_env was written by Dave Kinchlea &lt;kinch@kinch.ark.com&gt;.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_env/tst-pam_env b/modules/pam_env/tst-pam_env
new file mode 100755
index 0000000..c40e70a
--- /dev/null
+++ b/modules/pam_env/tst-pam_env
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_env.so
diff --git a/modules/pam_exec/Makefile.am b/modules/pam_exec/Makefile.am
new file mode 100644
index 0000000..713de6a
--- /dev/null
+++ b/modules/pam_exec/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_exec.8
+endif
+XMLS = README.xml pam_exec.8.xml
+dist_check_SCRIPTS = tst-pam_exec
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_exec.la
+pam_exec_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_exec/Makefile.in b/modules/pam_exec/Makefile.in
new file mode 100644
index 0000000..a312387
--- /dev/null
+++ b/modules/pam_exec/Makefile.in
@@ -0,0 +1,1150 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_exec
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_exec_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_exec_la_SOURCES = pam_exec.c
+pam_exec_la_OBJECTS = pam_exec.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_exec.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_exec.c
+DIST_SOURCES = pam_exec.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_exec.8
+XMLS = README.xml pam_exec.8.xml
+dist_check_SCRIPTS = tst-pam_exec
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_exec.la
+pam_exec_la_LIBADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_exec/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_exec/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_exec.la: $(pam_exec_la_OBJECTS) $(pam_exec_la_DEPENDENCIES) $(EXTRA_pam_exec_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_exec_la_OBJECTS) $(pam_exec_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_exec.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_exec.log: tst-pam_exec
+ @p='tst-pam_exec'; \
+ b='tst-pam_exec'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_exec.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_exec.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_exec/README b/modules/pam_exec/README
new file mode 100644
index 0000000..3959162
--- /dev/null
+++ b/modules/pam_exec/README
@@ -0,0 +1,79 @@
+pam_exec — PAM module which calls an external command
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+pam_exec is a PAM module that can be used to run an external command.
+
+The child's environment is set to the current PAM environment list, as returned
+by pam_getenvlist(3) In addition, the following PAM items are exported as
+environment variables: PAM_RHOST, PAM_RUSER, PAM_SERVICE, PAM_TTY, PAM_USER and
+PAM_TYPE, which contains one of the module types: account, auth, password,
+open_session and close_session.
+
+Commands called by pam_exec need to be aware of that the user can have control
+over the environment.
+
+OPTIONS
+
+debug
+
+ Print debug information.
+
+expose_authtok
+
+ During authentication the calling command can read the password from stdin
+ (3). Only first PAM_MAX_RESP_SIZE bytes of a password are provided to the
+ command.
+
+log=file
+
+ The output of the command is appended to file
+
+type=type
+
+ Only run the command if the module type matches the given type.
+
+stdout
+
+ Per default the output of the executed command is written to /dev/null.
+ With this option, the stdout output of the executed command is redirected
+ to the calling application. It's in the responsibility of this application
+ what happens with the output. The log option is ignored.
+
+quiet
+
+ Per default pam_exec.so will echo the exit status of the external command
+ if it fails. Specifying this option will suppress the message.
+
+quiet_log
+
+ Per default pam_exec.so will log the exit status of the external command if
+ it fails. Specifying this option will suppress the log message.
+
+seteuid
+
+ Per default pam_exec.so will execute the external command with the real
+ user ID of the calling process. Specifying this option means the command is
+ run with the effective user ID.
+
+EXAMPLES
+
+Add the following line to /etc/pam.d/passwd to rebuild the NIS database after
+each local password change:
+
+ password optional pam_exec.so seteuid /usr/bin/make -C /var/yp
+
+
+This will execute the command
+
+make -C /var/yp
+
+with effective user ID.
+
+AUTHOR
+
+pam_exec was written by Thorsten Kukuk <kukuk@thkukuk.de> and Josh Triplett
+<josh@joshtriplett.org>.
+
diff --git a/modules/pam_exec/README.xml b/modules/pam_exec/README.xml
new file mode 100644
index 0000000..5e76cab
--- /dev/null
+++ b/modules/pam_exec/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_exec.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_exec.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_exec-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_exec.8.xml" xpointer='xpointer(//refsect1[@id = "pam_exec-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_exec.8.xml" xpointer='xpointer(//refsect1[@id = "pam_exec-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_exec.8.xml" xpointer='xpointer(//refsect1[@id = "pam_exec-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_exec.8.xml" xpointer='xpointer(//refsect1[@id = "pam_exec-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_exec/pam_exec.8 b/modules/pam_exec/pam_exec.8
new file mode 100644
index 0000000..7108791
--- /dev/null
+++ b/modules/pam_exec/pam_exec.8
@@ -0,0 +1,188 @@
+'\" t
+.\" Title: pam_exec
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_EXEC" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_exec \- PAM module which calls an external command
+.SH "SYNOPSIS"
+.HP \w'\fBpam_exec\&.so\fR\ 'u
+\fBpam_exec\&.so\fR [debug] [expose_authtok] [seteuid] [quiet] [quiet_log] [stdout] [log=\fIfile\fR] [type=\fItype\fR] \fIcommand\fR [\fI\&.\&.\&.\fR]
+.SH "DESCRIPTION"
+.PP
+pam_exec is a PAM module that can be used to run an external command\&.
+.PP
+The child\*(Aqs environment is set to the current PAM environment list, as returned by
+\fBpam_getenvlist\fR(3)
+In addition, the following PAM items are exported as environment variables:
+\fIPAM_RHOST\fR,
+\fIPAM_RUSER\fR,
+\fIPAM_SERVICE\fR,
+\fIPAM_TTY\fR,
+\fIPAM_USER\fR
+and
+\fIPAM_TYPE\fR, which contains one of the module types:
+\fBaccount\fR,
+\fBauth\fR,
+\fBpassword\fR,
+\fBopen_session\fR
+and
+\fBclose_session\fR\&.
+.PP
+Commands called by pam_exec need to be aware of that the user can have control over the environment\&.
+.SH "OPTIONS"
+.PP
+.PP
+\fBdebug\fR
+.RS 4
+Print debug information\&.
+.RE
+.PP
+\fBexpose_authtok\fR
+.RS 4
+During authentication the calling command can read the password from
+\fBstdin\fR(3)\&. Only first
+\fIPAM_MAX_RESP_SIZE\fR
+bytes of a password are provided to the command\&.
+.RE
+.PP
+\fBlog=\fR\fB\fIfile\fR\fR
+.RS 4
+The output of the command is appended to
+file
+.RE
+.PP
+\fBtype=\fR\fB\fItype\fR\fR
+.RS 4
+Only run the command if the module type matches the given type\&.
+.RE
+.PP
+\fBstdout\fR
+.RS 4
+Per default the output of the executed command is written to
+/dev/null\&. With this option, the stdout output of the executed command is redirected to the calling application\&. It\*(Aqs in the responsibility of this application what happens with the output\&. The
+\fBlog\fR
+option is ignored\&.
+.RE
+.PP
+\fBquiet\fR
+.RS 4
+Per default pam_exec\&.so will echo the exit status of the external command if it fails\&. Specifying this option will suppress the message\&.
+.RE
+.PP
+\fBquiet_log\fR
+.RS 4
+Per default pam_exec\&.so will log the exit status of the external command if it fails\&. Specifying this option will suppress the log message\&.
+.RE
+.PP
+\fBseteuid\fR
+.RS 4
+Per default pam_exec\&.so will execute the external command with the real user ID of the calling process\&. Specifying this option means the command is run with the effective user ID\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+All module types (\fBauth\fR,
+\fBaccount\fR,
+\fBpassword\fR
+and
+\fBsession\fR) are provided\&.
+.SH "RETURN VALUES"
+.PP
+.PP
+PAM_SUCCESS
+.RS 4
+The external command was run successfully\&.
+.RE
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_CONV_ERR
+.RS 4
+The conversation method supplied by the application failed to obtain the username\&.
+.RE
+.PP
+PAM_INCOMPLETE
+.RS 4
+The conversation method supplied by the application returned PAM_CONV_AGAIN\&.
+.RE
+.PP
+PAM_SERVICE_ERR
+.RS 4
+No argument or a wrong number of arguments were given\&.
+.RE
+.PP
+PAM_SYSTEM_ERR
+.RS 4
+A system error occurred or the command to execute failed\&.
+.RE
+.PP
+PAM_IGNORE
+.RS 4
+\fBpam_setcred\fR
+was called, which does not execute the command\&. Or, the value given for the type= parameter did not match the module type\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Add the following line to
+/etc/pam\&.d/passwd
+to rebuild the NIS database after each local password change:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ password optional pam_exec\&.so seteuid /usr/bin/make \-C /var/yp
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+This will execute the command
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+make \-C /var/yp
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+with effective user ID\&.
+.SH "SEE ALSO"
+.PP
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_exec was written by Thorsten Kukuk <kukuk@thkukuk\&.de> and Josh Triplett <josh@joshtriplett\&.org>\&.
diff --git a/modules/pam_exec/pam_exec.8.xml b/modules/pam_exec/pam_exec.8.xml
new file mode 100644
index 0000000..7e89943
--- /dev/null
+++ b/modules/pam_exec/pam_exec.8.xml
@@ -0,0 +1,319 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_exec">
+
+ <refmeta>
+ <refentrytitle>pam_exec</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_exec-name">
+ <refname>pam_exec</refname>
+ <refpurpose>PAM module which calls an external command</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_exec-cmdsynopsis">
+ <command>pam_exec.so</command>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ expose_authtok
+ </arg>
+ <arg choice="opt">
+ seteuid
+ </arg>
+ <arg choice="opt">
+ quiet
+ </arg>
+ <arg choice="opt">
+ quiet_log
+ </arg>
+ <arg choice="opt">
+ stdout
+ </arg>
+ <arg choice="opt">
+ log=<replaceable>file</replaceable>
+ </arg>
+ <arg choice="opt">
+ type=<replaceable>type</replaceable>
+ </arg>
+ <arg choice="plain">
+ <replaceable>command</replaceable>
+ </arg>
+ <arg choice="opt">
+ <replaceable>...</replaceable>
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_exec-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ pam_exec is a PAM module that can be used to run
+ an external command.
+ </para>
+
+ <para>
+ The child's environment is set to the current PAM environment list, as
+ returned by
+ <citerefentry>
+ <refentrytitle>pam_getenvlist</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>
+ In addition, the following PAM items are
+ exported as environment variables: <emphasis>PAM_RHOST</emphasis>,
+ <emphasis>PAM_RUSER</emphasis>, <emphasis>PAM_SERVICE</emphasis>,
+ <emphasis>PAM_TTY</emphasis>, <emphasis>PAM_USER</emphasis> and
+ <emphasis>PAM_TYPE</emphasis>, which contains one of the module
+ types: <option>account</option>, <option>auth</option>,
+ <option>password</option>, <option>open_session</option> and
+ <option>close_session</option>.
+ </para>
+
+ <para>
+ Commands called by pam_exec need to be aware of that the user
+ can have control over the environment.
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="pam_exec-options">
+
+ <title>OPTIONS</title>
+ <para>
+ <variablelist>
+
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Print debug information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>expose_authtok</option>
+ </term>
+ <listitem>
+ <para>
+ During authentication the calling command can read
+ the password from <citerefentry>
+ <refentrytitle>stdin</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>. Only first <emphasis>PAM_MAX_RESP_SIZE</emphasis>
+ bytes of a password are provided to the command.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>log=<replaceable>file</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The output of the command is appended to
+ <filename>file</filename>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>type=<replaceable>type</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Only run the command if the module type matches the given type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>stdout</option>
+ </term>
+ <listitem>
+ <para>
+ Per default the output of the executed command is written to <filename>/dev/null</filename>. With this option, the stdout output of the executed command is redirected to the calling application. It's in the responsibility of this application what happens with the output. The <option>log</option> option is ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>quiet</option>
+ </term>
+ <listitem>
+ <para>
+ Per default pam_exec.so will echo the exit status of the
+ external command if it fails.
+ Specifying this option will suppress the message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>quiet_log</option>
+ </term>
+ <listitem>
+ <para>
+ Per default pam_exec.so will log the exit status of the
+ external command if it fails.
+ Specifying this option will suppress the log message.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>seteuid</option>
+ </term>
+ <listitem>
+ <para>
+ Per default pam_exec.so will execute the external command
+ with the real user ID of the calling process.
+ Specifying this option means the command is run
+ with the effective user ID.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_exec-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ All module types (<option>auth</option>, <option>account</option>,
+ <option>password</option> and <option>session</option>) are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_exec-return_values'>
+ <title>RETURN VALUES</title>
+ <para>
+ <variablelist>
+
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ The external command was run successfully.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory buffer error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_CONV_ERR</term>
+ <listitem>
+ <para>
+ The conversation method supplied by the application
+ failed to obtain the username.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_INCOMPLETE</term>
+ <listitem>
+ <para>
+ The conversation method supplied by the application
+ returned PAM_CONV_AGAIN.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ No argument or a wrong number of arguments were given.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SYSTEM_ERR</term>
+ <listitem>
+ <para>
+ A system error occurred or the command to execute failed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ <function>pam_setcred</function> was called, which
+ does not execute the command. Or, the value given for the type=
+ parameter did not match the module type.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_exec-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ Add the following line to <filename>/etc/pam.d/passwd</filename> to
+ rebuild the NIS database after each local password change:
+ <programlisting>
+ password optional pam_exec.so seteuid /usr/bin/make -C /var/yp
+ </programlisting>
+
+ This will execute the command
+ <programlisting>make -C /var/yp</programlisting>
+ with effective user ID.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_exec-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_exec-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_exec was written by Thorsten Kukuk &lt;kukuk@thkukuk.de&gt; and
+ Josh Triplett &lt;josh@joshtriplett.org&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_exec/pam_exec.c b/modules/pam_exec/pam_exec.c
new file mode 100644
index 0000000..05dec16
--- /dev/null
+++ b/modules/pam_exec/pam_exec.c
@@ -0,0 +1,522 @@
+/*
+ * Copyright (c) 2006, 2008 Thorsten Kukuk <kukuk@thkukuk.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include <time.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+#include <security/_pam_macros.h>
+#include "pam_inline.h"
+
+#define ENV_ITEM(n) { (n), #n }
+static struct {
+ int item;
+ const char *name;
+} env_items[] = {
+ ENV_ITEM(PAM_SERVICE),
+ ENV_ITEM(PAM_USER),
+ ENV_ITEM(PAM_TTY),
+ ENV_ITEM(PAM_RHOST),
+ ENV_ITEM(PAM_RUSER),
+};
+
+/* move_fd_to_non_stdio copies the given file descriptor to something other
+ * than stdin, stdout, or stderr. Assumes that the caller will close all
+ * unwanted fds after calling. */
+static int
+move_fd_to_non_stdio (pam_handle_t *pamh, int fd)
+{
+ while (fd < 3)
+ {
+ fd = dup(fd);
+ if (fd == -1)
+ {
+ int err = errno;
+ pam_syslog (pamh, LOG_ERR, "dup failed: %m");
+ _exit (err);
+ }
+ }
+ return fd;
+}
+
+static int
+call_exec (const char *pam_type, pam_handle_t *pamh,
+ int argc, const char **argv)
+{
+ int debug = 0;
+ int call_setuid = 0;
+ int quiet = 0;
+ int quiet_log = 0;
+ int expose_authtok = 0;
+ int use_stdout = 0;
+ int optargc;
+ const char *logfile = NULL;
+ char authtok[PAM_MAX_RESP_SIZE] = {};
+ pid_t pid;
+ int fds[2];
+ int stdout_fds[2];
+ FILE *stdout_file = NULL;
+ int retval;
+ const char *name;
+
+ if (argc < 1) {
+ pam_syslog (pamh, LOG_ERR,
+ "This module needs at least one argument");
+ return PAM_SERVICE_ERR;
+ }
+
+ for (optargc = 0; optargc < argc; optargc++)
+ {
+ const char *str;
+
+ if (argv[optargc][0] == '/') /* paths starts with / */
+ break;
+
+ if (strcasecmp (argv[optargc], "debug") == 0)
+ debug = 1;
+ else if (strcasecmp (argv[optargc], "stdout") == 0)
+ use_stdout = 1;
+ else if ((str = pam_str_skip_icase_prefix (argv[optargc], "log=")) != NULL)
+ logfile = str;
+ else if ((str = pam_str_skip_icase_prefix (argv[optargc], "type=")) != NULL)
+ {
+ if (strcmp (pam_type, str) != 0)
+ return PAM_IGNORE;
+ }
+ else if (strcasecmp (argv[optargc], "seteuid") == 0)
+ call_setuid = 1;
+ else if (strcasecmp (argv[optargc], "quiet") == 0)
+ quiet = 1;
+ else if (strcasecmp (argv[optargc], "quiet_log") == 0)
+ quiet_log = 1;
+ else if (strcasecmp (argv[optargc], "expose_authtok") == 0)
+ expose_authtok = 1;
+ else
+ break; /* Unknown option, assume program to execute. */
+ }
+
+ /* Request user name to be available. */
+
+ retval = pam_get_user(pamh, &name, NULL);
+ if (retval != PAM_SUCCESS)
+ {
+ if (retval == PAM_CONV_AGAIN)
+ retval = PAM_INCOMPLETE;
+ return retval;
+ }
+
+ if (expose_authtok == 1)
+ {
+ if (strcmp (pam_type, "auth") != 0)
+ {
+ pam_syslog (pamh, LOG_ERR,
+ "expose_authtok not supported for type %s", pam_type);
+ expose_authtok = 0;
+ }
+ else
+ {
+ const void *void_pass;
+
+ retval = pam_get_item (pamh, PAM_AUTHTOK, &void_pass);
+ if (retval != PAM_SUCCESS)
+ {
+ if (debug)
+ pam_syslog (pamh, LOG_DEBUG,
+ "pam_get_item (PAM_AUTHTOK) failed, return %d",
+ retval);
+ return retval;
+ }
+ else if (void_pass == NULL)
+ {
+ char *resp = NULL;
+
+ retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF,
+ &resp, _("Password: "));
+
+ if (retval != PAM_SUCCESS)
+ {
+ _pam_drop (resp);
+ if (retval == PAM_CONV_AGAIN)
+ retval = PAM_INCOMPLETE;
+ return retval;
+ }
+
+ if (resp)
+ {
+ pam_set_item (pamh, PAM_AUTHTOK, resp);
+ strncpy (authtok, resp, sizeof(authtok) - 1);
+ _pam_drop (resp);
+ }
+ }
+ else
+ strncpy (authtok, void_pass, sizeof(authtok) - 1);
+
+ if (pipe(fds) != 0)
+ {
+ pam_syslog (pamh, LOG_ERR, "Could not create pipe: %m");
+ return PAM_SYSTEM_ERR;
+ }
+ }
+ }
+
+ if (use_stdout)
+ {
+ if (pipe(stdout_fds) != 0)
+ {
+ pam_syslog (pamh, LOG_ERR, "Could not create pipe: %m");
+ return PAM_SYSTEM_ERR;
+ }
+ stdout_file = fdopen(stdout_fds[0], "r");
+ if (!stdout_file)
+ {
+ pam_syslog (pamh, LOG_ERR, "Could not fdopen pipe: %m");
+ return PAM_SYSTEM_ERR;
+ }
+ }
+
+ if (optargc >= argc) {
+ pam_syslog (pamh, LOG_ERR, "No path given as argument");
+ return PAM_SERVICE_ERR;
+ }
+
+ pid = fork();
+ if (pid == -1)
+ return PAM_SYSTEM_ERR;
+ if (pid > 0) /* parent */
+ {
+ int status = 0;
+ pid_t rc;
+
+ if (expose_authtok) /* send the password to the child */
+ {
+ if (debug)
+ pam_syslog (pamh, LOG_DEBUG, "send password to child");
+ if (write(fds[1], authtok, strlen(authtok)) == -1)
+ pam_syslog (pamh, LOG_ERR,
+ "sending password to child failed: %m");
+
+ close(fds[0]); /* close here to avoid possible SIGPIPE above */
+ close(fds[1]);
+ }
+
+ if (use_stdout)
+ {
+ char buf[4096];
+ close(stdout_fds[1]);
+ while (fgets(buf, sizeof(buf), stdout_file) != NULL)
+ {
+ size_t len;
+ len = strlen(buf);
+ if (buf[len-1] == '\n')
+ buf[len-1] = '\0';
+ pam_info(pamh, "%s", buf);
+ }
+ fclose(stdout_file);
+ }
+
+ while ((rc = waitpid (pid, &status, 0)) == -1 &&
+ errno == EINTR);
+ if (rc == (pid_t)-1)
+ {
+ pam_syslog (pamh, LOG_ERR, "waitpid returns with -1: %m");
+ return PAM_SYSTEM_ERR;
+ }
+ else if (status != 0)
+ {
+ if (WIFEXITED(status))
+ {
+ if (!quiet_log)
+ pam_syslog (pamh, LOG_ERR, "%s failed: exit code %d",
+ argv[optargc], WEXITSTATUS(status));
+ if (!quiet)
+ pam_error (pamh, _("%s failed: exit code %d"),
+ argv[optargc], WEXITSTATUS(status));
+ }
+ else if (WIFSIGNALED(status))
+ {
+ if (!quiet_log)
+ pam_syslog (pamh, LOG_ERR, "%s failed: caught signal %d%s",
+ argv[optargc], WTERMSIG(status),
+ WCOREDUMP(status) ? " (core dumped)" : "");
+ if (!quiet)
+ pam_error (pamh, _("%s failed: caught signal %d%s"),
+ argv[optargc], WTERMSIG(status),
+ WCOREDUMP(status) ? " (core dumped)" : "");
+ }
+ else
+ {
+ if (!quiet_log)
+ pam_syslog (pamh, LOG_ERR, "%s failed: unknown status 0x%x",
+ argv[optargc], status);
+ if (!quiet)
+ pam_error (pamh, _("%s failed: unknown status 0x%x"),
+ argv[optargc], status);
+ }
+ return PAM_SYSTEM_ERR;
+ }
+ return PAM_SUCCESS;
+ }
+ else /* child */
+ {
+ char **arggv;
+ int i;
+ char **envlist, **tmp;
+ int envlen, nitems;
+ char *envstr;
+ enum pam_modutil_redirect_fd redirect_stdin =
+ expose_authtok ? PAM_MODUTIL_IGNORE_FD : PAM_MODUTIL_PIPE_FD;
+ enum pam_modutil_redirect_fd redirect_stdout =
+ (use_stdout || logfile) ? PAM_MODUTIL_IGNORE_FD : PAM_MODUTIL_NULL_FD;
+
+ /* First, move all the pipes off of stdin, stdout, and stderr, to ensure
+ * that calls to dup2 won't close them. */
+
+ if (expose_authtok)
+ {
+ fds[0] = move_fd_to_non_stdio(pamh, fds[0]);
+ close(fds[1]);
+ }
+
+ if (use_stdout)
+ {
+ stdout_fds[1] = move_fd_to_non_stdio(pamh, stdout_fds[1]);
+ close(stdout_fds[0]);
+ }
+
+ /* Set up stdin. */
+
+ if (expose_authtok)
+ {
+ /* reopen stdin as pipe */
+ if (dup2(fds[0], STDIN_FILENO) == -1)
+ {
+ int err = errno;
+ pam_syslog (pamh, LOG_ERR, "dup2 of STDIN failed: %m");
+ _exit (err);
+ }
+ }
+
+ /* Set up stdout. */
+
+ if (use_stdout)
+ {
+ if (dup2(stdout_fds[1], STDOUT_FILENO) == -1)
+ {
+ int err = errno;
+ pam_syslog (pamh, LOG_ERR, "dup2 to stdout failed: %m");
+ _exit (err);
+ }
+ }
+ else if (logfile)
+ {
+ time_t tm = time (NULL);
+ char *buffer = NULL;
+
+ close (STDOUT_FILENO);
+ if ((i = open (logfile, O_CREAT|O_APPEND|O_WRONLY,
+ S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == -1)
+ {
+ int err = errno;
+ pam_syslog (pamh, LOG_ERR, "open of %s failed: %m",
+ logfile);
+ _exit (err);
+ }
+ if (i != STDOUT_FILENO)
+ {
+ if (dup2 (i, STDOUT_FILENO) == -1)
+ {
+ int err = errno;
+ pam_syslog (pamh, LOG_ERR, "dup2 failed: %m");
+ _exit (err);
+ }
+ close (i);
+ }
+ if (asprintf (&buffer, "*** %s", ctime (&tm)) > 0)
+ {
+ pam_modutil_write (STDOUT_FILENO, buffer, strlen (buffer));
+ free (buffer);
+ }
+ }
+
+ if ((use_stdout || logfile) &&
+ dup2 (STDOUT_FILENO, STDERR_FILENO) == -1)
+ {
+ int err = errno;
+ pam_syslog (pamh, LOG_ERR, "dup2 failed: %m");
+ _exit (err);
+ }
+
+ if (pam_modutil_sanitize_helper_fds(pamh, redirect_stdin,
+ redirect_stdout, redirect_stdout) < 0)
+ _exit(1);
+
+ if (call_setuid)
+ if (setuid (geteuid ()) == -1)
+ {
+ int err = errno;
+ pam_syslog (pamh, LOG_ERR, "setuid(%lu) failed: %m",
+ (unsigned long) geteuid ());
+ _exit (err);
+ }
+
+ if (setsid () == -1)
+ {
+ int err = errno;
+ pam_syslog (pamh, LOG_ERR, "setsid failed: %m");
+ _exit (err);
+ }
+
+ arggv = calloc (argc + 4, sizeof (char *));
+ if (arggv == NULL)
+ _exit (ENOMEM);
+
+ for (i = 0; i < (argc - optargc); i++)
+ arggv[i] = strdup(argv[i+optargc]);
+ arggv[i] = NULL;
+
+ /*
+ * Set up the child's environment list. It consists of the PAM
+ * environment, plus a few hand-picked PAM items.
+ */
+ envlist = pam_getenvlist(pamh);
+ for (envlen = 0; envlist[envlen] != NULL; ++envlen)
+ /* nothing */ ;
+ nitems = PAM_ARRAY_SIZE(env_items);
+ /* + 2 because of PAM_TYPE and NULL entry */
+ tmp = realloc(envlist, (envlen + nitems + 2) * sizeof(*envlist));
+ if (tmp == NULL)
+ {
+ free(envlist);
+ pam_syslog (pamh, LOG_CRIT, "realloc environment failed: %m");
+ _exit (ENOMEM);
+ }
+ envlist = tmp;
+ for (i = 0; i < nitems; ++i)
+ {
+ const void *item;
+
+ if (pam_get_item(pamh, env_items[i].item, &item) != PAM_SUCCESS || item == NULL)
+ continue;
+ if (asprintf(&envstr, "%s=%s", env_items[i].name, (const char *)item) < 0)
+ {
+ free(envlist);
+ pam_syslog (pamh, LOG_CRIT, "prepare environment failed: %m");
+ _exit (ENOMEM);
+ }
+ envlist[envlen++] = envstr;
+ envlist[envlen] = NULL;
+ }
+
+ if (asprintf(&envstr, "PAM_TYPE=%s", pam_type) < 0)
+ {
+ free(envlist);
+ pam_syslog (pamh, LOG_CRIT, "prepare environment failed: %m");
+ _exit (ENOMEM);
+ }
+ envlist[envlen++] = envstr;
+ envlist[envlen] = NULL;
+
+ if (debug)
+ pam_syslog (pamh, LOG_DEBUG, "Calling %s ...", arggv[0]);
+
+ execve (arggv[0], arggv, envlist);
+ i = errno;
+ pam_syslog (pamh, LOG_ERR, "execve(%s,...) failed: %m", arggv[0]);
+ free(envlist);
+ _exit (i);
+ }
+ return PAM_SYSTEM_ERR; /* will never be reached. */
+}
+
+int
+pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ return call_exec ("auth", pamh, argc, argv);
+}
+
+int
+pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_IGNORE;
+}
+
+/* password updating functions */
+
+int
+pam_sm_chauthtok(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ if (flags & PAM_PRELIM_CHECK)
+ return PAM_SUCCESS;
+ return call_exec ("password", pamh, argc, argv);
+}
+
+int
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ return call_exec ("account", pamh, argc, argv);
+}
+
+int
+pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ return call_exec ("open_session", pamh, argc, argv);
+}
+
+int
+pam_sm_close_session(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ return call_exec ("close_session", pamh, argc, argv);
+}
diff --git a/modules/pam_exec/tst-pam_exec b/modules/pam_exec/tst-pam_exec
new file mode 100755
index 0000000..a0b0039
--- /dev/null
+++ b/modules/pam_exec/tst-pam_exec
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_exec.so
diff --git a/modules/pam_faildelay/Makefile.am b/modules/pam_faildelay/Makefile.am
new file mode 100644
index 0000000..3a49a11
--- /dev/null
+++ b/modules/pam_faildelay/Makefile.am
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_faildelay.8
+endif
+XMLS = README.xml pam_faildelay.8.xml
+dist_check_SCRIPTS = tst-pam_faildelay
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_faildelay.la
+pam_faildelay_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+check_PROGRAMS = tst-pam_faildelay-retval
+tst_pam_faildelay_retval_LDADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_faildelay/Makefile.in b/modules/pam_faildelay/Makefile.in
new file mode 100644
index 0000000..f06712a
--- /dev/null
+++ b/modules/pam_faildelay/Makefile.in
@@ -0,0 +1,1181 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+check_PROGRAMS = tst-pam_faildelay-retval$(EXEEXT)
+subdir = modules/pam_faildelay
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_faildelay_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_faildelay_la_SOURCES = pam_faildelay.c
+pam_faildelay_la_OBJECTS = pam_faildelay.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+tst_pam_faildelay_retval_SOURCES = tst-pam_faildelay-retval.c
+tst_pam_faildelay_retval_OBJECTS = tst-pam_faildelay-retval.$(OBJEXT)
+tst_pam_faildelay_retval_DEPENDENCIES = \
+ $(top_builddir)/libpam/libpam.la
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_faildelay.Plo \
+ ./$(DEPDIR)/tst-pam_faildelay-retval.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_faildelay.c tst-pam_faildelay-retval.c
+DIST_SOURCES = pam_faildelay.c tst-pam_faildelay-retval.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_faildelay.8
+XMLS = README.xml pam_faildelay.8.xml
+dist_check_SCRIPTS = tst-pam_faildelay
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_faildelay.la
+pam_faildelay_la_LIBADD = $(top_builddir)/libpam/libpam.la
+tst_pam_faildelay_retval_LDADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_faildelay/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_faildelay/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_faildelay.la: $(pam_faildelay_la_OBJECTS) $(pam_faildelay_la_DEPENDENCIES) $(EXTRA_pam_faildelay_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_faildelay_la_OBJECTS) $(pam_faildelay_la_LIBADD) $(LIBS)
+
+tst-pam_faildelay-retval$(EXEEXT): $(tst_pam_faildelay_retval_OBJECTS) $(tst_pam_faildelay_retval_DEPENDENCIES) $(EXTRA_tst_pam_faildelay_retval_DEPENDENCIES)
+ @rm -f tst-pam_faildelay-retval$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tst_pam_faildelay_retval_OBJECTS) $(tst_pam_faildelay_retval_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_faildelay.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-pam_faildelay-retval.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_faildelay.log: tst-pam_faildelay
+ @p='tst-pam_faildelay'; \
+ b='tst-pam_faildelay'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+tst-pam_faildelay-retval.log: tst-pam_faildelay-retval$(EXEEXT)
+ @p='tst-pam_faildelay-retval$(EXEEXT)'; \
+ b='tst-pam_faildelay-retval'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) \
+ $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_faildelay.Plo
+ -rm -f ./$(DEPDIR)/tst-pam_faildelay-retval.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_faildelay.Plo
+ -rm -f ./$(DEPDIR)/tst-pam_faildelay-retval.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_faildelay/README b/modules/pam_faildelay/README
new file mode 100644
index 0000000..a06d7e3
--- /dev/null
+++ b/modules/pam_faildelay/README
@@ -0,0 +1,33 @@
+pam_faildelay — Change the delay on failure per-application
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+pam_faildelay is a PAM module that can be used to set the delay on failure
+per-application.
+
+If no delay is given, pam_faildelay will use the value of FAIL_DELAY from /etc/
+login.defs.
+
+OPTIONS
+
+debug
+
+ Turns on debugging messages sent to syslog.
+
+delay=N
+
+ Set the delay on failure to N microseconds.
+
+EXAMPLES
+
+The following example will set the delay on failure to 10 seconds:
+
+auth optional pam_faildelay.so delay=10000000
+
+
+AUTHOR
+
+pam_faildelay was written by Darren Tucker <dtucker@zip.com.au>.
+
diff --git a/modules/pam_faildelay/README.xml b/modules/pam_faildelay/README.xml
new file mode 100644
index 0000000..64d4acc
--- /dev/null
+++ b/modules/pam_faildelay/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+"http://www.docbook.org/xml/4.4/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_faildelay.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_faildelay.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_faildelay-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_faildelay.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faildelay-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_faildelay.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faildelay-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_faildelay.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faildelay-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_faildelay.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faildelay-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_faildelay/pam_faildelay.8 b/modules/pam_faildelay/pam_faildelay.8
new file mode 100644
index 0000000..5a29b6e
--- /dev/null
+++ b/modules/pam_faildelay/pam_faildelay.8
@@ -0,0 +1,93 @@
+'\" t
+.\" Title: pam_faildelay
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_FAILDELAY" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_faildelay \- Change the delay on failure per\-application
+.SH "SYNOPSIS"
+.HP \w'\fBpam_faildelay\&.so\fR\ 'u
+\fBpam_faildelay\&.so\fR [debug] [delay=\fImicroseconds\fR]
+.SH "DESCRIPTION"
+.PP
+pam_faildelay is a PAM module that can be used to set the delay on failure per\-application\&.
+.PP
+If no
+\fBdelay\fR
+is given, pam_faildelay will use the value of FAIL_DELAY from
+/etc/login\&.defs\&.
+.SH "OPTIONS"
+.PP
+\fBdebug\fR
+.RS 4
+Turns on debugging messages sent to syslog\&.
+.RE
+.PP
+\fBdelay=\fR\fB\fIN\fR\fR
+.RS 4
+Set the delay on failure to N microseconds\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+Only the
+\fBauth\fR
+module type is provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_IGNORE
+.RS 4
+Delay was successful adjusted\&.
+.RE
+.PP
+PAM_SYSTEM_ERR
+.RS 4
+The specified delay was not valid\&.
+.RE
+.SH "EXAMPLES"
+.PP
+The following example will set the delay on failure to 10 seconds:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+auth optional pam_faildelay\&.so delay=10000000
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.PP
+\fBpam_fail_delay\fR(3),
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_faildelay was written by Darren Tucker <dtucker@zip\&.com\&.au>\&.
diff --git a/modules/pam_faildelay/pam_faildelay.8.xml b/modules/pam_faildelay/pam_faildelay.8.xml
new file mode 100644
index 0000000..5710720
--- /dev/null
+++ b/modules/pam_faildelay/pam_faildelay.8.xml
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+ "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
+
+<refentry id="pam_faildelay">
+
+ <refmeta>
+ <refentrytitle>pam_faildelay</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_faildelay-name">
+ <refname>pam_faildelay</refname>
+ <refpurpose>Change the delay on failure per-application</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_faildelay-cmdsynopsis">
+ <command>pam_faildelay.so</command>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ delay=<replaceable>microseconds</replaceable>
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_faildelay-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ pam_faildelay is a PAM module that can be used to set
+ the delay on failure per-application.
+ </para>
+ <para>
+ If no <option>delay</option> is given, pam_faildelay will
+ use the value of FAIL_DELAY from <filename>/etc/login.defs</filename>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_faildelay-options">
+
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Turns on debugging messages sent to syslog.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>delay=<replaceable>N</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Set the delay on failure to N microseconds.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_faildelay-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ Only the <option>auth</option> module type is provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_faildelay-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ Delay was successful adjusted.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SYSTEM_ERR</term>
+ <listitem>
+ <para>
+ The specified delay was not valid.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_faildelay-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ The following example will set the delay on failure to
+ 10 seconds:
+ <programlisting>
+auth optional pam_faildelay.so delay=10000000
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_faildelay-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam_fail_delay</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_faildelay-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_faildelay was written by Darren Tucker &lt;dtucker@zip.com.au&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_faildelay/pam_faildelay.c b/modules/pam_faildelay/pam_faildelay.c
new file mode 100644
index 0000000..02c5faf
--- /dev/null
+++ b/modules/pam_faildelay/pam_faildelay.c
@@ -0,0 +1,138 @@
+/*
+ * pam_faildelay module
+ *
+ * Allows an admin to set the delay on failure per-application.
+ * Provides "auth" interface only.
+ *
+ * Use by putting something like this in the relevant pam config:
+ * auth required pam_faildelay.so delay=[microseconds]
+ *
+ * eg:
+ * auth required pam_faildelay.so delay=10000000
+ * will set the delay on failure to 10 seconds.
+ *
+ * If no delay option was given, pam_faildelay.so will use the
+ * FAIL_DELAY value of /etc/login.defs.
+ *
+ * Based on pam_rootok and parts of pam_unix both by Andrew Morgan
+ * <morgan@linux.kernel.org>
+ *
+ * Copyright (c) 2006 Thorsten Kukuk <kukuk@thkukuk.de>
+ * - Rewrite to use extended PAM functions
+ * - Add /etc/login.defs support
+ *
+ * Portions Copyright (c) 2005 Darren Tucker <dtucker at zip com au>.
+ *
+ * Redistribution and use in source and binary forms of, with
+ * or without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * 1. Redistributions of source code must retain any existing copyright
+ * notice, and this entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ *
+ * 2. Redistributions in binary form must reproduce all prior and current
+ * copyright notices, this list of conditions, and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * 3. The name of any author may not be used to endorse or promote
+ * products derived from this software without their specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of the
+ * GNU General Public License, in which case the provisions of the GNU
+ * GPL are required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential conflict between the GNU GPL and the
+ * restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <limits.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_ext.h>
+#include <security/pam_modutil.h>
+
+#define LOGIN_DEFS "/etc/login.defs"
+
+/* --- authentication management functions (only) --- */
+
+int pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ int i, debug_flag = 0;
+ long int delay = -1;
+
+ /* step through arguments */
+ for (i = 0; i < argc; i++) {
+ if (sscanf(argv[i], "delay=%ld", &delay) == 1) {
+ /* sscanf did already everything necessary */
+ } else if (strcmp (argv[i], "debug") == 0)
+ debug_flag = 1;
+ else
+ pam_syslog (pamh, LOG_ERR, "unknown option; %s", argv[i]);
+ }
+
+ if (delay == -1)
+ {
+ char *endptr;
+ char *val = pam_modutil_search_key (pamh, LOGIN_DEFS, "FAIL_DELAY");
+ const char *val_orig = val;
+
+ if (val == NULL)
+ return PAM_IGNORE;
+
+ errno = 0;
+ delay = strtol (val, &endptr, 10) & 0777;
+ if (((delay == 0) && (val_orig == endptr)) ||
+ ((delay == LONG_MIN || delay == LONG_MAX) && (errno == ERANGE)))
+ {
+ pam_syslog (pamh, LOG_ERR, "FAIL_DELAY=%s in %s not valid",
+ val, LOGIN_DEFS);
+ free (val);
+ return PAM_IGNORE;
+ }
+
+ free (val);
+ /* delay is in seconds, convert to microseconds. */
+ delay *= 1000000;
+ }
+
+ if (debug_flag)
+ pam_syslog (pamh, LOG_DEBUG, "setting fail delay to %ld", delay);
+
+ i = pam_fail_delay(pamh, delay);
+ if (i == PAM_SUCCESS)
+ return PAM_IGNORE;
+ else
+ return i;
+}
+
+int pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_IGNORE;
+}
+
+/* end of module definition */
diff --git a/modules/pam_faildelay/tst-pam_faildelay b/modules/pam_faildelay/tst-pam_faildelay
new file mode 100755
index 0000000..87f7fd4
--- /dev/null
+++ b/modules/pam_faildelay/tst-pam_faildelay
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_faildelay.so
diff --git a/modules/pam_faildelay/tst-pam_faildelay-retval.c b/modules/pam_faildelay/tst-pam_faildelay-retval.c
new file mode 100644
index 0000000..cbd8f2a
--- /dev/null
+++ b/modules/pam_faildelay/tst-pam_faildelay-retval.c
@@ -0,0 +1,88 @@
+/*
+ * Check pam_faildelay return values.
+ *
+ * Copyright (c) 2020 Dmitry V. Levin <ldv@altlinux.org>
+ */
+
+#include "test_assert.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <security/pam_appl.h>
+
+#define MODULE_NAME "pam_faildelay"
+#define TEST_NAME "tst-" MODULE_NAME "-retval"
+
+static const char service_file[] = TEST_NAME ".service";
+static const char user_name[] = "";
+static struct pam_conv conv;
+
+int
+main(void)
+{
+ pam_handle_t *pamh = NULL;
+ FILE *fp;
+ char cwd[PATH_MAX];
+
+ ASSERT_NE(NULL, getcwd(cwd, sizeof(cwd)));
+
+ /* PAM_IGNORE -> PAM_PERM_DENIED */
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so delay=1\n"
+ "account required %s/.libs/%s.so delay=1\n"
+ "password required %s/.libs/%s.so delay=1\n"
+ "session required %s/.libs/%s.so delay=1\n",
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, user_name, &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_PERM_DENIED, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ /* PAM_IGNORE -> PAM_SUCCESS */
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so delay=1\n"
+ "auth required %s/../pam_permit/.libs/pam_permit.so\n"
+ "account required %s/.libs/%s.so delay=1\n"
+ "account required %s/../pam_permit/.libs/pam_permit.so\n"
+ "password required %s/.libs/%s.so delay=1\n"
+ "password required %s/../pam_permit/.libs/pam_permit.so\n"
+ "session required %s/.libs/%s.so delay=1\n"
+ "session required %s/../pam_permit/.libs/pam_permit.so\n",
+ cwd, MODULE_NAME, cwd,
+ cwd, MODULE_NAME, cwd,
+ cwd, MODULE_NAME, cwd,
+ cwd, MODULE_NAME, cwd));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, user_name, &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ ASSERT_EQ(0, unlink(service_file));
+
+ return 0;
+}
diff --git a/modules/pam_faillock/Makefile.am b/modules/pam_faillock/Makefile.am
new file mode 100644
index 0000000..44a4966
--- /dev/null
+++ b/modules/pam_faillock/Makefile.am
@@ -0,0 +1,50 @@
+#
+# Copyright (c) 2005, 2006, 2007, 2009 Thorsten Kukuk <kukuk@thkukuk.de>
+# Copyright (c) 2008, 2018, 2020 Red Hat, Inc.
+# Copyright (c) 2010 Tomas Mraz <tmraz@redhat.com>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_faillock.8 faillock.8 faillock.conf.5
+endif
+XMLS = README.xml pam_faillock.8.xml faillock.8.xml faillock.conf.5.xml
+
+dist_check_SCRIPTS = tst-pam_faillock
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+noinst_HEADERS = faillock.h
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+faillock_CFLAGS = $(AM_CFLAGS) @EXE_CFLAGS@
+
+pam_faillock_la_LDFLAGS = -no-undefined -avoid-version -module
+pam_faillock_la_LIBADD = $(top_builddir)/libpam/libpam.la $(LIBAUDIT)
+if HAVE_VERSIONING
+ pam_faillock_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+faillock_LDFLAGS = @EXE_LDFLAGS@
+faillock_LDADD = $(top_builddir)/libpam/libpam.la $(LIBAUDIT)
+
+dist_secureconf_DATA = faillock.conf
+
+securelib_LTLIBRARIES = pam_faillock.la
+sbin_PROGRAMS = faillock
+
+pam_faillock_la_SOURCES = pam_faillock.c faillock.c
+faillock_SOURCES = main.c faillock.c
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_faillock/Makefile.in b/modules/pam_faillock/Makefile.in
new file mode 100644
index 0000000..9070f17
--- /dev/null
+++ b/modules/pam_faillock/Makefile.in
@@ -0,0 +1,1344 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2007, 2009 Thorsten Kukuk <kukuk@thkukuk.de>
+# Copyright (c) 2008, 2018, 2020 Red Hat, Inc.
+# Copyright (c) 2010 Tomas Mraz <tmraz@redhat.com>
+#
+
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+sbin_PROGRAMS = faillock$(EXEEXT)
+subdir = modules/pam_faillock
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(dist_secureconf_DATA) \
+ $(noinst_HEADERS) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(securelibdir)" \
+ "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" \
+ "$(DESTDIR)$(secureconfdir)"
+PROGRAMS = $(sbin_PROGRAMS)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+pam_faillock_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la \
+ $(am__DEPENDENCIES_1)
+am_pam_faillock_la_OBJECTS = pam_faillock.lo faillock.lo
+pam_faillock_la_OBJECTS = $(am_pam_faillock_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+pam_faillock_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(pam_faillock_la_LDFLAGS) $(LDFLAGS) \
+ -o $@
+am_faillock_OBJECTS = faillock-main.$(OBJEXT) \
+ faillock-faillock.$(OBJEXT)
+faillock_OBJECTS = $(am_faillock_OBJECTS)
+faillock_DEPENDENCIES = $(top_builddir)/libpam/libpam.la \
+ $(am__DEPENDENCIES_1)
+faillock_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(faillock_CFLAGS) \
+ $(CFLAGS) $(faillock_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/faillock-faillock.Po \
+ ./$(DEPDIR)/faillock-main.Po ./$(DEPDIR)/faillock.Plo \
+ ./$(DEPDIR)/pam_faillock.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(pam_faillock_la_SOURCES) $(faillock_SOURCES)
+DIST_SOURCES = $(pam_faillock_la_SOURCES) $(faillock_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man5dir = $(mandir)/man5
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA) $(dist_secureconf_DATA)
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_faillock.8 faillock.8 faillock.conf.5
+XMLS = README.xml pam_faillock.8.xml faillock.8.xml faillock.conf.5.xml
+dist_check_SCRIPTS = tst-pam_faillock
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+noinst_HEADERS = faillock.h
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+faillock_CFLAGS = $(AM_CFLAGS) @EXE_CFLAGS@
+pam_faillock_la_LDFLAGS = -no-undefined -avoid-version -module \
+ $(am__append_1)
+pam_faillock_la_LIBADD = $(top_builddir)/libpam/libpam.la $(LIBAUDIT)
+faillock_LDFLAGS = @EXE_LDFLAGS@
+faillock_LDADD = $(top_builddir)/libpam/libpam.la $(LIBAUDIT)
+dist_secureconf_DATA = faillock.conf
+securelib_LTLIBRARIES = pam_faillock.la
+pam_faillock_la_SOURCES = pam_faillock.c faillock.c
+faillock_SOURCES = main.c faillock.c
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_faillock/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_faillock/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(sbindir)" && rm -f $$files
+
+clean-sbinPROGRAMS:
+ @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_faillock.la: $(pam_faillock_la_OBJECTS) $(pam_faillock_la_DEPENDENCIES) $(EXTRA_pam_faillock_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(pam_faillock_la_LINK) -rpath $(securelibdir) $(pam_faillock_la_OBJECTS) $(pam_faillock_la_LIBADD) $(LIBS)
+
+faillock$(EXEEXT): $(faillock_OBJECTS) $(faillock_DEPENDENCIES) $(EXTRA_faillock_DEPENDENCIES)
+ @rm -f faillock$(EXEEXT)
+ $(AM_V_CCLD)$(faillock_LINK) $(faillock_OBJECTS) $(faillock_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/faillock-faillock.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/faillock-main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/faillock.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_faillock.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+faillock-main.o: main.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(faillock_CFLAGS) $(CFLAGS) -MT faillock-main.o -MD -MP -MF $(DEPDIR)/faillock-main.Tpo -c -o faillock-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/faillock-main.Tpo $(DEPDIR)/faillock-main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='faillock-main.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(faillock_CFLAGS) $(CFLAGS) -c -o faillock-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
+
+faillock-main.obj: main.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(faillock_CFLAGS) $(CFLAGS) -MT faillock-main.obj -MD -MP -MF $(DEPDIR)/faillock-main.Tpo -c -o faillock-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/faillock-main.Tpo $(DEPDIR)/faillock-main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='main.c' object='faillock-main.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(faillock_CFLAGS) $(CFLAGS) -c -o faillock-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
+
+faillock-faillock.o: faillock.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(faillock_CFLAGS) $(CFLAGS) -MT faillock-faillock.o -MD -MP -MF $(DEPDIR)/faillock-faillock.Tpo -c -o faillock-faillock.o `test -f 'faillock.c' || echo '$(srcdir)/'`faillock.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/faillock-faillock.Tpo $(DEPDIR)/faillock-faillock.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='faillock.c' object='faillock-faillock.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(faillock_CFLAGS) $(CFLAGS) -c -o faillock-faillock.o `test -f 'faillock.c' || echo '$(srcdir)/'`faillock.c
+
+faillock-faillock.obj: faillock.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(faillock_CFLAGS) $(CFLAGS) -MT faillock-faillock.obj -MD -MP -MF $(DEPDIR)/faillock-faillock.Tpo -c -o faillock-faillock.obj `if test -f 'faillock.c'; then $(CYGPATH_W) 'faillock.c'; else $(CYGPATH_W) '$(srcdir)/faillock.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/faillock-faillock.Tpo $(DEPDIR)/faillock-faillock.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='faillock.c' object='faillock-faillock.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(faillock_CFLAGS) $(CFLAGS) -c -o faillock-faillock.obj `if test -f 'faillock.c'; then $(CYGPATH_W) 'faillock.c'; else $(CYGPATH_W) '$(srcdir)/faillock.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man5: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man5dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.5[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man5:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man5dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.5[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir)
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+install-dist_secureconfDATA: $(dist_secureconf_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_secureconf_DATA)'; test -n "$(secureconfdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(secureconfdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(secureconfdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(secureconfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(secureconfdir)" || exit $$?; \
+ done
+
+uninstall-dist_secureconfDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_secureconf_DATA)'; test -n "$(secureconfdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(secureconfdir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_faillock.log: tst-pam_faillock
+ @p='tst-pam_faillock'; \
+ b='tst-pam_faillock'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(MANS) $(DATA) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(secureconfdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \
+ clean-securelibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/faillock-faillock.Po
+ -rm -f ./$(DEPDIR)/faillock-main.Po
+ -rm -f ./$(DEPDIR)/faillock.Plo
+ -rm -f ./$(DEPDIR)/pam_faillock.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-dist_secureconfDATA install-man \
+ install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-sbinPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man5 install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/faillock-faillock.Po
+ -rm -f ./$(DEPDIR)/faillock-main.Po
+ -rm -f ./$(DEPDIR)/faillock.Plo
+ -rm -f ./$(DEPDIR)/pam_faillock.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-dist_secureconfDATA uninstall-man \
+ uninstall-sbinPROGRAMS uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man5 uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool clean-sbinPROGRAMS \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dist_secureconfDATA install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-man5 install-man8 install-pdf install-pdf-am \
+ install-ps install-ps-am install-sbinPROGRAMS \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am \
+ uninstall-dist_secureconfDATA uninstall-man uninstall-man5 \
+ uninstall-man8 uninstall-sbinPROGRAMS \
+ uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_faillock/README b/modules/pam_faillock/README
new file mode 100644
index 0000000..3b63c6b
--- /dev/null
+++ b/modules/pam_faillock/README
@@ -0,0 +1,140 @@
+pam_faillock — Module counting authentication failures during a specified
+interval
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+This module maintains a list of failed authentication attempts per user during
+a specified interval and locks the account in case there were more than deny
+consecutive failed authentications.
+
+Normally, failed attempts to authenticate root will not cause the root account
+to become blocked, to prevent denial-of-service: if your users aren't given
+shell accounts and root may only login via su or at the machine console (not
+telnet/rsh, etc), this is safe.
+
+OPTIONS
+
+{preauth|authfail|authsucc}
+
+ This argument must be set accordingly to the position of this module
+ instance in the PAM stack.
+
+ The preauth argument must be used when the module is called before the
+ modules which ask for the user credentials such as the password. The module
+ just examines whether the user should be blocked from accessing the service
+ in case there were anomalous number of failed consecutive authentication
+ attempts recently. This call is optional if authsucc is used.
+
+ The authfail argument must be used when the module is called after the
+ modules which determine the authentication outcome, failed. Unless the user
+ is already blocked due to previous authentication failures, the module will
+ record the failure into the appropriate user tally file.
+
+ The authsucc argument must be used when the module is called after the
+ modules which determine the authentication outcome, succeeded. Unless the
+ user is already blocked due to previous authentication failures, the module
+ will then clear the record of the failures in the respective user tally
+ file. Otherwise it will return authentication error. If this call is not
+ done, the pam_faillock will not distinguish between consecutive and
+ non-consecutive failed authentication attempts. The preauth call must be
+ used in such case. Due to complications in the way the PAM stack can be
+ configured it is also possible to call pam_faillock as an account module.
+ In such configuration the module must be also called in the preauth stage.
+
+conf=/path/to/config-file
+
+ Use another configuration file instead of the default /etc/security/
+ faillock.conf.
+
+The options for configuring the module behavior are described in the
+faillock.conf(5) manual page. The options specified on the module command line
+override the values from the configuration file.
+
+NOTES
+
+Configuring options on the module command line is not recommend. The /etc/
+security/faillock.conf should be used instead.
+
+The setup of pam_faillock in the PAM stack is different from the pam_tally2
+module setup.
+
+Individual files with the failure records are created as owned by the user.
+This allows pam_faillock.so module to work correctly when it is called from a
+screensaver.
+
+Note that using the module in preauth without the silent option specified in /
+etc/security/faillock.conf or with requisite control field leaks an information
+about existence or non-existence of a user account in the system because the
+failures are not recorded for the unknown users. The message about the user
+account being locked is never displayed for non-existing user accounts allowing
+the adversary to infer that a particular account is not existing on a system.
+
+EXAMPLES
+
+Here are two possible configuration examples for /etc/pam.d/login. They make
+pam_faillock to lock the account after 4 consecutive failed logins during the
+default interval of 15 minutes. Root account will be locked as well. The
+accounts will be automatically unlocked after 20 minutes.
+
+In the first example the module is called only in the auth phase and the module
+does not print any information about the account being blocked by pam_faillock.
+The preauth call can be added to tell users that their logins are blocked by
+the module and also to abort the authentication without even asking for
+password in such case.
+
+/etc/security/faillock.conf file example:
+
+deny=4
+unlock_time=1200
+silent
+
+
+/etc/pam.d/config file example:
+
+auth required pam_securetty.so
+auth required pam_env.so
+auth required pam_nologin.so
+# optionally call: auth requisite pam_faillock.so preauth
+# to display the message about account being locked
+auth [success=1 default=bad] pam_unix.so
+auth [default=die] pam_faillock.so authfail
+auth sufficient pam_faillock.so authsucc
+auth required pam_deny.so
+account required pam_unix.so
+password required pam_unix.so shadow
+session required pam_selinux.so close
+session required pam_loginuid.so
+session required pam_unix.so
+session required pam_selinux.so open
+
+
+In the second example the module is called both in the auth and account phases
+and the module informs the authenticating user when the account is locked if
+silent option is not specified in the faillock.conf.
+
+auth required pam_securetty.so
+auth required pam_env.so
+auth required pam_nologin.so
+auth required pam_faillock.so preauth
+# optionally use requisite above if you do not want to prompt for the password
+# on locked accounts
+auth sufficient pam_unix.so
+auth [default=die] pam_faillock.so authfail
+auth required pam_deny.so
+account required pam_faillock.so
+# if you drop the above call to pam_faillock.so the lock will be done also
+# on non-consecutive authentication failures
+account required pam_unix.so
+password required pam_unix.so shadow
+session required pam_selinux.so close
+session required pam_loginuid.so
+session required pam_unix.so
+session required pam_selinux.so open
+
+
+AUTHOR
+
+pam_faillock was written by Tomas Mraz.
+
diff --git a/modules/pam_faillock/README.xml b/modules/pam_faillock/README.xml
new file mode 100644
index 0000000..f0654db
--- /dev/null
+++ b/modules/pam_faillock/README.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_faillock.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_faillock.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_faillock-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-notes"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_faillock.8.xml" xpointer='xpointer(//refsect1[@id = "pam_faillock-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_faillock/faillock.8 b/modules/pam_faillock/faillock.8
new file mode 100644
index 0000000..5544353
--- /dev/null
+++ b/modules/pam_faillock/faillock.8
@@ -0,0 +1,78 @@
+'\" t
+.\" Title: faillock
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "FAILLOCK" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+faillock \- Tool for displaying and modifying the authentication failure record files
+.SH "SYNOPSIS"
+.HP \w'\fBfaillock\fR\ 'u
+\fBfaillock\fR [\-\-dir\ \fI/path/to/tally\-directory\fR] [\-\-user\ \fIusername\fR] [\-\-reset]
+.SH "DESCRIPTION"
+.PP
+The
+\fIpam_faillock\&.so\fR
+module maintains a list of failed authentication attempts per user during a specified interval and locks the account in case there were more than
+\fIdeny\fR
+consecutive failed authentications\&. It stores the failure records into per\-user files in the tally directory\&.
+.PP
+The
+\fBfaillock\fR
+command is an application which can be used to examine and modify the contents of the tally files\&. It can display the recent failed authentication attempts of the
+\fIusername\fR
+or clear the tally files of all or individual
+\fIusernames\fR\&.
+.SH "OPTIONS"
+.PP
+\fB\-\-dir \fR\fB\fI/path/to/tally\-directory\fR\fR
+.RS 4
+The directory where the user files with the failure records are kept\&. The default is
+/var/run/faillock\&.
+.RE
+.PP
+\fB\-\-user \fR\fB\fIusername\fR\fR
+.RS 4
+The user whose failure records should be displayed or cleared\&.
+.RE
+.PP
+\fB\-\-reset\fR
+.RS 4
+Instead of displaying the user\*(Aqs failure records, clear them\&.
+.RE
+.SH "FILES"
+.PP
+/var/run/faillock/*
+.RS 4
+the files logging the authentication failures for users
+.RE
+.SH "SEE ALSO"
+.PP
+\fBpam_faillock\fR(8),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+faillock was written by Tomas Mraz\&.
diff --git a/modules/pam_faillock/faillock.8.xml b/modules/pam_faillock/faillock.8.xml
new file mode 100644
index 0000000..6c20593
--- /dev/null
+++ b/modules/pam_faillock/faillock.8.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="faillock">
+
+ <refmeta>
+ <refentrytitle>faillock</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_faillock-name">
+ <refname>faillock</refname>
+ <refpurpose>Tool for displaying and modifying the authentication failure record files</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="faillock-cmdsynopsis">
+ <command>faillock</command>
+ <arg choice="opt">
+ --dir <replaceable>/path/to/tally-directory</replaceable>
+ </arg>
+ <arg choice="opt">
+ --user <replaceable>username</replaceable>
+ </arg>
+ <arg choice="opt">
+ --reset
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="faillock-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ The <emphasis>pam_faillock.so</emphasis> module maintains a list of
+ failed authentication attempts per user during a specified interval
+ and locks the account in case there were more than
+ <replaceable>deny</replaceable> consecutive failed authentications.
+ It stores the failure records into per-user files in the tally
+ directory.
+ </para>
+ <para>
+ The <command>faillock</command> command is an application which
+ can be used to examine and modify the contents of the
+ tally files. It can display the recent failed authentication
+ attempts of the <replaceable>username</replaceable> or clear the tally
+ files of all or individual <replaceable>usernames</replaceable>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="faillock-options">
+
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>--dir <replaceable>/path/to/tally-directory</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The directory where the user files with the failure records are kept. The
+ default is <filename>/var/run/faillock</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>--user <replaceable>username</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The user whose failure records should be displayed or cleared.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>--reset</option>
+ </term>
+ <listitem>
+ <para>
+ Instead of displaying the user's failure records, clear them.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="faillock-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/var/run/faillock/*</filename></term>
+ <listitem>
+ <para>the files logging the authentication failures for users</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='faillock-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam_faillock</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='faillock-author'>
+ <title>AUTHOR</title>
+ <para>
+ faillock was written by Tomas Mraz.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_faillock/faillock.c b/modules/pam_faillock/faillock.c
new file mode 100644
index 0000000..091f253
--- /dev/null
+++ b/modules/pam_faillock/faillock.c
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2010 Tomas Mraz <tmraz@redhat.com>
+ * Copyright (c) 2010, 2016, 2017 Red Hat, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <security/pam_modutil.h>
+
+#include "faillock.h"
+
+#define ignore_return(x) if (1==((int)x)) {;}
+
+int
+open_tally (const char *dir, const char *user, uid_t uid, int create)
+{
+ char *path;
+ int flags = O_RDWR;
+ int fd;
+
+ if (dir == NULL || strstr(user, "../") != NULL)
+ /* just a defensive programming as the user must be a
+ * valid user on the system anyway
+ */
+ return -1;
+ path = malloc(strlen(dir) + strlen(user) + 2);
+ if (path == NULL)
+ return -1;
+
+ strcpy(path, dir);
+ if (*dir && dir[strlen(dir) - 1] != '/') {
+ strcat(path, "/");
+ }
+ strcat(path, user);
+
+ if (create) {
+ flags |= O_CREAT;
+ if (access(dir, F_OK) != 0) {
+ mkdir(dir, 0755);
+ }
+ }
+
+ fd = open(path, flags, 0660);
+
+ free(path);
+
+ if (fd != -1) {
+ struct stat st;
+
+ while (flock(fd, LOCK_EX) == -1 && errno == EINTR);
+ if (fstat(fd, &st) == 0) {
+ if (st.st_uid != uid) {
+ ignore_return(fchown(fd, uid, -1));
+ }
+
+ /*
+ * If umask is set to 022, as will probably in most systems, then the
+ * group will not be able to write to the file. So, change the file
+ * permissions just in case.
+ * Note: owners of this file are user:root, so if the permissions are
+ * not changed the root process writing to this file will require
+ * CAP_DAC_OVERRIDE.
+ */
+ if (!(st.st_mode & S_IWGRP)) {
+ ignore_return(fchmod(fd, 0660));
+ }
+ }
+ }
+
+ return fd;
+}
+
+#define CHUNK_SIZE (64 * sizeof(struct tally))
+#define MAX_RECORDS 1024
+
+int
+read_tally(int fd, struct tally_data *tallies)
+{
+ void *data = NULL, *newdata;
+ unsigned int count = 0;
+ ssize_t chunk = 0;
+
+ do {
+ newdata = realloc(data, count * sizeof(struct tally) + CHUNK_SIZE);
+ if (newdata == NULL) {
+ free(data);
+ return -1;
+ }
+
+ data = newdata;
+
+ chunk = pam_modutil_read(fd, (char *)data + count * sizeof(struct tally), CHUNK_SIZE);
+ if (chunk < 0) {
+ free(data);
+ return -1;
+ }
+
+ count += chunk/sizeof(struct tally);
+
+ if (count >= MAX_RECORDS)
+ break;
+ }
+ while (chunk == CHUNK_SIZE);
+
+ tallies->records = data;
+ tallies->count = count;
+
+ return 0;
+}
+
+int
+update_tally(int fd, struct tally_data *tallies)
+{
+ void *data = tallies->records;
+ unsigned int count = tallies->count;
+ ssize_t chunk;
+
+ if (tallies->count > MAX_RECORDS) {
+ data = tallies->records + (count - MAX_RECORDS);
+ count = MAX_RECORDS;
+ }
+
+ if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
+ return -1;
+ }
+
+ chunk = pam_modutil_write(fd, data, count * sizeof(struct tally));
+
+ if (chunk != (ssize_t)(count * sizeof(struct tally))) {
+ return -1;
+ }
+
+ if (ftruncate(fd, count * sizeof(struct tally)) == -1)
+ return -1;
+
+ return 0;
+}
diff --git a/modules/pam_faillock/faillock.conf b/modules/pam_faillock/faillock.conf
new file mode 100644
index 0000000..16d93df
--- /dev/null
+++ b/modules/pam_faillock/faillock.conf
@@ -0,0 +1,62 @@
+# Configuration for locking the user after multiple failed
+# authentication attempts.
+#
+# The directory where the user files with the failure records are kept.
+# The default is /var/run/faillock.
+# dir = /var/run/faillock
+#
+# Will log the user name into the system log if the user is not found.
+# Enabled if option is present.
+# audit
+#
+# Don't print informative messages.
+# Enabled if option is present.
+# silent
+#
+# Don't log informative messages via syslog.
+# Enabled if option is present.
+# no_log_info
+#
+# Only track failed user authentications attempts for local users
+# in /etc/passwd and ignore centralized (AD, IdM, LDAP, etc.) users.
+# The `faillock` command will also no longer track user failed
+# authentication attempts. Enabling this option will prevent a
+# double-lockout scenario where a user is locked out locally and
+# in the centralized mechanism.
+# Enabled if option is present.
+# local_users_only
+#
+# Deny access if the number of consecutive authentication failures
+# for this user during the recent interval exceeds n tries.
+# The default is 3.
+# deny = 3
+#
+# The length of the interval during which the consecutive
+# authentication failures must happen for the user account
+# lock out is <replaceable>n</replaceable> seconds.
+# The default is 900 (15 minutes).
+# fail_interval = 900
+#
+# The access will be re-enabled after n seconds after the lock out.
+# The value 0 has the same meaning as value `never` - the access
+# will not be re-enabled without resetting the faillock
+# entries by the `faillock` command.
+# The default is 600 (10 minutes).
+# unlock_time = 600
+#
+# Root account can become locked as well as regular accounts.
+# Enabled if option is present.
+# even_deny_root
+#
+# This option implies the `even_deny_root` option.
+# Allow access after n seconds to root account after the
+# account is locked. In case the option is not specified
+# the value is the same as of the `unlock_time` option.
+# root_unlock_time = 900
+#
+# If a group name is specified with this option, members
+# of the group will be handled by this module the same as
+# the root account (the options `even_deny_root>` and
+# `root_unlock_time` will apply to them.
+# By default, the option is not set.
+# admin_group = <admin_group_name>
diff --git a/modules/pam_faillock/faillock.conf.5 b/modules/pam_faillock/faillock.conf.5
new file mode 100644
index 0000000..7b4ddb5
--- /dev/null
+++ b/modules/pam_faillock/faillock.conf.5
@@ -0,0 +1,171 @@
+'\" t
+.\" Title: faillock.conf
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "FAILLOCK\&.CONF" "5" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+faillock.conf \- pam_faillock configuration file
+.SH "DESCRIPTION"
+.PP
+\fBfaillock\&.conf\fR
+provides a way to configure the default settings for locking the user after multiple failed authentication attempts\&. This file is read by the
+\fIpam_faillock\fR
+module and is the preferred method over configuring
+\fIpam_faillock\fR
+directly\&.
+.PP
+The file has a very simple
+\fIname = value\fR
+format with possible comments starting with
+\fI#\fR
+character\&. The whitespace at the beginning of line, end of line, and around the
+\fI=\fR
+sign is ignored\&.
+.SH "OPTIONS"
+.PP
+\fBdir=\fR\fB\fI/path/to/tally\-directory\fR\fR
+.RS 4
+The directory where the user files with the failure records are kept\&. The default is
+/var/run/faillock\&.
+.RE
+.PP
+\fBaudit\fR
+.RS 4
+Will log the user name into the system log if the user is not found\&.
+.RE
+.PP
+\fBsilent\fR
+.RS 4
+Don\*(Aqt print informative messages to the user\&. Please note that when this option is not used there will be difference in the authentication behavior for users which exist on the system and non\-existing users\&.
+.RE
+.PP
+\fBno_log_info\fR
+.RS 4
+Don\*(Aqt log informative messages via
+\fBsyslog\fR(3)\&.
+.RE
+.PP
+\fBlocal_users_only\fR
+.RS 4
+Only track failed user authentications attempts for local users in /etc/passwd and ignore centralized (AD, IdM, LDAP, etc\&.) users\&. The
+\fBfaillock\fR(8)
+command will also no longer track user failed authentication attempts\&. Enabling this option will prevent a double\-lockout scenario where a user is locked out locally and in the centralized mechanism\&.
+.RE
+.PP
+\fBnodelay\fR
+.RS 4
+Don\*(Aqt enforce a delay after authentication failures\&.
+.RE
+.PP
+\fBdeny=\fR\fB\fIn\fR\fR
+.RS 4
+Deny access if the number of consecutive authentication failures for this user during the recent interval exceeds
+\fIn\fR\&. The default is 3\&.
+.RE
+.PP
+\fBfail_interval=\fR\fB\fIn\fR\fR
+.RS 4
+The length of the interval during which the consecutive authentication failures must happen for the user account lock out is
+\fIn\fR
+seconds\&. The default is 900 (15 minutes)\&.
+.RE
+.PP
+\fBunlock_time=\fR\fB\fIn\fR\fR
+.RS 4
+The access will be re\-enabled after
+\fIn\fR
+seconds after the lock out\&. The value 0 has the same meaning as value
+\fInever\fR
+\- the access will not be re\-enabled without resetting the faillock entries by the
+\fBfaillock\fR(8)
+command\&. The default is 600 (10 minutes)\&.
+.sp
+Note that the default directory that
+\fIpam_faillock\fR
+uses is usually cleared on system boot so the access will be also re\-enabled after system reboot\&. If that is undesirable a different tally directory must be set with the
+\fBdir\fR
+option\&.
+.sp
+Also note that it is usually undesirable to permanently lock out users as they can become easily a target of denial of service attack unless the usernames are random and kept secret to potential attackers\&.
+.RE
+.PP
+\fBeven_deny_root\fR
+.RS 4
+Root account can become locked as well as regular accounts\&.
+.RE
+.PP
+\fBroot_unlock_time=\fR\fB\fIn\fR\fR
+.RS 4
+This option implies
+\fBeven_deny_root\fR
+option\&. Allow access after
+\fIn\fR
+seconds to root account after the account is locked\&. In case the option is not specified the value is the same as of the
+\fBunlock_time\fR
+option\&.
+.RE
+.PP
+\fBadmin_group=\fR\fB\fIname\fR\fR
+.RS 4
+If a group name is specified with this option, members of the group will be handled by this module the same as the root account (the options
+\fBeven_deny_root\fR
+and
+\fBroot_unlock_time\fR
+will apply to them\&. By default the option is not set\&.
+.RE
+.SH "EXAMPLES"
+.PP
+/etc/security/faillock\&.conf file example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+deny=4
+unlock_time=1200
+silent
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "FILES"
+.PP
+/etc/security/faillock\&.conf
+.RS 4
+the config file for custom options
+.RE
+.SH "SEE ALSO"
+.PP
+\fBfaillock\fR(8),
+\fBpam_faillock\fR(8),
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_faillock was written by Tomas Mraz\&. The support for faillock\&.conf was written by Brian Ward\&.
diff --git a/modules/pam_faillock/faillock.conf.5.xml b/modules/pam_faillock/faillock.conf.5.xml
new file mode 100644
index 0000000..04a8410
--- /dev/null
+++ b/modules/pam_faillock/faillock.conf.5.xml
@@ -0,0 +1,253 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="faillock.conf">
+
+ <refmeta>
+ <refentrytitle>faillock.conf</refentrytitle>
+ <manvolnum>5</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="faillock.conf-name">
+ <refname>faillock.conf</refname>
+ <refpurpose>pam_faillock configuration file</refpurpose>
+ </refnamediv>
+
+ <refsect1 id="faillock.conf-description">
+
+ <title>DESCRIPTION</title>
+ <para>
+ <emphasis remap='B'>faillock.conf</emphasis> provides a way to configure the
+ default settings for locking the user after multiple failed authentication attempts.
+ This file is read by the <emphasis>pam_faillock</emphasis> module and is the
+ preferred method over configuring <emphasis>pam_faillock</emphasis> directly.
+ </para>
+ <para>
+ The file has a very simple <emphasis>name = value</emphasis> format with possible comments
+ starting with <emphasis>#</emphasis> character. The whitespace at the beginning of line, end
+ of line, and around the <emphasis>=</emphasis> sign is ignored.
+ </para>
+ </refsect1>
+
+ <refsect1 id="faillock.conf-options">
+
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>dir=<replaceable>/path/to/tally-directory</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The directory where the user files with the failure records are kept. The
+ default is <filename>/var/run/faillock</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>audit</option>
+ </term>
+ <listitem>
+ <para>
+ Will log the user name into the system log if the user is not found.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>silent</option>
+ </term>
+ <listitem>
+ <para>
+ Don't print informative messages to the user. Please note that when
+ this option is not used there will be difference in the authentication
+ behavior for users which exist on the system and non-existing users.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>no_log_info</option>
+ </term>
+ <listitem>
+ <para>
+ Don't log informative messages via <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>local_users_only</option>
+ </term>
+ <listitem>
+ <para>
+ Only track failed user authentications attempts for local users
+ in /etc/passwd and ignore centralized (AD, IdM, LDAP, etc.) users.
+ The <citerefentry><refentrytitle>faillock</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ command will also no longer track user failed
+ authentication attempts. Enabling this option will prevent a
+ double-lockout scenario where a user is locked out locally and
+ in the centralized mechanism.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>nodelay</option>
+ </term>
+ <listitem>
+ <para>
+ Don't enforce a delay after authentication failures.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>deny=<replaceable>n</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Deny access if the number of consecutive authentication failures
+ for this user during the recent interval exceeds
+ <replaceable>n</replaceable>. The default is 3.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>fail_interval=<replaceable>n</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The length of the interval during which the consecutive
+ authentication failures must happen for the user account
+ lock out is <replaceable>n</replaceable> seconds.
+ The default is 900 (15 minutes).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>unlock_time=<replaceable>n</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The access will be re-enabled after
+ <replaceable>n</replaceable> seconds after the lock out.
+ The value 0 has the same meaning as value
+ <emphasis>never</emphasis> - the access
+ will not be re-enabled without resetting the faillock
+ entries by the <citerefentry><refentrytitle>faillock</refentrytitle><manvolnum>8</manvolnum></citerefentry> command.
+ The default is 600 (10 minutes).
+ </para>
+ <para>
+ Note that the default directory that <emphasis>pam_faillock</emphasis>
+ uses is usually cleared on system boot so the access will be also re-enabled
+ after system reboot. If that is undesirable a different tally directory
+ must be set with the <option>dir</option> option.
+ </para>
+ <para>
+ Also note that it is usually undesirable to permanently lock
+ out users as they can become easily a target of denial of service
+ attack unless the usernames are random and kept secret to potential
+ attackers.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>even_deny_root</option>
+ </term>
+ <listitem>
+ <para>
+ Root account can become locked as well as regular accounts.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>root_unlock_time=<replaceable>n</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ This option implies <option>even_deny_root</option> option.
+ Allow access after <replaceable>n</replaceable> seconds
+ to root account after the account is locked. In case the
+ option is not specified the value is the same as of the
+ <option>unlock_time</option> option.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>admin_group=<replaceable>name</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ If a group name is specified with this option, members
+ of the group will be handled by this module the same as
+ the root account (the options <option>even_deny_root</option>
+ and <option>root_unlock_time</option> will apply to them.
+ By default the option is not set.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='faillock.conf-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ /etc/security/faillock.conf file example:
+ </para>
+ <programlisting>
+deny=4
+unlock_time=1200
+silent
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id="faillock.conf-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/security/faillock.conf</filename></term>
+ <listitem>
+ <para>the config file for custom options</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='faillock.conf-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>faillock</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam_faillock</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='faillock.conf-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_faillock was written by Tomas Mraz. The support for faillock.conf was written by Brian Ward.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_faillock/faillock.h b/modules/pam_faillock/faillock.h
new file mode 100644
index 0000000..b22a9df
--- /dev/null
+++ b/modules/pam_faillock/faillock.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2010 Tomas Mraz <tmraz@redhat.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * faillock.h - authentication failure data file record structure
+ *
+ * Each record in the file represents an instance of login failure of
+ * the user at the recorded time.
+ */
+
+
+#ifndef _FAILLOCK_H
+#define _FAILLOCK_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#define TALLY_STATUS_VALID 0x1 /* the tally file entry is valid */
+#define TALLY_STATUS_RHOST 0x2 /* the source is rhost */
+#define TALLY_STATUS_TTY 0x4 /* the source is tty */
+/* If neither TALLY_FLAG_RHOST nor TALLY_FLAG_TTY are set the source is service. */
+
+struct tally {
+ char source[52]; /* rhost or tty of the login failure */
+ /* (not necessarily NULL terminated) */
+ uint16_t reserved; /* reserved for future use */
+ uint16_t status; /* record status */
+ uint64_t time; /* time of the login failure */
+};
+/* 64 bytes per entry */
+
+struct tally_data {
+ struct tally *records; /* array of tallies */
+ unsigned int count; /* number of records */
+};
+
+#define FAILLOCK_DEFAULT_TALLYDIR "/var/run/faillock"
+#define FAILLOCK_DEFAULT_CONF "/etc/security/faillock.conf"
+
+int open_tally(const char *dir, const char *user, uid_t uid, int create);
+int read_tally(int fd, struct tally_data *tallies);
+int update_tally(int fd, struct tally_data *tallies);
+#endif
diff --git a/modules/pam_faillock/main.c b/modules/pam_faillock/main.c
new file mode 100644
index 0000000..f62e1bb
--- /dev/null
+++ b/modules/pam_faillock/main.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2010 Tomas Mraz <tmraz@redhat.com>
+ * Copyright (c) 2010 Red Hat, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dirent.h>
+#include <errno.h>
+#include <pwd.h>
+#include <time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#ifdef HAVE_LIBAUDIT
+#include <libaudit.h>
+
+#define AUDIT_NO_ID ((unsigned int) -1)
+#endif
+
+#include "faillock.h"
+
+struct options {
+ unsigned int reset;
+ const char *dir;
+ const char *user;
+ const char *progname;
+};
+
+static int
+args_parse(int argc, char **argv, struct options *opts)
+{
+ int i;
+ memset(opts, 0, sizeof(*opts));
+
+ opts->dir = FAILLOCK_DEFAULT_TALLYDIR;
+ opts->progname = argv[0];
+
+ for (i = 1; i < argc; ++i) {
+ if (strcmp(argv[i], "--dir") == 0) {
+ ++i;
+ if (i >= argc || strlen(argv[i]) == 0) {
+ fprintf(stderr, "%s: No directory supplied.\n", argv[0]);
+ return -1;
+ }
+ opts->dir = argv[i];
+ }
+ else if (strcmp(argv[i], "--user") == 0) {
+ ++i;
+ if (i >= argc || strlen(argv[i]) == 0) {
+ fprintf(stderr, "%s: No user name supplied.\n", argv[0]);
+ return -1;
+ }
+ opts->user = argv[i];
+ }
+ else if (strcmp(argv[i], "--reset") == 0) {
+ opts->reset = 1;
+ }
+ else {
+ fprintf(stderr, "%s: Unknown option: %s\n", argv[0], argv[i]);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static void
+usage(const char *progname)
+{
+ fprintf(stderr, _("Usage: %s [--dir /path/to/tally-directory] [--user username] [--reset]\n"),
+ progname);
+}
+
+static int
+do_user(struct options *opts, const char *user)
+{
+ int fd;
+ int rv;
+ struct tally_data tallies;
+ struct passwd *pwd;
+
+ pwd = getpwnam(user);
+
+ fd = open_tally(opts->dir, user, pwd != NULL ? pwd->pw_uid : 0, 0);
+
+ if (fd == -1) {
+ if (errno == ENOENT) {
+ return 0;
+ }
+ else {
+ fprintf(stderr, "%s: Error opening the tally file for %s:",
+ opts->progname, user);
+ perror(NULL);
+ return 3;
+ }
+ }
+ if (opts->reset) {
+#ifdef HAVE_LIBAUDIT
+ int audit_fd;
+#endif
+
+ while ((rv=ftruncate(fd, 0)) == -1 && errno == EINTR);
+ if (rv == -1) {
+ fprintf(stderr, "%s: Error clearing the tally file for %s:",
+ opts->progname, user);
+ perror(NULL);
+#ifdef HAVE_LIBAUDIT
+ }
+ if ((audit_fd=audit_open()) >= 0) {
+ audit_log_acct_message(audit_fd, AUDIT_USER_MGMT, NULL,
+ "faillock-reset", user,
+ pwd != NULL ? pwd->pw_uid : AUDIT_NO_ID,
+ NULL, NULL, NULL, rv == 0);
+ close(audit_fd);
+ }
+ if (rv == -1) {
+#endif
+ close(fd);
+ return 4;
+ }
+ }
+ else {
+ unsigned int i;
+
+ memset(&tallies, 0, sizeof(tallies));
+ if (read_tally(fd, &tallies) == -1) {
+ fprintf(stderr, "%s: Error reading the tally file for %s:",
+ opts->progname, user);
+ perror(NULL);
+ close(fd);
+ return 5;
+ }
+
+ printf("%s:\n", user);
+ printf("%-19s %-5s %-48s %-5s\n", "When", "Type", "Source", "Valid");
+
+ for (i = 0; i < tallies.count; i++) {
+ struct tm *tm;
+ char timebuf[80];
+ uint16_t status = tallies.records[i].status;
+ time_t when = tallies.records[i].time;
+
+ tm = localtime(&when);
+ strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tm);
+ printf("%-19s %-5s %-52.52s %s\n", timebuf,
+ status & TALLY_STATUS_RHOST ? "RHOST" : (status & TALLY_STATUS_TTY ? "TTY" : "SVC"),
+ tallies.records[i].source, status & TALLY_STATUS_VALID ? "V":"I");
+ }
+ free(tallies.records);
+ }
+ close(fd);
+ return 0;
+}
+
+static int
+do_allusers(struct options *opts)
+{
+ struct dirent **userlist;
+ int rv, i;
+
+ rv = scandir(opts->dir, &userlist, NULL, alphasort);
+ if (rv < 0) {
+ fprintf(stderr, "%s: Error reading tally directory: %m\n", opts->progname);
+ return 2;
+ }
+
+ for (i = 0; i < rv; i++) {
+ if (userlist[i]->d_name[0] == '.') {
+ if ((userlist[i]->d_name[1] == '.' && userlist[i]->d_name[2] == '\0') ||
+ userlist[i]->d_name[1] == '\0')
+ continue;
+ }
+ do_user(opts, userlist[i]->d_name);
+ free(userlist[i]);
+ }
+ free(userlist);
+
+ return 0;
+}
+
+
+/*-----------------------------------------------------------------------*/
+int
+main (int argc, char *argv[])
+{
+ struct options opts;
+
+ if (args_parse(argc, argv, &opts)) {
+ usage(argv[0]);
+ return 1;
+ }
+
+ if (opts.user == NULL) {
+ return do_allusers(&opts);
+ }
+
+ return do_user(&opts, opts.user);
+}
diff --git a/modules/pam_faillock/pam_faillock.8 b/modules/pam_faillock/pam_faillock.8
new file mode 100644
index 0000000..cec02ea
--- /dev/null
+++ b/modules/pam_faillock/pam_faillock.8
@@ -0,0 +1,262 @@
+'\" t
+.\" Title: pam_faillock
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_FAILLOCK" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_faillock \- Module counting authentication failures during a specified interval
+.SH "SYNOPSIS"
+.HP \w'\fBauth\ \&.\&.\&.\ pam_faillock\&.so\fR\ 'u
+\fBauth \&.\&.\&. pam_faillock\&.so\fR {preauth|authfail|authsucc} [conf=\fI/path/to/config\-file\fR] [dir=\fI/path/to/tally\-directory\fR] [even_deny_root] [deny=\fIn\fR] [fail_interval=\fIn\fR] [unlock_time=\fIn\fR] [root_unlock_time=\fIn\fR] [admin_group=\fIname\fR] [audit] [silent] [no_log_info]
+.HP \w'\fBaccount\ \&.\&.\&.\ pam_faillock\&.so\fR\ 'u
+\fBaccount \&.\&.\&. pam_faillock\&.so\fR [dir=\fI/path/to/tally\-directory\fR] [no_log_info]
+.SH "DESCRIPTION"
+.PP
+This module maintains a list of failed authentication attempts per user during a specified interval and locks the account in case there were more than
+\fIdeny\fR
+consecutive failed authentications\&.
+.PP
+Normally, failed attempts to authenticate
+\fIroot\fR
+will
+\fBnot\fR
+cause the root account to become blocked, to prevent denial\-of\-service: if your users aren\*(Aqt given shell accounts and root may only login via
+\fBsu\fR
+or at the machine console (not telnet/rsh, etc), this is safe\&.
+.SH "OPTIONS"
+.PP
+\fB{preauth|authfail|authsucc}\fR
+.RS 4
+This argument must be set accordingly to the position of this module instance in the PAM stack\&.
+.sp
+The
+\fIpreauth\fR
+argument must be used when the module is called before the modules which ask for the user credentials such as the password\&. The module just examines whether the user should be blocked from accessing the service in case there were anomalous number of failed consecutive authentication attempts recently\&. This call is optional if
+\fIauthsucc\fR
+is used\&.
+.sp
+The
+\fIauthfail\fR
+argument must be used when the module is called after the modules which determine the authentication outcome, failed\&. Unless the user is already blocked due to previous authentication failures, the module will record the failure into the appropriate user tally file\&.
+.sp
+The
+\fIauthsucc\fR
+argument must be used when the module is called after the modules which determine the authentication outcome, succeeded\&. Unless the user is already blocked due to previous authentication failures, the module will then clear the record of the failures in the respective user tally file\&. Otherwise it will return authentication error\&. If this call is not done, the pam_faillock will not distinguish between consecutive and non\-consecutive failed authentication attempts\&. The
+\fIpreauth\fR
+call must be used in such case\&. Due to complications in the way the PAM stack can be configured it is also possible to call
+\fIpam_faillock\fR
+as an account module\&. In such configuration the module must be also called in the
+\fIpreauth\fR
+stage\&.
+.RE
+.PP
+\fBconf=/path/to/config\-file\fR
+.RS 4
+Use another configuration file instead of the default
+/etc/security/faillock\&.conf\&.
+.RE
+.PP
+The options for configuring the module behavior are described in the
+\fBfaillock.conf\fR(5)
+manual page\&. The options specified on the module command line override the values from the configuration file\&.
+.SH "MODULE TYPES PROVIDED"
+.PP
+The
+\fBauth\fR
+and
+\fBaccount\fR
+module types are provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_AUTH_ERR
+.RS 4
+An invalid option was given, the module was not able to retrieve the user name, no valid counter file was found, or too many failed logins\&.
+.RE
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_CONV_ERR
+.RS 4
+The conversation method supplied by the application failed to obtain the username\&.
+.RE
+.PP
+PAM_INCOMPLETE
+.RS 4
+The conversation method supplied by the application returned PAM_CONV_AGAIN\&.
+.RE
+.PP
+PAM_SUCCESS
+.RS 4
+Everything was successful\&.
+.RE
+.PP
+PAM_IGNORE
+.RS 4
+User not present in passwd database\&.
+.RE
+.SH "NOTES"
+.PP
+Configuring options on the module command line is not recommend\&. The
+/etc/security/faillock\&.conf
+should be used instead\&.
+.PP
+The setup of
+\fIpam_faillock\fR
+in the PAM stack is different from the
+\fIpam_tally2\fR
+module setup\&.
+.PP
+Individual files with the failure records are created as owned by the user\&. This allows
+\fBpam_faillock\&.so\fR
+module to work correctly when it is called from a screensaver\&.
+.PP
+Note that using the module in
+\fBpreauth\fR
+without the
+\fBsilent\fR
+option specified in
+/etc/security/faillock\&.conf
+or with
+\fIrequisite\fR
+control field leaks an information about existence or non\-existence of a user account in the system because the failures are not recorded for the unknown users\&. The message about the user account being locked is never displayed for non\-existing user accounts allowing the adversary to infer that a particular account is not existing on a system\&.
+.SH "EXAMPLES"
+.PP
+Here are two possible configuration examples for
+/etc/pam\&.d/login\&. They make
+\fIpam_faillock\fR
+to lock the account after 4 consecutive failed logins during the default interval of 15 minutes\&. Root account will be locked as well\&. The accounts will be automatically unlocked after 20 minutes\&.
+.PP
+In the first example the module is called only in the
+\fIauth\fR
+phase and the module does not print any information about the account being blocked by
+\fIpam_faillock\fR\&. The
+\fIpreauth\fR
+call can be added to tell users that their logins are blocked by the module and also to abort the authentication without even asking for password in such case\&.
+.PP
+/etc/security/faillock\&.conf
+file example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+deny=4
+unlock_time=1200
+silent
+
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+/etc/pam\&.d/config file example:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+auth required pam_securetty\&.so
+auth required pam_env\&.so
+auth required pam_nologin\&.so
+# optionally call: auth requisite pam_faillock\&.so preauth
+# to display the message about account being locked
+auth [success=1 default=bad] pam_unix\&.so
+auth [default=die] pam_faillock\&.so authfail
+auth sufficient pam_faillock\&.so authsucc
+auth required pam_deny\&.so
+account required pam_unix\&.so
+password required pam_unix\&.so shadow
+session required pam_selinux\&.so close
+session required pam_loginuid\&.so
+session required pam_unix\&.so
+session required pam_selinux\&.so open
+
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+In the second example the module is called both in the
+\fIauth\fR
+and
+\fIaccount\fR
+phases and the module informs the authenticating user when the account is locked if
+\fBsilent\fR
+option is not specified in the
+faillock\&.conf\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+auth required pam_securetty\&.so
+auth required pam_env\&.so
+auth required pam_nologin\&.so
+auth required pam_faillock\&.so preauth
+# optionally use requisite above if you do not want to prompt for the password
+# on locked accounts
+auth sufficient pam_unix\&.so
+auth [default=die] pam_faillock\&.so authfail
+auth required pam_deny\&.so
+account required pam_faillock\&.so
+# if you drop the above call to pam_faillock\&.so the lock will be done also
+# on non\-consecutive authentication failures
+account required pam_unix\&.so
+password required pam_unix\&.so shadow
+session required pam_selinux\&.so close
+session required pam_loginuid\&.so
+session required pam_unix\&.so
+session required pam_selinux\&.so open
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "FILES"
+.PP
+/var/run/faillock/*
+.RS 4
+the files logging the authentication failures for users
+.RE
+.PP
+/etc/security/faillock\&.conf
+.RS 4
+the config file for pam_faillock options
+.RE
+.SH "SEE ALSO"
+.PP
+\fBfaillock\fR(8),
+\fBfaillock.conf\fR(5),
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_faillock was written by Tomas Mraz\&.
diff --git a/modules/pam_faillock/pam_faillock.8.xml b/modules/pam_faillock/pam_faillock.8.xml
new file mode 100644
index 0000000..58c1644
--- /dev/null
+++ b/modules/pam_faillock/pam_faillock.8.xml
@@ -0,0 +1,362 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_faillock">
+
+ <refmeta>
+ <refentrytitle>pam_faillock</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_faillock-name">
+ <refname>pam_faillock</refname>
+ <refpurpose>Module counting authentication failures during a specified interval</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_faillock-cmdsynopsisauth">
+ <command>auth ... pam_faillock.so</command>
+ <arg choice="req">
+ preauth|authfail|authsucc
+ </arg>
+ <arg choice="opt">
+ conf=<replaceable>/path/to/config-file</replaceable>
+ </arg>
+ <arg choice="opt">
+ dir=<replaceable>/path/to/tally-directory</replaceable>
+ </arg>
+ <arg choice="opt">
+ even_deny_root
+ </arg>
+ <arg choice="opt">
+ deny=<replaceable>n</replaceable>
+ </arg>
+ <arg choice="opt">
+ fail_interval=<replaceable>n</replaceable>
+ </arg>
+ <arg choice="opt">
+ unlock_time=<replaceable>n</replaceable>
+ </arg>
+ <arg choice="opt">
+ root_unlock_time=<replaceable>n</replaceable>
+ </arg>
+ <arg choice="opt">
+ admin_group=<replaceable>name</replaceable>
+ </arg>
+ <arg choice="opt">
+ audit
+ </arg>
+ <arg choice="opt">
+ silent
+ </arg>
+ <arg choice="opt">
+ no_log_info
+ </arg>
+ </cmdsynopsis>
+ <cmdsynopsis id="pam_faillock-cmdsynopsisacct">
+ <command>account ... pam_faillock.so</command>
+ <arg choice="opt">
+ dir=<replaceable>/path/to/tally-directory</replaceable>
+ </arg>
+ <arg choice="opt">
+ no_log_info
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_faillock-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ This module maintains a list of failed authentication attempts per
+ user during a specified interval and locks the account in case
+ there were more than <replaceable>deny</replaceable> consecutive
+ failed authentications.
+ </para>
+ <para>
+ Normally, failed attempts to authenticate <emphasis>root</emphasis> will
+ <emphasis remap='B'>not</emphasis> cause the root account to become
+ blocked, to prevent denial-of-service: if your users aren't given
+ shell accounts and root may only login via <command>su</command> or
+ at the machine console (not telnet/rsh, etc), this is safe.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_faillock-options">
+
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>{preauth|authfail|authsucc}</option>
+ </term>
+ <listitem>
+ <para>
+ This argument must be set accordingly to the position of this module
+ instance in the PAM stack.
+ </para>
+ <para>
+ The <emphasis>preauth</emphasis> argument must be used when the module
+ is called before the modules which ask for the user credentials such
+ as the password. The module just examines whether the user should
+ be blocked from accessing the service in case there were anomalous
+ number of failed consecutive authentication attempts recently. This
+ call is optional if <emphasis>authsucc</emphasis> is used.
+ </para>
+ <para>
+ The <emphasis>authfail</emphasis> argument must be used when the module
+ is called after the modules which determine the authentication outcome,
+ failed. Unless the user is already blocked due to previous authentication
+ failures, the module will record the failure into the appropriate user
+ tally file.
+ </para>
+ <para>
+ The <emphasis>authsucc</emphasis> argument must be used when the module
+ is called after the modules which determine the authentication outcome,
+ succeeded. Unless the user is already blocked due to previous authentication
+ failures, the module will then clear the record of the failures in the
+ respective user tally file. Otherwise it will return authentication error.
+ If this call is not done, the pam_faillock will not distinguish between
+ consecutive and non-consecutive failed authentication attempts. The
+ <emphasis>preauth</emphasis> call must be used in such case. Due to
+ complications in the way the PAM stack can be configured it is also
+ possible to call <emphasis>pam_faillock</emphasis> as an account module.
+ In such configuration the module must be also called in the
+ <emphasis>preauth</emphasis> stage.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>conf=/path/to/config-file</option>
+ </term>
+ <listitem>
+ <para>
+ Use another configuration file instead of the default
+ <filename>/etc/security/faillock.conf</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+ The options for configuring the module behavior are described in the
+ <citerefentry><refentrytitle>faillock.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry> manual page. The options specified on the module command
+ line override the values from the configuration file.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_faillock-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ The <option>auth</option> and <option>account</option> module types are
+ provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_faillock-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_AUTH_ERR</term>
+ <listitem>
+ <para>
+ An invalid option was given, the module was not able
+ to retrieve the user name, no valid counter file
+ was found, or too many failed logins.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory buffer error.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_CONV_ERR</term>
+ <listitem>
+ <para>
+ The conversation method supplied by the application
+ failed to obtain the username.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_INCOMPLETE</term>
+ <listitem>
+ <para>
+ The conversation method supplied by the application
+ returned PAM_CONV_AGAIN.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Everything was successful.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ User not present in passwd database.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_faillock-notes'>
+ <title>NOTES</title>
+ <para>
+ Configuring options on the module command line is not recommend. The
+ <filename>/etc/security/faillock.conf</filename> should be used instead.
+ </para>
+ <para>
+ The setup of <emphasis>pam_faillock</emphasis> in the PAM stack is different
+ from the <emphasis>pam_tally2</emphasis> module setup.
+ </para>
+ <para>
+ Individual files with the failure records are created as owned by
+ the user. This allows <emphasis remap='B'>pam_faillock.so</emphasis> module
+ to work correctly when it is called from a screensaver.
+ </para>
+ <para>
+ Note that using the module in <option>preauth</option> without the
+ <option>silent</option> option specified in <filename>/etc/security/faillock.conf</filename>
+ or with <emphasis>requisite</emphasis> control field leaks an information about
+ existence or non-existence of a user account in the system because
+ the failures are not recorded for the unknown users. The message
+ about the user account being locked is never displayed for non-existing
+ user accounts allowing the adversary to infer that a particular account
+ is not existing on a system.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_faillock-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ Here are two possible configuration examples for <filename>/etc/pam.d/login</filename>.
+ They make <emphasis>pam_faillock</emphasis> to lock the account after 4 consecutive
+ failed logins during the default interval of 15 minutes. Root account will be locked
+ as well. The accounts will be automatically unlocked after 20 minutes.
+ </para>
+ <para>
+ In the first example the module is called only in the <emphasis>auth</emphasis>
+ phase and the module does not print any information about the account being blocked
+ by <emphasis>pam_faillock</emphasis>. The <emphasis>preauth</emphasis> call can
+ be added to tell users that their logins are blocked by the module and also to abort
+ the authentication without even asking for password in such case.
+ </para>
+ <para>
+ <filename>/etc/security/faillock.conf</filename> file example:
+ </para>
+ <programlisting>
+deny=4
+unlock_time=1200
+silent
+ </programlisting>
+ <para>
+ /etc/pam.d/config file example:
+ </para>
+ <programlisting>
+auth required pam_securetty.so
+auth required pam_env.so
+auth required pam_nologin.so
+# optionally call: auth requisite pam_faillock.so preauth
+# to display the message about account being locked
+auth [success=1 default=bad] pam_unix.so
+auth [default=die] pam_faillock.so authfail
+auth sufficient pam_faillock.so authsucc
+auth required pam_deny.so
+account required pam_unix.so
+password required pam_unix.so shadow
+session required pam_selinux.so close
+session required pam_loginuid.so
+session required pam_unix.so
+session required pam_selinux.so open
+ </programlisting>
+ <para>
+ In the second example the module is called both in the <emphasis>auth</emphasis>
+ and <emphasis>account</emphasis> phases and the module informs the authenticating
+ user when the account is locked if <option>silent</option> option is not
+ specified in the <filename>faillock.conf</filename>.
+ </para>
+ <programlisting>
+auth required pam_securetty.so
+auth required pam_env.so
+auth required pam_nologin.so
+auth required pam_faillock.so preauth
+# optionally use requisite above if you do not want to prompt for the password
+# on locked accounts
+auth sufficient pam_unix.so
+auth [default=die] pam_faillock.so authfail
+auth required pam_deny.so
+account required pam_faillock.so
+# if you drop the above call to pam_faillock.so the lock will be done also
+# on non-consecutive authentication failures
+account required pam_unix.so
+password required pam_unix.so shadow
+session required pam_selinux.so close
+session required pam_loginuid.so
+session required pam_unix.so
+session required pam_selinux.so open
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id="pam_faillock-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/var/run/faillock/*</filename></term>
+ <listitem>
+ <para>the files logging the authentication failures for users</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><filename>/etc/security/faillock.conf</filename></term>
+ <listitem>
+ <para>the config file for pam_faillock options</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_faillock-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>faillock</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>faillock.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_faillock-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_faillock was written by Tomas Mraz.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_faillock/pam_faillock.c b/modules/pam_faillock/pam_faillock.c
new file mode 100644
index 0000000..8328fba
--- /dev/null
+++ b/modules/pam_faillock/pam_faillock.c
@@ -0,0 +1,764 @@
+/*
+ * Copyright (c) 2010, 2017, 2019 Tomas Mraz <tmraz@redhat.com>
+ * Copyright (c) 2010, 2017, 2019 Red Hat, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <time.h>
+#include <pwd.h>
+#include <syslog.h>
+#include <ctype.h>
+
+#ifdef HAVE_LIBAUDIT
+#include <libaudit.h>
+#endif
+
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+
+#include "pam_inline.h"
+#include "faillock.h"
+
+#define FAILLOCK_ACTION_PREAUTH 0
+#define FAILLOCK_ACTION_AUTHSUCC 1
+#define FAILLOCK_ACTION_AUTHFAIL 2
+
+#define FAILLOCK_FLAG_DENY_ROOT 0x1
+#define FAILLOCK_FLAG_AUDIT 0x2
+#define FAILLOCK_FLAG_SILENT 0x4
+#define FAILLOCK_FLAG_NO_LOG_INFO 0x8
+#define FAILLOCK_FLAG_UNLOCKED 0x10
+#define FAILLOCK_FLAG_LOCAL_ONLY 0x20
+#define FAILLOCK_FLAG_NO_DELAY 0x40
+
+#define MAX_TIME_INTERVAL 604800 /* 7 days */
+#define FAILLOCK_CONF_MAX_LINELEN 1023
+
+static const char default_faillock_conf[] = FAILLOCK_DEFAULT_CONF;
+
+struct options {
+ unsigned int action;
+ unsigned int flags;
+ unsigned short deny;
+ unsigned int fail_interval;
+ unsigned int unlock_time;
+ unsigned int root_unlock_time;
+ char *dir;
+ const char *user;
+ char *admin_group;
+ int failures;
+ uint64_t latest_time;
+ uid_t uid;
+ int is_admin;
+ uint64_t now;
+ int fatal_error;
+};
+
+static int read_config_file(
+ pam_handle_t *pamh,
+ struct options *opts,
+ const char *cfgfile
+);
+
+static void set_conf_opt(
+ pam_handle_t *pamh,
+ struct options *opts,
+ const char *name,
+ const char *value
+);
+
+static int
+args_parse(pam_handle_t *pamh, int argc, const char **argv,
+ int flags, struct options *opts)
+{
+ int i;
+ int config_arg_index = -1;
+ int rv;
+ const char *conf = default_faillock_conf;
+
+ memset(opts, 0, sizeof(*opts));
+
+ opts->dir = strdup(FAILLOCK_DEFAULT_TALLYDIR);
+ opts->deny = 3;
+ opts->fail_interval = 900;
+ opts->unlock_time = 600;
+ opts->root_unlock_time = MAX_TIME_INTERVAL+1;
+
+ for (i = 0; i < argc; ++i) {
+ const char *str = pam_str_skip_prefix(argv[i], "conf=");
+
+ if (str != NULL) {
+ conf = str;
+ config_arg_index = i;
+ }
+ }
+
+ if ((rv = read_config_file(pamh, opts, conf)) != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR,
+ "Configuration file missing or broken");
+ return rv;
+ }
+
+ for (i = 0; i < argc; ++i) {
+ if (i == config_arg_index) {
+ continue;
+ }
+ else if (strcmp(argv[i], "preauth") == 0) {
+ opts->action = FAILLOCK_ACTION_PREAUTH;
+ }
+ else if (strcmp(argv[i], "authfail") == 0) {
+ opts->action = FAILLOCK_ACTION_AUTHFAIL;
+ }
+ else if (strcmp(argv[i], "authsucc") == 0) {
+ opts->action = FAILLOCK_ACTION_AUTHSUCC;
+ }
+ else {
+ char buf[FAILLOCK_CONF_MAX_LINELEN + 1];
+ char *val;
+
+ strncpy(buf, argv[i], sizeof(buf) - 1);
+ buf[sizeof(buf) - 1] = '\0';
+
+ val = strchr(buf, '=');
+ if (val != NULL) {
+ *val = '\0';
+ ++val;
+ }
+ else {
+ val = buf + sizeof(buf) - 1;
+ }
+ set_conf_opt(pamh, opts, buf, val);
+ }
+ }
+
+ if (opts->root_unlock_time == MAX_TIME_INTERVAL+1)
+ opts->root_unlock_time = opts->unlock_time;
+ if (flags & PAM_SILENT)
+ opts->flags |= FAILLOCK_FLAG_SILENT;
+
+ if (opts->dir == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "Error allocating memory: %m");
+ opts->fatal_error = 1;
+ }
+
+ if (opts->fatal_error)
+ return PAM_BUF_ERR;
+ return PAM_SUCCESS;
+}
+
+/* parse a single configuration file */
+static int
+read_config_file(pam_handle_t *pamh, struct options *opts, const char *cfgfile)
+{
+ FILE *f;
+ char linebuf[FAILLOCK_CONF_MAX_LINELEN+1];
+
+ f = fopen(cfgfile, "r");
+ if (f == NULL) {
+ /* ignore non-existent default config file */
+ if (errno == ENOENT && cfgfile == default_faillock_conf)
+ return PAM_SUCCESS;
+ return PAM_SERVICE_ERR;
+ }
+
+ while (fgets(linebuf, sizeof(linebuf), f) != NULL) {
+ size_t len;
+ char *ptr;
+ char *name;
+ int eq;
+
+ len = strlen(linebuf);
+ /* len cannot be 0 unless there is a bug in fgets */
+ if (len && linebuf[len - 1] != '\n' && !feof(f)) {
+ (void) fclose(f);
+ return PAM_SERVICE_ERR;
+ }
+
+ if ((ptr=strchr(linebuf, '#')) != NULL) {
+ *ptr = '\0';
+ } else {
+ ptr = linebuf + len;
+ }
+
+ /* drop terminating whitespace including the \n */
+ while (ptr > linebuf) {
+ if (!isspace(*(ptr-1))) {
+ *ptr = '\0';
+ break;
+ }
+ --ptr;
+ }
+
+ /* skip initial whitespace */
+ for (ptr = linebuf; isspace(*ptr); ptr++);
+ if (*ptr == '\0')
+ continue;
+
+ /* grab the key name */
+ eq = 0;
+ name = ptr;
+ while (*ptr != '\0') {
+ if (isspace(*ptr) || *ptr == '=') {
+ eq = *ptr == '=';
+ *ptr = '\0';
+ ++ptr;
+ break;
+ }
+ ++ptr;
+ }
+
+ /* grab the key value */
+ while (*ptr != '\0') {
+ if (*ptr != '=' || eq) {
+ if (!isspace(*ptr)) {
+ break;
+ }
+ } else {
+ eq = 1;
+ }
+ ++ptr;
+ }
+
+ /* set the key:value pair on opts */
+ set_conf_opt(pamh, opts, name, ptr);
+ }
+
+ (void)fclose(f);
+ return PAM_SUCCESS;
+}
+
+static void
+set_conf_opt(pam_handle_t *pamh, struct options *opts, const char *name, const char *value)
+{
+ if (strcmp(name, "dir") == 0) {
+ if (value[0] != '/') {
+ pam_syslog(pamh, LOG_ERR,
+ "Tally directory is not absolute path (%s); keeping default", value);
+ } else {
+ free(opts->dir);
+ opts->dir = strdup(value);
+ }
+ }
+ else if (strcmp(name, "deny") == 0) {
+ if (sscanf(value, "%hu", &opts->deny) != 1) {
+ pam_syslog(pamh, LOG_ERR,
+ "Bad number supplied for deny argument");
+ }
+ }
+ else if (strcmp(name, "fail_interval") == 0) {
+ unsigned int temp;
+ if (sscanf(value, "%u", &temp) != 1 ||
+ temp > MAX_TIME_INTERVAL) {
+ pam_syslog(pamh, LOG_ERR,
+ "Bad number supplied for fail_interval argument");
+ } else {
+ opts->fail_interval = temp;
+ }
+ }
+ else if (strcmp(name, "unlock_time") == 0) {
+ unsigned int temp;
+
+ if (strcmp(value, "never") == 0) {
+ opts->unlock_time = 0;
+ }
+ else if (sscanf(value, "%u", &temp) != 1 ||
+ temp > MAX_TIME_INTERVAL) {
+ pam_syslog(pamh, LOG_ERR,
+ "Bad number supplied for unlock_time argument");
+ }
+ else {
+ opts->unlock_time = temp;
+ }
+ }
+ else if (strcmp(name, "root_unlock_time") == 0) {
+ unsigned int temp;
+
+ if (strcmp(value, "never") == 0) {
+ opts->root_unlock_time = 0;
+ }
+ else if (sscanf(value, "%u", &temp) != 1 ||
+ temp > MAX_TIME_INTERVAL) {
+ pam_syslog(pamh, LOG_ERR,
+ "Bad number supplied for root_unlock_time argument");
+ } else {
+ opts->root_unlock_time = temp;
+ }
+ }
+ else if (strcmp(name, "admin_group") == 0) {
+ free(opts->admin_group);
+ opts->admin_group = strdup(value);
+ if (opts->admin_group == NULL) {
+ opts->fatal_error = 1;
+ pam_syslog(pamh, LOG_CRIT, "Error allocating memory: %m");
+ }
+ }
+ else if (strcmp(name, "even_deny_root") == 0) {
+ opts->flags |= FAILLOCK_FLAG_DENY_ROOT;
+ }
+ else if (strcmp(name, "audit") == 0) {
+ opts->flags |= FAILLOCK_FLAG_AUDIT;
+ }
+ else if (strcmp(name, "silent") == 0) {
+ opts->flags |= FAILLOCK_FLAG_SILENT;
+ }
+ else if (strcmp(name, "no_log_info") == 0) {
+ opts->flags |= FAILLOCK_FLAG_NO_LOG_INFO;
+ }
+ else if (strcmp(name, "local_users_only") == 0) {
+ opts->flags |= FAILLOCK_FLAG_LOCAL_ONLY;
+ }
+ else if (strcmp(name, "nodelay") == 0) {
+ opts->flags |= FAILLOCK_FLAG_NO_DELAY;
+ }
+ else {
+ pam_syslog(pamh, LOG_ERR, "Unknown option: %s", name);
+ }
+}
+
+static int
+check_local_user (pam_handle_t *pamh, const char *user)
+{
+ return pam_modutil_check_user_in_passwd(pamh, user, NULL) == PAM_SUCCESS;
+}
+
+static int
+get_pam_user(pam_handle_t *pamh, struct options *opts)
+{
+ const char *user;
+ int rv;
+ struct passwd *pwd;
+
+ if ((rv=pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS) {
+ return rv == PAM_CONV_AGAIN ? PAM_INCOMPLETE : rv;
+ }
+
+ if (*user == '\0') {
+ return PAM_IGNORE;
+ }
+
+ if ((pwd=pam_modutil_getpwnam(pamh, user)) == NULL) {
+ if (opts->flags & FAILLOCK_FLAG_AUDIT) {
+ pam_syslog(pamh, LOG_NOTICE, "User unknown: %s", user);
+ }
+ else {
+ pam_syslog(pamh, LOG_NOTICE, "User unknown");
+ }
+ return PAM_IGNORE;
+ }
+ opts->user = user;
+ opts->uid = pwd->pw_uid;
+
+ if (pwd->pw_uid == 0) {
+ opts->is_admin = 1;
+ return PAM_SUCCESS;
+ }
+
+ if (opts->admin_group && *opts->admin_group) {
+ opts->is_admin = pam_modutil_user_in_group_uid_nam(pamh,
+ pwd->pw_uid, opts->admin_group);
+ }
+
+ return PAM_SUCCESS;
+}
+
+static int
+check_tally(pam_handle_t *pamh, struct options *opts, struct tally_data *tallies, int *fd)
+{
+ int tfd;
+ unsigned int i;
+ uint64_t latest_time;
+ int failures;
+
+ opts->now = time(NULL);
+
+ tfd = open_tally(opts->dir, opts->user, opts->uid, 0);
+
+ *fd = tfd;
+
+ if (tfd == -1) {
+ if (errno == EACCES || errno == ENOENT) {
+ return PAM_SUCCESS;
+ }
+ pam_syslog(pamh, LOG_ERR, "Error opening the tally file for %s: %m", opts->user);
+ return PAM_SYSTEM_ERR;
+ }
+
+ if (read_tally(tfd, tallies) != 0) {
+ pam_syslog(pamh, LOG_ERR, "Error reading the tally file for %s: %m", opts->user);
+ return PAM_SYSTEM_ERR;
+ }
+
+ if (opts->is_admin && !(opts->flags & FAILLOCK_FLAG_DENY_ROOT)) {
+ return PAM_SUCCESS;
+ }
+
+ latest_time = 0;
+ for (i = 0; i < tallies->count; i++) {
+ if ((tallies->records[i].status & TALLY_STATUS_VALID) &&
+ tallies->records[i].time > latest_time)
+ latest_time = tallies->records[i].time;
+ }
+
+ opts->latest_time = latest_time;
+
+ failures = 0;
+ for (i = 0; i < tallies->count; i++) {
+ if ((tallies->records[i].status & TALLY_STATUS_VALID) &&
+ latest_time - tallies->records[i].time < opts->fail_interval) {
+ ++failures;
+ }
+ }
+
+ opts->failures = failures;
+
+ if (opts->deny && failures >= opts->deny) {
+ if ((!opts->is_admin && opts->unlock_time && latest_time + opts->unlock_time < opts->now) ||
+ (opts->is_admin && opts->root_unlock_time && latest_time + opts->root_unlock_time < opts->now)) {
+#ifdef HAVE_LIBAUDIT
+ if (opts->action != FAILLOCK_ACTION_PREAUTH) { /* do not audit in preauth */
+ char buf[64];
+ int audit_fd;
+ const void *rhost = NULL, *tty = NULL;
+
+ audit_fd = audit_open();
+ /* If there is an error & audit support is in the kernel report error */
+ if ((audit_fd < 0) && !(errno == EINVAL || errno == EPROTONOSUPPORT ||
+ errno == EAFNOSUPPORT))
+ return PAM_SYSTEM_ERR;
+
+ (void)pam_get_item(pamh, PAM_TTY, &tty);
+ (void)pam_get_item(pamh, PAM_RHOST, &rhost);
+ snprintf(buf, sizeof(buf), "pam_faillock uid=%u ", opts->uid);
+ audit_log_user_message(audit_fd, AUDIT_RESP_ACCT_UNLOCK_TIMED, buf,
+ rhost, NULL, tty, 1);
+ }
+#endif
+ opts->flags |= FAILLOCK_FLAG_UNLOCKED;
+ return PAM_SUCCESS;
+ }
+ return PAM_AUTH_ERR;
+ }
+ return PAM_SUCCESS;
+}
+
+static void
+reset_tally(pam_handle_t *pamh, struct options *opts, int *fd)
+{
+ int rv;
+
+ if (*fd == -1) {
+ *fd = open_tally(opts->dir, opts->user, opts->uid, 1);
+ }
+ else {
+ while ((rv=ftruncate(*fd, 0)) == -1 && errno == EINTR);
+ if (rv == -1) {
+ pam_syslog(pamh, LOG_ERR, "Error clearing the tally file for %s: %m", opts->user);
+ }
+ }
+}
+
+static int
+write_tally(pam_handle_t *pamh, struct options *opts, struct tally_data *tallies, int *fd)
+{
+ struct tally *records;
+ unsigned int i;
+ int failures;
+ unsigned int oldest;
+ uint64_t oldtime;
+ const void *source = NULL;
+
+ if (*fd == -1) {
+ *fd = open_tally(opts->dir, opts->user, opts->uid, 1);
+ }
+ if (*fd == -1) {
+ if (errno == EACCES) {
+ return PAM_SUCCESS;
+ }
+ pam_syslog(pamh, LOG_ERR, "Error opening the tally file for %s: %m", opts->user);
+ return PAM_SYSTEM_ERR;
+ }
+
+ oldtime = 0;
+ oldest = 0;
+ failures = 0;
+
+ for (i = 0; i < tallies->count; ++i) {
+ if (oldtime == 0 || tallies->records[i].time < oldtime) {
+ oldtime = tallies->records[i].time;
+ oldest = i;
+ }
+ if (opts->flags & FAILLOCK_FLAG_UNLOCKED ||
+ opts->now - tallies->records[i].time >= opts->fail_interval ) {
+ tallies->records[i].status &= ~TALLY_STATUS_VALID;
+ } else {
+ ++failures;
+ }
+ }
+
+ if (oldest >= tallies->count || (tallies->records[oldest].status & TALLY_STATUS_VALID)) {
+ oldest = tallies->count;
+
+ if ((records=realloc(tallies->records, (oldest+1) * sizeof (*tallies->records))) == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "Error allocating memory for tally records: %m");
+ return PAM_BUF_ERR;
+ }
+
+ ++tallies->count;
+ tallies->records = records;
+ }
+
+ memset(&tallies->records[oldest], 0, sizeof (*tallies->records));
+
+ tallies->records[oldest].status = TALLY_STATUS_VALID;
+ if (pam_get_item(pamh, PAM_RHOST, &source) != PAM_SUCCESS || source == NULL) {
+ if (pam_get_item(pamh, PAM_TTY, &source) != PAM_SUCCESS || source == NULL) {
+ if (pam_get_item(pamh, PAM_SERVICE, &source) != PAM_SUCCESS || source == NULL) {
+ source = "";
+ }
+ }
+ else {
+ tallies->records[oldest].status |= TALLY_STATUS_TTY;
+ }
+ }
+ else {
+ tallies->records[oldest].status |= TALLY_STATUS_RHOST;
+ }
+
+ strncpy(tallies->records[oldest].source, source, sizeof(tallies->records[oldest].source));
+ /* source does not have to be null terminated */
+
+ tallies->records[oldest].time = opts->now;
+
+ ++failures;
+
+ if (opts->deny && failures == opts->deny) {
+#ifdef HAVE_LIBAUDIT
+ char buf[64];
+ int audit_fd;
+
+ audit_fd = audit_open();
+ /* If there is an error & audit support is in the kernel report error */
+ if ((audit_fd < 0) && !(errno == EINVAL || errno == EPROTONOSUPPORT ||
+ errno == EAFNOSUPPORT))
+ return PAM_SYSTEM_ERR;
+
+ snprintf(buf, sizeof(buf), "pam_faillock uid=%u ", opts->uid);
+ audit_log_user_message(audit_fd, AUDIT_ANOM_LOGIN_FAILURES, buf,
+ NULL, NULL, NULL, 1);
+
+ if (!opts->is_admin || (opts->flags & FAILLOCK_FLAG_DENY_ROOT)) {
+ audit_log_user_message(audit_fd, AUDIT_RESP_ACCT_LOCK, buf,
+ NULL, NULL, NULL, 1);
+ }
+ close(audit_fd);
+#endif
+ if (!(opts->flags & FAILLOCK_FLAG_NO_LOG_INFO)) {
+ pam_syslog(pamh, LOG_INFO, "Consecutive login failures for user %s account temporarily locked",
+ opts->user);
+ }
+ }
+
+ if (update_tally(*fd, tallies) == 0)
+ return PAM_SUCCESS;
+
+ return PAM_SYSTEM_ERR;
+}
+
+static void
+faillock_message(pam_handle_t *pamh, struct options *opts)
+{
+ int64_t left;
+
+ if (!(opts->flags & FAILLOCK_FLAG_SILENT)) {
+ if (opts->is_admin) {
+ left = opts->latest_time + opts->root_unlock_time - opts->now;
+ }
+ else {
+ left = opts->latest_time + opts->unlock_time - opts->now;
+ }
+
+ pam_info(pamh, _("The account is locked due to %u failed logins."),
+ (unsigned int)opts->failures);
+ if (left > 0) {
+ left = (left + 59)/60; /* minutes */
+
+#if defined HAVE_DNGETTEXT && defined ENABLE_NLS
+ pam_info(
+ pamh,
+ dngettext(PACKAGE,
+ "(%d minute left to unlock)",
+ "(%d minutes left to unlock)",
+ (int)left),
+ (int)left);
+#else
+ if (left == 1)
+ pam_info(pamh, _("(%d minute left to unlock)"), (int)left);
+ else
+ /* TRANSLATORS: only used if dngettext is not supported. */
+ pam_info(pamh, _("(%d minutes left to unlock)"), (int)left);
+#endif
+ }
+ }
+}
+
+static void
+tally_cleanup(struct tally_data *tallies, int fd)
+{
+ if (fd != -1) {
+ close(fd);
+ }
+
+ free(tallies->records);
+}
+
+static void
+opts_cleanup(struct options *opts)
+{
+ free(opts->dir);
+ free(opts->admin_group);
+}
+
+/*---------------------------------------------------------------------*/
+
+int
+pam_sm_authenticate(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ struct options opts;
+ int rv, fd = -1;
+ struct tally_data tallies;
+
+ memset(&tallies, 0, sizeof(tallies));
+
+ rv = args_parse(pamh, argc, argv, flags, &opts);
+ if (rv != PAM_SUCCESS)
+ goto err;
+
+ if (!(opts.flags & FAILLOCK_FLAG_NO_DELAY)) {
+ pam_fail_delay(pamh, 2000000); /* 2 sec delay on failure */
+ }
+
+ if ((rv=get_pam_user(pamh, &opts)) != PAM_SUCCESS) {
+ goto err;
+ }
+
+ if (!(opts.flags & FAILLOCK_FLAG_LOCAL_ONLY) ||
+ check_local_user (pamh, opts.user) != 0) {
+ switch (opts.action) {
+ case FAILLOCK_ACTION_PREAUTH:
+ rv = check_tally(pamh, &opts, &tallies, &fd);
+ if (rv == PAM_AUTH_ERR && !(opts.flags & FAILLOCK_FLAG_SILENT)) {
+ faillock_message(pamh, &opts);
+ }
+ break;
+
+ case FAILLOCK_ACTION_AUTHSUCC:
+ rv = check_tally(pamh, &opts, &tallies, &fd);
+ if (rv == PAM_SUCCESS) {
+ reset_tally(pamh, &opts, &fd);
+ }
+ break;
+
+ case FAILLOCK_ACTION_AUTHFAIL:
+ rv = check_tally(pamh, &opts, &tallies, &fd);
+ if (rv == PAM_SUCCESS) {
+ rv = PAM_IGNORE; /* this return value should be ignored */
+ write_tally(pamh, &opts, &tallies, &fd);
+ }
+ break;
+ }
+ }
+
+ tally_cleanup(&tallies, fd);
+
+err:
+ opts_cleanup(&opts);
+
+ return rv;
+}
+
+/*---------------------------------------------------------------------*/
+
+int
+pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
+
+/*---------------------------------------------------------------------*/
+
+int
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ struct options opts;
+ int rv, fd = -1;
+ struct tally_data tallies;
+
+ memset(&tallies, 0, sizeof(tallies));
+
+ rv = args_parse(pamh, argc, argv, flags, &opts);
+
+ if (rv != PAM_SUCCESS)
+ goto err;
+
+ opts.action = FAILLOCK_ACTION_AUTHSUCC;
+
+ if ((rv=get_pam_user(pamh, &opts)) != PAM_SUCCESS) {
+ goto err;
+ }
+
+ if (!(opts.flags & FAILLOCK_FLAG_LOCAL_ONLY) ||
+ check_local_user (pamh, opts.user) != 0) {
+ check_tally(pamh, &opts, &tallies, &fd); /* for auditing */
+ reset_tally(pamh, &opts, &fd);
+ }
+
+ tally_cleanup(&tallies, fd);
+
+err:
+ opts_cleanup(&opts);
+
+ return rv;
+}
+
+/*-----------------------------------------------------------------------*/
diff --git a/modules/pam_faillock/tst-pam_faillock b/modules/pam_faillock/tst-pam_faillock
new file mode 100755
index 0000000..ec454c2
--- /dev/null
+++ b/modules/pam_faillock/tst-pam_faillock
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_faillock.so
diff --git a/modules/pam_filter/Makefile.am b/modules/pam_filter/Makefile.am
new file mode 100644
index 0000000..4d75e84
--- /dev/null
+++ b/modules/pam_filter/Makefile.am
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2005, 2006, 2007, 2009 Thorsten Kukuk <kukuk@thkukuk.de>
+#
+
+SUBDIRS = upperLOWER
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_filter.8
+endif
+XMLS = README.xml pam_filter.8.xml
+dist_check_SCRIPTS = tst-pam_filter
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+include_HEADERS=pam_filter.h
+pam_filter_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+securelib_LTLIBRARIES = pam_filter.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_filter/Makefile.in b/modules/pam_filter/Makefile.in
new file mode 100644
index 0000000..76b1765
--- /dev/null
+++ b/modules/pam_filter/Makefile.in
@@ -0,0 +1,1294 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2007, 2009 Thorsten Kukuk <kukuk@thkukuk.de>
+#
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_filter
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(include_HEADERS) \
+ $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)" \
+ "$(DESTDIR)$(includedir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_filter_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_filter_la_SOURCES = pam_filter.c
+pam_filter_la_OBJECTS = pam_filter.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_filter.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_filter.c
+DIST_SOURCES = pam_filter.c
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+ ctags-recursive dvi-recursive html-recursive info-recursive \
+ install-data-recursive install-dvi-recursive \
+ install-exec-recursive install-html-recursive \
+ install-info-recursive install-pdf-recursive \
+ install-ps-recursive install-recursive installcheck-recursive \
+ installdirs-recursive pdf-recursive ps-recursive \
+ tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+HEADERS = $(include_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+ $(RECURSIVE_TARGETS) \
+ $(RECURSIVE_CLEAN_TARGETS) \
+ $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+ check recheck distdir distdir-am
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+DIST_SUBDIRS = $(SUBDIRS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+ dir0=`pwd`; \
+ sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+ sed_rest='s,^[^/]*/*,,'; \
+ sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+ sed_butlast='s,/*[^/]*$$,,'; \
+ while test -n "$$dir1"; do \
+ first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+ if test "$$first" != "."; then \
+ if test "$$first" = ".."; then \
+ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+ else \
+ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+ if test "$$first2" = "$$first"; then \
+ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+ else \
+ dir2="../$$dir2"; \
+ fi; \
+ dir0="$$dir0"/"$$first"; \
+ fi; \
+ fi; \
+ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+ done; \
+ reldir="$$dir2"
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUBDIRS = upperLOWER
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_filter.8
+XMLS = README.xml pam_filter.8.xml
+dist_check_SCRIPTS = tst-pam_filter
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+include_HEADERS = pam_filter.h
+pam_filter_la_LIBADD = $(top_builddir)/libpam/libpam.la
+securelib_LTLIBRARIES = pam_filter.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_filter/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_filter/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_filter.la: $(pam_filter_la_OBJECTS) $(pam_filter_la_DEPENDENCIES) $(EXTRA_pam_filter_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_filter_la_OBJECTS) $(pam_filter_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_filter.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+# (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+ @fail=; \
+ if $(am__make_keepgoing); then \
+ failcom='fail=yes'; \
+ else \
+ failcom='exit 1'; \
+ fi; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_filter.log: tst-pam_filter
+ @p='tst-pam_filter'; \
+ b='tst-pam_filter'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+ @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
+ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+ $(am__relativize); \
+ new_distdir=$$reldir; \
+ dir1=$$subdir; dir2="$(top_distdir)"; \
+ $(am__relativize); \
+ new_top_distdir=$$reldir; \
+ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+ ($(am__cd) $$subdir && \
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$$new_top_distdir" \
+ distdir="$$new_distdir" \
+ am__remove_distdir=: \
+ am__skip_length_check=: \
+ am__skip_mode_fix=: \
+ distdir) \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-recursive
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA) $(HEADERS)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(includedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -f ./$(DEPDIR)/pam_filter.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-includeHEADERS install-man \
+ install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f ./$(DEPDIR)/pam_filter.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-includeHEADERS uninstall-man \
+ uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: $(am__recursive_targets) check-am install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
+ am--depfiles check check-TESTS check-am clean clean-generic \
+ clean-libtool clean-securelibLTLIBRARIES cscopelist-am ctags \
+ ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am \
+ install-includeHEADERS install-info install-info-am \
+ install-man install-man8 install-pdf install-pdf-am install-ps \
+ install-ps-am install-securelibLTLIBRARIES install-strip \
+ installcheck installcheck-am installdirs installdirs-am \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am recheck tags tags-am uninstall \
+ uninstall-am uninstall-includeHEADERS uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_filter/README b/modules/pam_filter/README
new file mode 100644
index 0000000..2978e54
--- /dev/null
+++ b/modules/pam_filter/README
@@ -0,0 +1,78 @@
+pam_filter — PAM filter module
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+This module is intended to be a platform for providing access to all of the
+input/output that passes between the user and the application. It is only
+suitable for tty-based and (stdin/stdout) applications.
+
+To function this module requires filters to be installed on the system. The
+single filter provided with the module simply transposes upper and lower case
+letters in the input and output streams. (This can be very annoying and is not
+kind to termcap based editors).
+
+Each component of the module has the potential to invoke the desired filter.
+The filter is always execv(2) with the privilege of the calling application and
+not that of the user. For this reason it cannot usually be killed by the user
+without closing their session.
+
+OPTIONS
+
+debug
+
+ Print debug information.
+
+new_term
+
+ The default action of the filter is to set the PAM_TTY item to indicate the
+ terminal that the user is using to connect to the application. This
+ argument indicates that the filter should set PAM_TTY to the filtered
+ pseudo-terminal.
+
+non_term
+
+ don't try to set the PAM_TTY item.
+
+runX
+
+ In order that the module can invoke a filter it should know when to invoke
+ it. This argument is required to tell the filter when to do this.
+
+ Permitted values for X are 1 and 2. These indicate the precise time that
+ the filter is to be run. To understand this concept it will be useful to
+ have read the pam(3) manual page. Basically, for each management group
+ there are up to two ways of calling the module's functions. In the case of
+ the authentication and session components there are actually two separate
+ functions. For the case of authentication, these functions are
+ pam_authenticate(3) and pam_setcred(3), here run1 means run the filter from
+ the pam_authenticate function and run2 means run the filter from
+ pam_setcred. In the case of the session modules, run1 implies that the
+ filter is invoked at the pam_open_session(3) stage, and run2 for
+ pam_close_session(3).
+
+ For the case of the account component. Either run1 or run2 may be used.
+
+ For the case of the password component, run1 is used to indicate that the
+ filter is run on the first occasion of pam_chauthtok(3) (the
+ PAM_PRELIM_CHECK phase) and run2 is used to indicate that the filter is run
+ on the second occasion (the PAM_UPDATE_AUTHTOK phase).
+
+filter
+
+ The full pathname of the filter to be run and any command line arguments
+ that the filter might expect.
+
+EXAMPLES
+
+Add the following line to /etc/pam.d/login to see how to configure login to
+transpose upper and lower case letters once the user has logged in:
+
+ session required pam_filter.so run1 /lib/security/pam_filter/upperLOWER
+
+
+AUTHOR
+
+pam_filter was written by Andrew G. Morgan <morgan@kernel.org>.
+
diff --git a/modules/pam_filter/README.xml b/modules/pam_filter/README.xml
new file mode 100644
index 0000000..b76cb74
--- /dev/null
+++ b/modules/pam_filter/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_filter.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_filter.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_filter-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_filter.8.xml" xpointer='xpointer(//refsect1[@id = "pam_filter-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_filter.8.xml" xpointer='xpointer(//refsect1[@id = "pam_filter-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_filter.8.xml" xpointer='xpointer(//refsect1[@id = "pam_filter-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_filter.8.xml" xpointer='xpointer(//refsect1[@id = "pam_filter-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_filter/pam_filter.8 b/modules/pam_filter/pam_filter.8
new file mode 100644
index 0000000..d804faf
--- /dev/null
+++ b/modules/pam_filter/pam_filter.8
@@ -0,0 +1,172 @@
+'\" t
+.\" Title: pam_filter
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_FILTER" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_filter \- PAM filter module
+.SH "SYNOPSIS"
+.HP \w'\fBpam_filter\&.so\fR\ 'u
+\fBpam_filter\&.so\fR [debug] [new_term] [non_term] run1|run2 \fIfilter\fR [\fI\&.\&.\&.\fR]
+.SH "DESCRIPTION"
+.PP
+This module is intended to be a platform for providing access to all of the input/output that passes between the user and the application\&. It is only suitable for tty\-based and (stdin/stdout) applications\&.
+.PP
+To function this module requires
+\fIfilters\fR
+to be installed on the system\&. The single filter provided with the module simply transposes upper and lower case letters in the input and output streams\&. (This can be very annoying and is not kind to termcap based editors)\&.
+.PP
+Each component of the module has the potential to invoke the desired filter\&. The filter is always
+\fBexecv\fR(2)
+with the privilege of the calling application and
+\fInot\fR
+that of the user\&. For this reason it cannot usually be killed by the user without closing their session\&.
+.SH "OPTIONS"
+.PP
+.PP
+\fBdebug\fR
+.RS 4
+Print debug information\&.
+.RE
+.PP
+\fBnew_term\fR
+.RS 4
+The default action of the filter is to set the
+\fIPAM_TTY\fR
+item to indicate the terminal that the user is using to connect to the application\&. This argument indicates that the filter should set
+\fIPAM_TTY\fR
+to the filtered pseudo\-terminal\&.
+.RE
+.PP
+\fBnon_term\fR
+.RS 4
+don\*(Aqt try to set the
+\fIPAM_TTY\fR
+item\&.
+.RE
+.PP
+\fBrunX\fR
+.RS 4
+In order that the module can invoke a filter it should know when to invoke it\&. This argument is required to tell the filter when to do this\&.
+.sp
+Permitted values for
+\fIX\fR
+are
+\fI1\fR
+and
+\fI2\fR\&. These indicate the precise time that the filter is to be run\&. To understand this concept it will be useful to have read the
+\fBpam\fR(3)
+manual page\&. Basically, for each management group there are up to two ways of calling the module\*(Aqs functions\&. In the case of the
+\fIauthentication\fR
+and
+\fIsession\fR
+components there are actually two separate functions\&. For the case of authentication, these functions are
+\fBpam_authenticate\fR(3)
+and
+\fBpam_setcred\fR(3), here
+\fBrun1\fR
+means run the filter from the
+\fBpam_authenticate\fR
+function and
+\fBrun2\fR
+means run the filter from
+\fBpam_setcred\fR\&. In the case of the session modules,
+\fIrun1\fR
+implies that the filter is invoked at the
+\fBpam_open_session\fR(3)
+stage, and
+\fIrun2\fR
+for
+\fBpam_close_session\fR(3)\&.
+.sp
+For the case of the account component\&. Either
+\fIrun1\fR
+or
+\fIrun2\fR
+may be used\&.
+.sp
+For the case of the password component,
+\fIrun1\fR
+is used to indicate that the filter is run on the first occasion of
+\fBpam_chauthtok\fR(3)
+(the
+\fIPAM_PRELIM_CHECK\fR
+phase) and
+\fIrun2\fR
+is used to indicate that the filter is run on the second occasion (the
+\fIPAM_UPDATE_AUTHTOK\fR
+phase)\&.
+.RE
+.PP
+\fBfilter\fR
+.RS 4
+The full pathname of the filter to be run and any command line arguments that the filter might expect\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+All module types (\fBauth\fR,
+\fBaccount\fR,
+\fBpassword\fR
+and
+\fBsession\fR) are provided\&.
+.SH "RETURN VALUES"
+.PP
+.PP
+PAM_SUCCESS
+.RS 4
+The new filter was set successfully\&.
+.RE
+.PP
+PAM_ABORT
+.RS 4
+Critical error, immediate abort\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Add the following line to
+/etc/pam\&.d/login
+to see how to configure login to transpose upper and lower case letters once the user has logged in:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ session required pam_filter\&.so run1 /lib/security/pam_filter/upperLOWER
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.PP
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_filter was written by Andrew G\&. Morgan <morgan@kernel\&.org>\&.
diff --git a/modules/pam_filter/pam_filter.8.xml b/modules/pam_filter/pam_filter.8.xml
new file mode 100644
index 0000000..7309c35
--- /dev/null
+++ b/modules/pam_filter/pam_filter.8.xml
@@ -0,0 +1,261 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_filter">
+
+ <refmeta>
+ <refentrytitle>pam_filter</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_filter-name">
+ <refname>pam_filter</refname>
+ <refpurpose>PAM filter module</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_filter-cmdsynopsis">
+ <command>pam_filter.so</command>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ new_term
+ </arg>
+ <arg choice="opt">
+ non_term
+ </arg>
+ <arg choice="plain">
+ run1|run2
+ </arg>
+ <arg choice="plain">
+ <replaceable>filter</replaceable>
+ </arg>
+ <arg choice="opt">
+ <replaceable>...</replaceable>
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_filter-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ This module is intended to be a platform for providing access to all
+ of the input/output that passes between the user and the application.
+ It is only suitable for tty-based and (stdin/stdout) applications.
+ </para>
+ <para>
+ To function this module requires <emphasis>filters</emphasis> to be
+ installed on the system.
+ The single filter provided with the module simply transposes upper and
+ lower case letters in the input and output streams. (This can be very
+ annoying and is not kind to termcap based editors).
+ </para>
+ <para>
+ Each component of the module has the potential to invoke the
+ desired filter. The filter is always
+ <citerefentry>
+ <refentrytitle>execv</refentrytitle><manvolnum>2</manvolnum>
+ </citerefentry> with the privilege of the calling application
+ and <emphasis>not</emphasis> that of the user. For this reason it
+ cannot usually be killed by the user without closing their session.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_filter-options">
+
+ <title>OPTIONS</title>
+ <para>
+ <variablelist>
+
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Print debug information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>new_term</option>
+ </term>
+ <listitem>
+ <para>
+ The default action of the filter is to set the
+ <emphasis>PAM_TTY</emphasis> item to indicate the
+ terminal that the user is using to connect to the
+ application. This argument indicates that the filter
+ should set <emphasis>PAM_TTY</emphasis> to the filtered
+ pseudo-terminal.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>non_term</option>
+ </term>
+ <listitem>
+ <para>
+ don't try to set the <emphasis>PAM_TTY</emphasis> item.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>runX</option>
+ </term>
+ <listitem>
+ <para>
+ In order that the module can invoke a filter it should
+ know when to invoke it. This argument is required to tell
+ the filter when to do this.
+ </para>
+ <para>
+ Permitted values for <emphasis>X</emphasis> are
+ <emphasis>1</emphasis> and <emphasis>2</emphasis>. These
+ indicate the precise time that the filter is to be run.
+ To understand this concept it will be useful to have read
+ the <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry> manual page.
+ Basically, for each management group there are up to two ways
+ of calling the module's functions.
+ In the case of the <emphasis>authentication</emphasis> and
+ <emphasis>session</emphasis> components there are actually
+ two separate functions. For the case of authentication, these
+ functions are
+ <citerefentry>
+ <refentrytitle>pam_authenticate</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry> and
+ <citerefentry>
+ <refentrytitle>pam_setcred</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>, here <option>run1</option> means run the
+ filter from the <function>pam_authenticate</function> function
+ and <option>run2</option> means run the filter from
+ <function>pam_setcred</function>. In the case of the
+ session modules, <emphasis>run1</emphasis> implies
+ that the filter is invoked at the
+ <citerefentry>
+ <refentrytitle>pam_open_session</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry> stage, and <emphasis>run2</emphasis> for
+ <citerefentry>
+ <refentrytitle>pam_close_session</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>.
+ </para>
+ <para>
+ For the case of the account component. Either
+ <emphasis>run1</emphasis> or <emphasis>run2</emphasis>
+ may be used.
+ </para>
+ <para>
+ For the case of the password component, <emphasis>run1</emphasis>
+ is used to indicate that the filter is run on the first
+ occasion of
+ <citerefentry>
+ <refentrytitle>pam_chauthtok</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry> (the <emphasis>PAM_PRELIM_CHECK</emphasis>
+ phase) and <emphasis>run2</emphasis> is used to indicate
+ that the filter is run on the second occasion (the
+ <emphasis>PAM_UPDATE_AUTHTOK</emphasis> phase).
+
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>filter</option>
+ </term>
+ <listitem>
+ <para>
+ The full pathname of the filter to be run and any command line
+ arguments that the filter might expect.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_filter-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ All module types (<option>auth</option>, <option>account</option>,
+ <option>password</option> and <option>session</option>) are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_filter-return_values'>
+ <title>RETURN VALUES</title>
+ <para>
+ <variablelist>
+
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ The new filter was set successfully.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_ABORT</term>
+ <listitem>
+ <para>
+ Critical error, immediate abort.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_filter-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ Add the following line to <filename>/etc/pam.d/login</filename> to
+ see how to configure login to transpose upper and lower case letters
+ once the user has logged in:
+
+ <programlisting>
+ session required pam_filter.so run1 /lib/security/pam_filter/upperLOWER
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_filter-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_filter-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_filter was written by Andrew G. Morgan &lt;morgan@kernel.org&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_filter/pam_filter.c b/modules/pam_filter/pam_filter.c
new file mode 100644
index 0000000..6e6def3
--- /dev/null
+++ b/modules/pam_filter/pam_filter.c
@@ -0,0 +1,714 @@
+/*
+ * pam_filter module
+ *
+ * written by Andrew Morgan <morgan@transmeta.com> with much help from
+ * Richard Stevens' UNIX Network Programming book.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+
+#include <signal.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_ext.h>
+#include "pam_filter.h"
+
+/* ------ some tokens used for convenience throughout this file ------- */
+
+#define FILTER_DEBUG 01
+#define FILTER_RUN1 02
+#define FILTER_RUN2 04
+#define NEW_TERM 010
+#define NON_TERM 020
+
+/* -------------------------------------------------------------------- */
+
+/* log errors */
+
+#include <stdarg.h>
+
+#define DEV_PTMX "/dev/ptmx"
+
+static int
+master (void)
+{
+ int fd;
+
+ if ((fd = open(DEV_PTMX, O_RDWR)) >= 0) {
+ return fd;
+ }
+
+ return -1;
+}
+
+static int process_args(pam_handle_t *pamh
+ , int argc, const char **argv, const char *type
+ , char ***evp, const char **filtername)
+{
+ int ctrl=0;
+
+ while (argc-- > 0) {
+ if (strcmp("debug",*argv) == 0) {
+ ctrl |= FILTER_DEBUG;
+ } else if (strcmp("new_term",*argv) == 0) {
+ ctrl |= NEW_TERM;
+ } else if (strcmp("non_term",*argv) == 0) {
+ ctrl |= NON_TERM;
+ } else if (strcmp("run1",*argv) == 0) {
+ ctrl |= FILTER_RUN1;
+ if (argc <= 0) {
+ pam_syslog(pamh, LOG_ERR, "no run filter supplied");
+ } else
+ break;
+ } else if (strcmp("run2",*argv) == 0) {
+ ctrl |= FILTER_RUN2;
+ if (argc <= 0) {
+ pam_syslog(pamh, LOG_ERR, "no run filter supplied");
+ } else
+ break;
+ } else {
+ pam_syslog(pamh, LOG_ERR, "unrecognized option: %s", *argv);
+ }
+ ++argv; /* step along list */
+ }
+
+ if (argc < 0) {
+ /* there was no reference to a filter */
+ *filtername = NULL;
+ *evp = NULL;
+ } else {
+ char **levp;
+ const char *user = NULL;
+ const void *tmp;
+ int i,size, retval;
+
+ *filtername = *++argv;
+ if (ctrl & FILTER_DEBUG) {
+ pam_syslog(pamh, LOG_DEBUG, "will run filter %s", *filtername);
+ }
+
+ levp = (char **) malloc(5*sizeof(char *));
+ if (levp == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "no memory for environment of filter");
+ return -1;
+ }
+
+ /* the "ARGS" variable */
+
+#define ARGS_NAME "ARGS="
+#define ARGS_OFFSET (sizeof(ARGS_NAME) - 1)
+
+ size = sizeof(ARGS_NAME);
+
+ for (i=0; i<argc; ++i) {
+ size += strlen(argv[i]) + (i != 0);
+ }
+
+ levp[0] = malloc(size);
+ if (levp[0] == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "no memory for filter arguments");
+ free(levp);
+ return -1;
+ }
+
+ strcpy(levp[0], ARGS_NAME);
+ size = ARGS_OFFSET;
+ for (i=0; i<argc; ++i) {
+ if (i)
+ levp[0][size++] = ' ';
+ strcpy(levp[0]+size, argv[i]);
+ size += strlen(argv[i]);
+ }
+
+ /* the "SERVICE" variable */
+
+#define SERVICE_NAME "SERVICE="
+#define SERVICE_OFFSET (sizeof(SERVICE_NAME) - 1)
+
+ retval = pam_get_item(pamh, PAM_SERVICE, &tmp);
+ if (retval != PAM_SUCCESS || tmp == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "service name not found");
+ if (levp) {
+ free(levp[0]);
+ free(levp);
+ }
+ return -1;
+ }
+ size = SERVICE_OFFSET+strlen(tmp);
+
+ levp[1] = (char *) malloc(size+1);
+ if (levp[1] == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "no memory for service name");
+ if (levp) {
+ free(levp[0]);
+ free(levp);
+ }
+ return -1;
+ }
+
+ strcpy(levp[1], SERVICE_NAME);
+ strcpy(levp[1]+SERVICE_OFFSET, tmp);
+ levp[1][size] = '\0'; /* <NUL> terminate */
+
+ /* the "USER" variable */
+
+#define USER_NAME "USER="
+#define USER_OFFSET (sizeof(USER_NAME) - 1)
+
+ if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS) {
+ user = "<unknown>";
+ }
+ size = USER_OFFSET+strlen(user);
+
+ levp[2] = (char *) malloc(size+1);
+ if (levp[2] == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "no memory for user's name");
+ if (levp) {
+ free(levp[1]);
+ free(levp[0]);
+ free(levp);
+ }
+ return -1;
+ }
+
+ strcpy(levp[2], USER_NAME);
+ strcpy(levp[2]+USER_OFFSET, user);
+ levp[2][size] = '\0'; /* <NUL> terminate */
+
+ /* the "USER" variable */
+
+#define TYPE_NAME "TYPE="
+#define TYPE_OFFSET (sizeof(TYPE_NAME) - 1)
+
+ size = TYPE_OFFSET+strlen(type);
+
+ levp[3] = (char *) malloc(size+1);
+ if (levp[3] == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "no memory for type");
+ if (levp) {
+ free(levp[2]);
+ free(levp[1]);
+ free(levp[0]);
+ free(levp);
+ }
+ return -1;
+ }
+
+ strcpy(levp[3], TYPE_NAME);
+ strcpy(levp[3]+TYPE_OFFSET, type);
+ levp[3][size] = '\0'; /* <NUL> terminate */
+
+ levp[4] = NULL; /* end list */
+
+ *evp = levp;
+ }
+
+ if ((ctrl & FILTER_DEBUG) && *filtername) {
+ char **e;
+
+ pam_syslog(pamh, LOG_DEBUG, "filter[%s]: %s", type, *filtername);
+ pam_syslog(pamh, LOG_DEBUG, "environment:");
+ for (e=*evp; e && *e; ++e) {
+ pam_syslog(pamh, LOG_DEBUG, " %s", *e);
+ }
+ }
+
+ return ctrl;
+}
+
+static void free_evp(char *evp[])
+{
+ int i;
+
+ if (evp)
+ for (i=0; i<4; ++i) {
+ if (evp[i])
+ free(evp[i]);
+ }
+ free(evp);
+}
+
+static int
+set_filter (pam_handle_t *pamh, int flags UNUSED, int ctrl,
+ char * const evp[], const char *filtername)
+{
+ int status=-1;
+ char* terminal = NULL;
+ struct termios stored_mode; /* initial terminal mode settings */
+ int fd[2], child=0, child2=0, aterminal;
+
+ if (filtername == NULL || *filtername != '/') {
+ pam_syslog(pamh, LOG_ERR,
+ "filtername not permitted; full pathname required");
+ return PAM_ABORT;
+ }
+
+ if (!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO)) {
+ aterminal = 0;
+ } else {
+ aterminal = 1;
+ }
+
+ if (aterminal) {
+
+ /* open the master pseudo terminal */
+
+ fd[0] = master();
+ if (fd[0] < 0) {
+ pam_syslog(pamh, LOG_CRIT, "no master terminal");
+ return PAM_AUTH_ERR;
+ }
+
+ /* set terminal into raw mode.. remember old mode so that we can
+ revert to it after the child has quit. */
+
+ /* this is termios terminal handling... */
+
+ if ( tcgetattr(STDIN_FILENO, &stored_mode) < 0 ) {
+ pam_syslog(pamh, LOG_CRIT, "couldn't copy terminal mode: %m");
+ /* in trouble, so close down */
+ close(fd[0]);
+ return PAM_ABORT;
+ } else {
+ struct termios t_mode = stored_mode;
+
+ t_mode.c_iflag = 0; /* no input control */
+ t_mode.c_oflag &= ~OPOST; /* no output post processing */
+
+ /* no signals, canonical input, echoing, upper/lower output */
+#ifdef XCASE
+ t_mode.c_lflag &= ~(XCASE);
+#endif
+ t_mode.c_lflag &= ~(ISIG|ICANON|ECHO);
+ t_mode.c_cflag &= ~(CSIZE|PARENB); /* no parity */
+ t_mode.c_cflag |= CS8; /* 8 bit chars */
+
+ t_mode.c_cc[VMIN] = 1; /* number of chars to satisfy a read */
+ t_mode.c_cc[VTIME] = 0; /* 0/10th second for chars */
+
+ if ( tcsetattr(STDIN_FILENO, TCSAFLUSH, &t_mode) < 0 ) {
+ pam_syslog(pamh, LOG_ERR,
+ "couldn't put terminal in RAW mode: %m");
+ close(fd[0]);
+ return PAM_ABORT;
+ }
+
+ /*
+ * NOTE: Unlike the stream socket case here the child
+ * opens the slave terminal as fd[1] *after* the fork...
+ */
+ }
+ } else {
+
+ /*
+ * not a terminal line so just open a stream socket fd[0-1]
+ * both set...
+ */
+
+ if ( socketpair(AF_UNIX, SOCK_STREAM, 0, fd) < 0 ) {
+ pam_syslog(pamh, LOG_ERR, "couldn't open a stream pipe: %m");
+ return PAM_ABORT;
+ }
+ }
+
+ /* start child process */
+
+ if ( (child = fork()) < 0 ) {
+
+ pam_syslog(pamh, LOG_ERR, "first fork failed: %m");
+ if (aterminal) {
+ (void) tcsetattr(STDIN_FILENO, TCSAFLUSH, &stored_mode);
+ close(fd[0]);
+ } else {
+ /* Socket pair */
+ close(fd[0]);
+ close(fd[1]);
+ }
+
+ return PAM_AUTH_ERR;
+ }
+
+ if ( child == 0 ) { /* child process *is* application */
+
+ if (aterminal) {
+
+ /* close the controlling tty */
+
+#if defined(__hpux) && defined(O_NOCTTY)
+ int t = open("/dev/tty", O_RDWR|O_NOCTTY);
+#else
+ int t = open("/dev/tty",O_RDWR);
+ if (t >= 0) {
+ (void) ioctl(t, TIOCNOTTY, NULL);
+ close(t);
+ }
+#endif /* defined(__hpux) && defined(O_NOCTTY) */
+
+ /* make this process it's own process leader */
+ if (setsid() == -1) {
+ pam_syslog(pamh, LOG_ERR,
+ "child cannot become new session: %m");
+ return PAM_ABORT;
+ }
+
+ /* grant slave terminal */
+ if (grantpt (fd[0]) < 0) {
+ pam_syslog(pamh, LOG_ERR, "Cannot grant access to slave terminal");
+ return PAM_ABORT;
+ }
+
+ /* unlock slave terminal */
+ if (unlockpt (fd[0]) < 0) {
+ pam_syslog(pamh, LOG_ERR, "Cannot unlock slave terminal");
+ return PAM_ABORT;
+ }
+
+ /* find slave's name */
+ terminal = ptsname(fd[0]); /* returned value should not be freed */
+
+ if (terminal == NULL) {
+ pam_syslog(pamh, LOG_ERR,
+ "Cannot get the name of the slave terminal: %m");
+ return PAM_ABORT;
+ }
+
+ fd[1] = open(terminal, O_RDWR);
+ close(fd[0]); /* process is the child -- uses line fd[1] */
+
+ if (fd[1] < 0) {
+ pam_syslog(pamh, LOG_ERR,
+ "cannot open slave terminal: %s: %m", terminal);
+ return PAM_ABORT;
+ }
+
+ /* initialize the child's terminal to be the way the
+ parent's was before we set it into RAW mode */
+
+ if ( tcsetattr(fd[1], TCSANOW, &stored_mode) < 0 ) {
+ pam_syslog(pamh, LOG_ERR,
+ "cannot set slave terminal mode: %s: %m", terminal);
+ close(fd[1]);
+ return PAM_ABORT;
+ }
+ } else {
+
+ /* nothing to do for a simple stream socket */
+
+ }
+
+ /* re-assign the stdin/out to fd[1] <- (talks to filter). */
+
+ if ( dup2(fd[1],STDIN_FILENO) != STDIN_FILENO ||
+ dup2(fd[1],STDOUT_FILENO) != STDOUT_FILENO ||
+ dup2(fd[1],STDERR_FILENO) != STDERR_FILENO ) {
+ pam_syslog(pamh, LOG_ERR,
+ "unable to re-assign STDIN/OUT/ERR: %m");
+ close(fd[1]);
+ return PAM_ABORT;
+ }
+
+ /* make sure that file descriptors survive 'exec's */
+
+ if ( fcntl(STDIN_FILENO, F_SETFD, 0) ||
+ fcntl(STDOUT_FILENO,F_SETFD, 0) ||
+ fcntl(STDERR_FILENO,F_SETFD, 0) ) {
+ pam_syslog(pamh, LOG_ERR,
+ "unable to re-assign STDIN/OUT/ERR: %m");
+ return PAM_ABORT;
+ }
+
+ /* now the user input is read from the parent/filter: forget fd */
+
+ close(fd[1]);
+
+ /* the current process is now apparently working with filtered
+ stdio/stdout/stderr --- success! */
+
+ return PAM_SUCCESS;
+ }
+
+ /* Clear out passwords... there is a security problem here in
+ * that this process never executes pam_end. Consequently, any
+ * other sensitive data in this process is *not* explicitly
+ * overwritten, before the process terminates */
+
+ (void) pam_set_item(pamh, PAM_AUTHTOK, NULL);
+ (void) pam_set_item(pamh, PAM_OLDAUTHTOK, NULL);
+
+ /* fork a copy of process to run the actual filter executable */
+
+ if ( (child2 = fork()) < 0 ) {
+
+ pam_syslog(pamh, LOG_ERR, "filter fork failed: %m");
+ child2 = 0;
+
+ } else if ( child2 == 0 ) { /* exec the child filter */
+
+ if ( dup2(fd[0],APPIN_FILENO) != APPIN_FILENO ||
+ dup2(fd[0],APPOUT_FILENO) != APPOUT_FILENO ||
+ dup2(fd[0],APPERR_FILENO) != APPERR_FILENO ) {
+ pam_syslog(pamh, LOG_ERR,
+ "unable to re-assign APPIN/OUT/ERR: %m");
+ close(fd[0]);
+ _exit(1);
+ }
+
+ /* make sure that file descriptors survive 'exec's */
+
+ if ( fcntl(APPIN_FILENO, F_SETFD, 0) == -1 ||
+ fcntl(APPOUT_FILENO,F_SETFD, 0) == -1 ||
+ fcntl(APPERR_FILENO,F_SETFD, 0) == -1 ) {
+ pam_syslog(pamh, LOG_ERR,
+ "unable to retain APPIN/OUT/ERR: %m");
+ close(APPIN_FILENO);
+ close(APPOUT_FILENO);
+ close(APPERR_FILENO);
+ _exit(1);
+ }
+
+ /* now the user input is read from the parent through filter */
+
+ execle(filtername, "<pam_filter>", NULL, evp);
+
+ /* getting to here is an error */
+
+ pam_syslog(pamh, LOG_ERR, "filter: %s: %m", filtername);
+ _exit(1);
+
+ } else { /* wait for either of the two children to exit */
+
+ while (child && child2) { /* loop if there are two children */
+ int lstatus=0;
+ int chid;
+
+ chid = wait(&lstatus);
+ if (chid == child) {
+
+ if (WIFEXITED(lstatus)) { /* exited ? */
+ status = WEXITSTATUS(lstatus);
+ } else if (WIFSIGNALED(lstatus)) { /* killed ? */
+ status = -1;
+ } else
+ continue; /* just stopped etc.. */
+ child = 0; /* the child has exited */
+
+ } else if (chid == child2) {
+ /*
+ * if the filter has exited. Let the child die
+ * naturally below
+ */
+ if (WIFEXITED(lstatus) || WIFSIGNALED(lstatus))
+ child2 = 0;
+ } else {
+
+ pam_syslog(pamh, LOG_ERR,
+ "programming error <chid=%d,lstatus=%x> "
+ "in file %s at line %d",
+ chid, lstatus, __FILE__, __LINE__);
+ child = child2 = 0;
+ status = -1;
+
+ }
+ }
+ }
+
+ close(fd[0]);
+
+ /* if there is something running, wait for it to exit */
+
+ while (child || child2) {
+ int lstatus=0;
+ int chid;
+
+ chid = wait(&lstatus);
+
+ if (child && chid == child) {
+
+ if (WIFEXITED(lstatus)) { /* exited ? */
+ status = WEXITSTATUS(lstatus);
+ } else if (WIFSIGNALED(lstatus)) { /* killed ? */
+ status = -1;
+ } else
+ continue; /* just stopped etc.. */
+ child = 0; /* the child has exited */
+
+ } else if (child2 && chid == child2) {
+
+ if (WIFEXITED(lstatus) || WIFSIGNALED(lstatus))
+ child2 = 0;
+
+ } else {
+
+ pam_syslog(pamh, LOG_ERR,
+ "programming error <chid=%d,lstatus=%x> "
+ "in file %s at line %d",
+ chid, lstatus, __FILE__, __LINE__);
+ child = child2 = 0;
+ status = -1;
+
+ }
+ }
+
+ if (aterminal) {
+ /* reset to initial terminal mode */
+ (void) tcsetattr(STDIN_FILENO, TCSANOW, &stored_mode);
+ }
+
+ if (ctrl & FILTER_DEBUG) {
+ pam_syslog(pamh, LOG_DEBUG, "parent process exited"); /* clock off */
+ }
+
+ /* quit the parent process, returning the child's exit status */
+
+ exit(status);
+ return status; /* never reached, to make gcc happy */
+}
+
+static int set_the_terminal(pam_handle_t *pamh)
+{
+ const void *tty;
+
+ if (pam_get_item(pamh, PAM_TTY, &tty) != PAM_SUCCESS
+ || tty == NULL) {
+ tty = ttyname(STDIN_FILENO);
+ if (tty == NULL) {
+ pam_syslog(pamh, LOG_ERR, "couldn't get the tty name");
+ return PAM_ABORT;
+ }
+ if (pam_set_item(pamh, PAM_TTY, tty) != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR, "couldn't set tty name");
+ return PAM_ABORT;
+ }
+ }
+ return PAM_SUCCESS;
+}
+
+static int need_a_filter(pam_handle_t *pamh
+ , int flags, int argc, const char **argv
+ , const char *name, int which_run)
+{
+ int ctrl;
+ char **evp;
+ const char *filterfile;
+ int retval;
+
+ ctrl = process_args(pamh, argc, argv, name, &evp, &filterfile);
+ if (ctrl == -1) {
+ return PAM_AUTHINFO_UNAVAIL;
+ }
+
+ /* set the tty to the old or the new one? */
+
+ if (!(ctrl & NON_TERM) && !(ctrl & NEW_TERM)) {
+ retval = set_the_terminal(pamh);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR, "tried and failed to set PAM_TTY");
+ }
+ } else {
+ retval = PAM_SUCCESS; /* nothing to do which is always a success */
+ }
+
+ if (retval == PAM_SUCCESS && (ctrl & which_run)) {
+ retval = set_filter(pamh, flags, ctrl, evp, filterfile);
+ }
+
+ if (retval == PAM_SUCCESS
+ && !(ctrl & NON_TERM) && (ctrl & NEW_TERM)) {
+ retval = set_the_terminal(pamh);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR,
+ "tried and failed to set new terminal as PAM_TTY");
+ }
+ }
+
+ free_evp(evp);
+
+ if (ctrl & FILTER_DEBUG) {
+ pam_syslog(pamh, LOG_DEBUG, "filter/%s, returning %d", name, retval);
+ pam_syslog(pamh, LOG_DEBUG, "[%s]", pam_strerror(pamh, retval));
+ }
+
+ return retval;
+}
+
+/* ----------------- public functions ---------------- */
+
+/*
+ * here are the advertised access points ...
+ */
+
+/* ------------------ authentication ----------------- */
+
+int pam_sm_authenticate(pam_handle_t *pamh,
+ int flags, int argc, const char **argv)
+{
+ return need_a_filter(pamh, flags, argc, argv
+ , "authenticate", FILTER_RUN1);
+}
+
+int pam_sm_setcred(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ return need_a_filter(pamh, flags, argc, argv, "setcred", FILTER_RUN2);
+}
+
+/* --------------- account management ---------------- */
+
+int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ return need_a_filter(pamh, flags, argc, argv
+ , "setcred", FILTER_RUN1|FILTER_RUN2 );
+}
+
+/* --------------- session management ---------------- */
+
+int pam_sm_open_session(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ return need_a_filter(pamh, flags, argc, argv
+ , "open_session", FILTER_RUN1);
+}
+
+int pam_sm_close_session(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ return need_a_filter(pamh, flags, argc, argv
+ , "close_session", FILTER_RUN2);
+}
+
+/* --------- updating authentication tokens --------- */
+
+
+int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ int runN;
+
+ if (flags & PAM_PRELIM_CHECK)
+ runN = FILTER_RUN1;
+ else if (flags & PAM_UPDATE_AUTHTOK)
+ runN = FILTER_RUN2;
+ else {
+ pam_syslog(pamh, LOG_ERR, "unknown flags for chauthtok (0x%X)", flags);
+ return PAM_TRY_AGAIN;
+ }
+
+ return need_a_filter(pamh, flags, argc, argv, "chauthtok", runN);
+}
diff --git a/modules/pam_filter/pam_filter.h b/modules/pam_filter/pam_filter.h
new file mode 100644
index 0000000..630198e
--- /dev/null
+++ b/modules/pam_filter/pam_filter.h
@@ -0,0 +1,32 @@
+/*
+ * $Id$
+ *
+ * this file is associated with the Linux-PAM filter module.
+ * it was written by Andrew G. Morgan <morgan@linux.kernel.org>
+ *
+ */
+
+#ifndef PAM_FILTER_H
+#define PAM_FILTER_H
+
+#include <sys/file.h>
+
+/*
+ * this will fail if there is some problem with these file descriptors
+ * being allocated by the pam_filter Linux-PAM module. The numbers
+ * here are thought safe, but the filter developer should use the
+ * macros, as these numbers are subject to change.
+ *
+ * The APPXXX_FILENO file descriptors are the STDIN/OUT/ERR_FILENO of the
+ * application. The filter uses the STDIN/OUT/ERR_FILENO's to converse
+ * with the user, passes (modified) user input to the application via
+ * APPIN_FILENO, and receives application output from APPOUT_FILENO/ERR.
+ */
+
+#define APPIN_FILENO 3 /* write here to give application input */
+#define APPOUT_FILENO 4 /* read here to get application output */
+#define APPERR_FILENO 5 /* read here to get application errors */
+
+#define APPTOP_FILE 6 /* used by select */
+
+#endif
diff --git a/modules/pam_filter/tst-pam_filter b/modules/pam_filter/tst-pam_filter
new file mode 100755
index 0000000..56a5d08
--- /dev/null
+++ b/modules/pam_filter/tst-pam_filter
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_filter.so
diff --git a/modules/pam_filter/upperLOWER/Makefile.am b/modules/pam_filter/upperLOWER/Makefile.am
new file mode 100644
index 0000000..f65c462
--- /dev/null
+++ b/modules/pam_filter/upperLOWER/Makefile.am
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2005 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+
+securelibfilterdir = $(SECUREDIR)/pam_filter
+
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -I$(srcdir)/.. @EXE_CFLAGS@ $(WARN_CFLAGS)
+AM_LDFLAGS = @EXE_LDFLAGS@
+LDADD = $(top_builddir)/libpam/libpam.la
+
+securelibfilter_PROGRAMS = upperLOWER
diff --git a/modules/pam_filter/upperLOWER/Makefile.in b/modules/pam_filter/upperLOWER/Makefile.in
new file mode 100644
index 0000000..3046fe8
--- /dev/null
+++ b/modules/pam_filter/upperLOWER/Makefile.in
@@ -0,0 +1,728 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005 Thorsten Kukuk <kukuk@suse.de>
+#
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+securelibfilter_PROGRAMS = upperLOWER$(EXEEXT)
+subdir = modules/pam_filter/upperLOWER
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(securelibfilterdir)"
+PROGRAMS = $(securelibfilter_PROGRAMS)
+upperLOWER_SOURCES = upperLOWER.c
+upperLOWER_OBJECTS = upperLOWER.$(OBJEXT)
+upperLOWER_LDADD = $(LDADD)
+upperLOWER_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/upperLOWER.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = upperLOWER.c
+DIST_SOURCES = upperLOWER.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__DIST_COMMON = $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+securelibfilterdir = $(SECUREDIR)/pam_filter
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -I$(srcdir)/.. @EXE_CFLAGS@ $(WARN_CFLAGS)
+
+AM_LDFLAGS = @EXE_LDFLAGS@
+LDADD = $(top_builddir)/libpam/libpam.la
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_filter/upperLOWER/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_filter/upperLOWER/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-securelibfilterPROGRAMS: $(securelibfilter_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(securelibfilter_PROGRAMS)'; test -n "$(securelibfilterdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibfilterdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibfilterdir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(securelibfilterdir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(securelibfilterdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-securelibfilterPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelibfilter_PROGRAMS)'; test -n "$(securelibfilterdir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(securelibfilterdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(securelibfilterdir)" && rm -f $$files
+
+clean-securelibfilterPROGRAMS:
+ @list='$(securelibfilter_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+upperLOWER$(EXEEXT): $(upperLOWER_OBJECTS) $(upperLOWER_DEPENDENCIES) $(EXTRA_upperLOWER_DEPENDENCIES)
+ @rm -f upperLOWER$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(upperLOWER_OBJECTS) $(upperLOWER_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/upperLOWER.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibfilterdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibfilterPROGRAMS \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/upperLOWER.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-securelibfilterPROGRAMS
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/upperLOWER.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-securelibfilterPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \
+ clean-generic clean-libtool clean-securelibfilterPROGRAMS \
+ cscopelist-am ctags ctags-am distclean distclean-compile \
+ distclean-generic distclean-libtool distclean-tags distdir dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibfilterPROGRAMS install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags tags-am uninstall uninstall-am \
+ uninstall-securelibfilterPROGRAMS
+
+.PRECIOUS: Makefile
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_filter/upperLOWER/upperLOWER.c b/modules/pam_filter/upperLOWER/upperLOWER.c
new file mode 100644
index 0000000..25e70a5
--- /dev/null
+++ b/modules/pam_filter/upperLOWER/upperLOWER.c
@@ -0,0 +1,141 @@
+/*
+ * This is a sample filter program, for use with pam_filter (a module
+ * provided with Linux-PAM). This filter simply transposes upper and
+ * lower case letters, it is intended for demonstration purposes and
+ * it serves no purpose other than to annoy the user...
+ */
+
+#include "config.h"
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <syslog.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "pam_filter.h"
+#include <security/pam_modutil.h>
+
+/* ---------------------------------------------------------------- */
+
+static void do_transpose(char *buffer,int len)
+{
+ int i;
+ for (i=0; i<len; ++i) {
+ if (islower(buffer[i])) {
+ buffer[i] = toupper(buffer[i]);
+ } else {
+ buffer[i] = tolower(buffer[i]);
+ }
+ }
+}
+
+extern char **environ;
+
+int main(int argc, char **argv UNUSED)
+{
+ char buffer[BUFSIZ];
+ fd_set readers;
+ void (*before_user)(char *,int);
+ void (*before_app)(char *,int);
+
+ openlog("upperLOWER", LOG_CONS|LOG_PID, LOG_AUTHPRIV);
+
+#ifdef DEBUG
+ {
+ int i;
+
+ fprintf(stderr,"environment :[\r\n");
+ for (i=0; environ[i]; ++i) {
+ fprintf(stderr,"-> %s\r\n",environ[i]);
+ }
+ fprintf(stderr,"]: end\r\n");
+ }
+#endif
+
+ if (argc != 1) {
+#ifdef DEBUG
+ fprintf(stderr,"filter invoked as conventional executable\n");
+#else
+ syslog(LOG_ERR, "filter invoked as conventional executable");
+#endif
+ exit(1);
+ }
+
+ before_user = before_app = do_transpose; /* assign filter functions */
+
+ /* enter a loop that deals with the input and output of the
+ user.. passing it to and from the application */
+
+ FD_ZERO(&readers); /* initialize reading mask */
+
+ for (;;) {
+
+ FD_SET(APPOUT_FILENO, &readers); /* wake for output */
+ FD_SET(APPERR_FILENO, &readers); /* wake for error */
+ FD_SET(STDIN_FILENO, &readers); /* wake for input */
+
+ if ( select(APPTOP_FILE,&readers,NULL,NULL,NULL) < 0 ) {
+#ifdef DEBUG
+ fprintf(stderr,"select failed\n");
+#else
+ syslog(LOG_WARNING,"select failed");
+#endif
+ break;
+ }
+
+ /* application errors */
+
+ if ( FD_ISSET(APPERR_FILENO,&readers) ) {
+ int got = read(APPERR_FILENO, buffer, BUFSIZ);
+ if (got <= 0) {
+ break;
+ } else {
+ /* translate to give to real terminal */
+ if (before_user != NULL)
+ before_user(buffer, got);
+ if (pam_modutil_write(STDERR_FILENO, buffer, got) != got ) {
+ syslog(LOG_WARNING,"couldn't write %d bytes?!",got);
+ break;
+ }
+ }
+ } else if ( FD_ISSET(APPOUT_FILENO,&readers) ) { /* app output */
+ int got = read(APPOUT_FILENO, buffer, BUFSIZ);
+ if (got <= 0) {
+ break;
+ } else {
+ /* translate to give to real terminal */
+ if (before_user != NULL)
+ before_user(buffer, got);
+ if (pam_modutil_write(STDOUT_FILENO, buffer, got) != got ) {
+ syslog(LOG_WARNING,"couldn't write %d bytes!?",got);
+ break;
+ }
+ }
+ }
+
+ if ( FD_ISSET(STDIN_FILENO, &readers) ) { /* user input */
+ int got = read(STDIN_FILENO, buffer, BUFSIZ);
+ if (got < 0) {
+ syslog(LOG_WARNING,"user input junked");
+ break;
+ } else if (got) {
+ /* translate to give to application */
+ if (before_app != NULL)
+ before_app(buffer, got);
+ if (pam_modutil_write(APPIN_FILENO, buffer, got) != got ) {
+ syslog(LOG_WARNING,"couldn't pass %d bytes!?",got);
+ break;
+ }
+ } else {
+ /* nothing received -- an error? */
+ syslog(LOG_WARNING,"user input null?");
+ break;
+ }
+ }
+ }
+
+ exit(0);
+}
diff --git a/modules/pam_ftp/Makefile.am b/modules/pam_ftp/Makefile.am
new file mode 100644
index 0000000..abfa98a
--- /dev/null
+++ b/modules/pam_ftp/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_ftp.8
+endif
+XMLS = README.xml pam_ftp.8.xml
+dist_check_SCRIPTS = tst-pam_ftp
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_ftp.la
+pam_ftp_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_ftp/Makefile.in b/modules/pam_ftp/Makefile.in
new file mode 100644
index 0000000..7788d6e
--- /dev/null
+++ b/modules/pam_ftp/Makefile.in
@@ -0,0 +1,1150 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_ftp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_ftp_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_ftp_la_SOURCES = pam_ftp.c
+pam_ftp_la_OBJECTS = pam_ftp.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_ftp.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_ftp.c
+DIST_SOURCES = pam_ftp.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_ftp.8
+XMLS = README.xml pam_ftp.8.xml
+dist_check_SCRIPTS = tst-pam_ftp
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_ftp.la
+pam_ftp_la_LIBADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_ftp/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_ftp/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_ftp.la: $(pam_ftp_la_OBJECTS) $(pam_ftp_la_DEPENDENCIES) $(EXTRA_pam_ftp_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_ftp_la_OBJECTS) $(pam_ftp_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_ftp.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_ftp.log: tst-pam_ftp
+ @p='tst-pam_ftp'; \
+ b='tst-pam_ftp'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_ftp.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_ftp.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_ftp/README b/modules/pam_ftp/README
new file mode 100644
index 0000000..b9ef785
--- /dev/null
+++ b/modules/pam_ftp/README
@@ -0,0 +1,52 @@
+pam_ftp — PAM module for anonymous access module
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+pam_ftp is a PAM module which provides a pluggable anonymous ftp mode of
+access.
+
+This module intercepts the user's name and password. If the name is ftp or
+anonymous, the user's password is broken up at the @ delimiter into a PAM_RUSER
+and a PAM_RHOST part; these pam-items being set accordingly. The username (
+PAM_USER) is set to ftp. In this case the module succeeds. Alternatively, the
+module sets the PAM_AUTHTOK item with the entered password and fails.
+
+This module is not safe and easily spoofable.
+
+OPTIONS
+
+debug
+
+ Print debug information.
+
+ignore
+
+ Pay no attention to the email address of the user (if supplied).
+
+ftp=XXX,YYY,...
+
+ Instead of ftp or anonymous, provide anonymous login to the comma separated
+ list of users: XXX,YYY,.... Should the applicant enter one of these
+ usernames the returned username is set to the first in the list: XXX.
+
+EXAMPLES
+
+Add the following line to /etc/pam.d/ftpd to handle ftp style anonymous login:
+
+#
+# ftpd; add ftp-specifics. These lines enable anonymous ftp over
+# standard UN*X access (the listfile entry blocks access to
+# users listed in /etc/ftpusers)
+#
+auth sufficient pam_ftp.so
+auth required pam_unix.so use_first_pass
+auth required pam_listfile.so \
+ onerr=succeed item=user sense=deny file=/etc/ftpusers
+
+
+AUTHOR
+
+pam_ftp was written by Andrew G. Morgan <morgan@kernel.org>.
+
diff --git a/modules/pam_ftp/README.xml b/modules/pam_ftp/README.xml
new file mode 100644
index 0000000..65de28e
--- /dev/null
+++ b/modules/pam_ftp/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_ftp.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_ftp.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_ftp-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_ftp.8.xml" xpointer='xpointer(//refsect1[@id = "pam_ftp-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_ftp.8.xml" xpointer='xpointer(//refsect1[@id = "pam_ftp-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_ftp.8.xml" xpointer='xpointer(//refsect1[@id = "pam_ftp-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_ftp.8.xml" xpointer='xpointer(//refsect1[@id = "pam_ftp-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_ftp/pam_ftp.8 b/modules/pam_ftp/pam_ftp.8
new file mode 100644
index 0000000..28e1af8
--- /dev/null
+++ b/modules/pam_ftp/pam_ftp.8
@@ -0,0 +1,125 @@
+'\" t
+.\" Title: pam_ftp
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_FTP" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_ftp \- PAM module for anonymous access module
+.SH "SYNOPSIS"
+.HP \w'\fBpam_ftp\&.so\fR\ 'u
+\fBpam_ftp\&.so\fR [debug] [ignore] [users=\fIXXX,YYY,\fR...]
+.SH "DESCRIPTION"
+.PP
+pam_ftp is a PAM module which provides a pluggable anonymous ftp mode of access\&.
+.PP
+This module intercepts the user\*(Aqs name and password\&. If the name is
+\fIftp\fR
+or
+\fIanonymous\fR, the user\*(Aqs password is broken up at the
+\fI@\fR
+delimiter into a
+\fIPAM_RUSER\fR
+and a
+\fIPAM_RHOST\fR
+part; these pam\-items being set accordingly\&. The username (\fIPAM_USER\fR) is set to
+\fIftp\fR\&. In this case the module succeeds\&. Alternatively, the module sets the
+\fIPAM_AUTHTOK\fR
+item with the entered password and fails\&.
+.PP
+This module is not safe and easily spoofable\&.
+.SH "OPTIONS"
+.PP
+.PP
+\fBdebug\fR
+.RS 4
+Print debug information\&.
+.RE
+.PP
+\fBignore\fR
+.RS 4
+Pay no attention to the email address of the user (if supplied)\&.
+.RE
+.PP
+\fBftp=\fR\fB\fIXXX,YYY,\&.\&.\&.\fR\fR
+.RS 4
+Instead of
+\fIftp\fR
+or
+\fIanonymous\fR, provide anonymous login to the comma separated list of users:
+\fB\fIXXX,YYY,\&.\&.\&.\fR\fR\&. Should the applicant enter one of these usernames the returned username is set to the first in the list:
+\fIXXX\fR\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+Only the
+\fBauth\fR
+module type is provided\&.
+.SH "RETURN VALUES"
+.PP
+.PP
+PAM_SUCCESS
+.RS 4
+The authentication was successful\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+User not known\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Add the following line to
+/etc/pam\&.d/ftpd
+to handle ftp style anonymous login:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+#
+# ftpd; add ftp\-specifics\&. These lines enable anonymous ftp over
+# standard UN*X access (the listfile entry blocks access to
+# users listed in /etc/ftpusers)
+#
+auth sufficient pam_ftp\&.so
+auth required pam_unix\&.so use_first_pass
+auth required pam_listfile\&.so \e
+ onerr=succeed item=user sense=deny file=/etc/ftpusers
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.PP
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_ftp was written by Andrew G\&. Morgan <morgan@kernel\&.org>\&.
diff --git a/modules/pam_ftp/pam_ftp.8.xml b/modules/pam_ftp/pam_ftp.8.xml
new file mode 100644
index 0000000..6f11f57
--- /dev/null
+++ b/modules/pam_ftp/pam_ftp.8.xml
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_ftp">
+
+ <refmeta>
+ <refentrytitle>pam_ftp</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_ftp-name">
+ <refname>pam_ftp</refname>
+ <refpurpose>PAM module for anonymous access module</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_ftp-cmdsynopsis">
+ <command>pam_ftp.so</command>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ ignore
+ </arg>
+ <arg choice="opt" rep='repeat'>
+ users=<replaceable>XXX,YYY,</replaceable>
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_ftp-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ pam_ftp is a PAM module which provides a pluggable
+ anonymous ftp mode of access.
+ </para>
+ <para>
+ This module intercepts the user's name and password. If the name is
+ <emphasis>ftp</emphasis> or <emphasis>anonymous</emphasis>, the
+ user's password is broken up at the <emphasis>@</emphasis> delimiter
+ into a <emphasis>PAM_RUSER</emphasis> and a
+ <emphasis>PAM_RHOST</emphasis> part; these pam-items being set
+ accordingly. The username (<emphasis>PAM_USER</emphasis>) is set
+ to <emphasis>ftp</emphasis>. In this case the module succeeds.
+ Alternatively, the module sets the <emphasis>PAM_AUTHTOK</emphasis>
+ item with the entered password and fails.
+ </para>
+ <para>
+ This module is not safe and easily spoofable.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_ftp-options">
+
+ <title>OPTIONS</title>
+ <para>
+ <variablelist>
+
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Print debug information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>ignore</option>
+ </term>
+ <listitem>
+ <para>
+ Pay no attention to the email address of the user
+ (if supplied).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>ftp=<replaceable>XXX,YYY,...</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Instead of <emphasis>ftp</emphasis> or
+ <emphasis>anonymous</emphasis>, provide anonymous login
+ to the comma separated list of users:
+ <option><replaceable>XXX,YYY,...</replaceable></option>.
+ Should the applicant enter
+ one of these usernames the returned username is set to
+ the first in the list: <emphasis>XXX</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_ftp-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ Only the <option>auth</option> module type is provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_ftp-return_values'>
+ <title>RETURN VALUES</title>
+ <para>
+ <variablelist>
+
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ The authentication was successful.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ User not known.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_ftp-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ Add the following line to <filename>/etc/pam.d/ftpd</filename> to
+ handle ftp style anonymous login:
+ <programlisting>
+#
+# ftpd; add ftp-specifics. These lines enable anonymous ftp over
+# standard UN*X access (the listfile entry blocks access to
+# users listed in /etc/ftpusers)
+#
+auth sufficient pam_ftp.so
+auth required pam_unix.so use_first_pass
+auth required pam_listfile.so \
+ onerr=succeed item=user sense=deny file=/etc/ftpusers
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_ftp-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_ftp-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_ftp was written by Andrew G. Morgan &lt;morgan@kernel.org&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_ftp/pam_ftp.c b/modules/pam_ftp/pam_ftp.c
new file mode 100644
index 0000000..441f2bb
--- /dev/null
+++ b/modules/pam_ftp/pam_ftp.c
@@ -0,0 +1,215 @@
+/*
+ * pam_ftp module
+ *
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
+ */
+
+#define PLEASE_ENTER_PASSWORD "Password required for %s."
+#define GUEST_LOGIN_PROMPT "Guest login ok, " \
+"send your complete e-mail address as password."
+
+/* the following is a password that "can't be correct" */
+#define BLOCK_PASSWORD "\177BAD PASSWPRD\177"
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+#include <security/pam_ext.h>
+#include "pam_inline.h"
+
+/* argument parsing */
+
+#define PAM_DEBUG_ARG 01
+#define PAM_IGNORE_EMAIL 02
+#define PAM_NO_ANON 04
+
+static int
+_pam_parse(pam_handle_t *pamh, int argc, const char **argv, const char **users)
+{
+ int ctrl=0;
+
+ /* step through arguments */
+ for (ctrl=0; argc-- > 0; ++argv) {
+ const char *str;
+
+ /* generic options */
+
+ if (!strcmp(*argv,"debug"))
+ ctrl |= PAM_DEBUG_ARG;
+ else if (!strcmp(*argv,"ignore"))
+ ctrl |= PAM_IGNORE_EMAIL;
+ else if ((str = pam_str_skip_prefix(*argv, "users=")) != NULL)
+ *users = str;
+ else
+ pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
+ }
+
+ return ctrl;
+}
+
+/*
+ * check if name is in list or default list. place users name in *_user
+ * return 1 if listed 0 if not.
+ */
+
+static int lookup(const char *name, const char *list, char **_user)
+{
+ int anon = 0;
+
+ if (list && *list) {
+ const char *l;
+ char *list_copy, *x;
+ char *sptr = NULL;
+
+ list_copy = strdup(list);
+ x = list_copy;
+ while (list_copy && (l = strtok_r(x, ",", &sptr))) {
+ x = NULL;
+ if (!strcmp(name, l)) {
+ *_user = list_copy;
+ anon = 1;
+ break;
+ }
+ }
+ if (*_user != list_copy) {
+ free(list_copy);
+ }
+ } else {
+#define MAX_L 2
+ static const char *l[MAX_L] = { "ftp", "anonymous" };
+ int i;
+
+ for (i=0; i<MAX_L; ++i) {
+ if (!strcmp(l[i], name)) {
+ *_user = strdup(l[0]);
+ anon = 1;
+ break;
+ }
+ }
+ }
+
+ return anon;
+}
+
+/* --- authentication management functions (only) --- */
+
+int
+pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ int retval, anon=0, ctrl;
+ const char *user;
+ char *anon_user = NULL;
+ const char *users = NULL;
+
+ /*
+ * this module checks if the user name is ftp or anonymous. If
+ * this is the case, it can set the PAM_RUSER to the entered email
+ * address and SUCCEEDS, otherwise it FAILS.
+ */
+
+ ctrl = _pam_parse(pamh, argc, argv, &users);
+
+ retval = pam_get_user(pamh, &user, NULL);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE, "cannot determine user name: %s",
+ pam_strerror(pamh, retval));
+ return PAM_USER_UNKNOWN;
+ }
+
+ if (!(ctrl & PAM_NO_ANON)) {
+ anon = lookup(user, users, &anon_user);
+ }
+
+ if (anon) {
+ retval = pam_set_item(pamh, PAM_USER, (const void *)anon_user);
+ if (retval != PAM_SUCCESS || anon_user == NULL) {
+ pam_syslog(pamh, LOG_ERR, "user resetting failed");
+ free(anon_user);
+
+ return PAM_USER_UNKNOWN;
+ }
+ free(anon_user);
+ }
+
+ /*
+ * OK. we require an email address for user or the user's password.
+ * - build conversation and get their input.
+ */
+
+ {
+ char *resp = NULL;
+ const char *token;
+
+ if (!anon)
+ retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp,
+ PLEASE_ENTER_PASSWORD, user);
+ else
+ retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, &resp,
+ GUEST_LOGIN_PROMPT);
+
+ if (retval != PAM_SUCCESS) {
+ _pam_overwrite (resp);
+ _pam_drop (resp);
+ return ((retval == PAM_CONV_AGAIN)
+ ? PAM_INCOMPLETE:PAM_AUTHINFO_UNAVAIL);
+ }
+
+ if (anon) {
+ /* XXX: Some effort should be made to verify this email address! */
+
+ if (!(ctrl & PAM_IGNORE_EMAIL)) {
+ char *sptr = NULL;
+ token = strtok_r(resp, "@", &sptr);
+ retval = pam_set_item(pamh, PAM_RUSER, token);
+
+ if ((token) && (retval == PAM_SUCCESS)) {
+ token = strtok_r(NULL, "@", &sptr);
+ retval = pam_set_item(pamh, PAM_RHOST, token);
+ }
+ }
+
+ /* we are happy to grant anonymous access to the user */
+ retval = PAM_SUCCESS;
+
+ } else {
+ /*
+ * we have a password so set AUTHTOK
+ */
+
+ pam_set_item(pamh, PAM_AUTHTOK, resp);
+
+ /*
+ * this module failed, but the next one might succeed with
+ * this password.
+ */
+
+ retval = PAM_AUTH_ERR;
+ }
+
+ /* clean up */
+ _pam_overwrite(resp);
+ _pam_drop(resp);
+
+ /* success or failure */
+
+ return retval;
+ }
+}
+
+int
+pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_IGNORE;
+}
+
+/* end of module definition */
diff --git a/modules/pam_ftp/tst-pam_ftp b/modules/pam_ftp/tst-pam_ftp
new file mode 100755
index 0000000..1a4f67c
--- /dev/null
+++ b/modules/pam_ftp/tst-pam_ftp
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_ftp.so
diff --git a/modules/pam_group/Makefile.am b/modules/pam_group/Makefile.am
new file mode 100644
index 0000000..a9a0a1e
--- /dev/null
+++ b/modules/pam_group/Makefile.am
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = group.conf.5 pam_group.8
+endif
+XMLS = README.xml group.conf.5.xml pam_group.8.xml
+dist_check_SCRIPTS = tst-pam_group
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DPAM_GROUP_CONF=\"$(SCONFIGDIR)/group.conf\" $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_group.la
+pam_group_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+dist_secureconf_DATA = group.conf
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_group/Makefile.in b/modules/pam_group/Makefile.in
new file mode 100644
index 0000000..6d916f1
--- /dev/null
+++ b/modules/pam_group/Makefile.in
@@ -0,0 +1,1221 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_group
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(dist_secureconf_DATA) \
+ $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man5dir)" \
+ "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(secureconfdir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_group_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_group_la_SOURCES = pam_group.c
+pam_group_la_OBJECTS = pam_group.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_group.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_group.c
+DIST_SOURCES = pam_group.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man5dir = $(mandir)/man5
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA) $(dist_secureconf_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = group.conf.5 pam_group.8
+XMLS = README.xml group.conf.5.xml pam_group.8.xml
+dist_check_SCRIPTS = tst-pam_group
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DPAM_GROUP_CONF=\"$(SCONFIGDIR)/group.conf\" $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_group.la
+pam_group_la_LIBADD = $(top_builddir)/libpam/libpam.la
+dist_secureconf_DATA = group.conf
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_group/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_group/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_group.la: $(pam_group_la_OBJECTS) $(pam_group_la_DEPENDENCIES) $(EXTRA_pam_group_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_group_la_OBJECTS) $(pam_group_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_group.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man5: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man5dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.5[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man5:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man5dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.5[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir)
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+install-dist_secureconfDATA: $(dist_secureconf_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_secureconf_DATA)'; test -n "$(secureconfdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(secureconfdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(secureconfdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(secureconfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(secureconfdir)" || exit $$?; \
+ done
+
+uninstall-dist_secureconfDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_secureconf_DATA)'; test -n "$(secureconfdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(secureconfdir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_group.log: tst-pam_group
+ @p='tst-pam_group'; \
+ b='tst-pam_group'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(secureconfdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_group.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-dist_secureconfDATA install-man \
+ install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man5 install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_group.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-dist_secureconfDATA uninstall-man \
+ uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man5 uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dist_secureconfDATA install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-man5 install-man8 install-pdf install-pdf-am \
+ install-ps install-ps-am install-securelibLTLIBRARIES \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am recheck tags tags-am uninstall \
+ uninstall-am uninstall-dist_secureconfDATA uninstall-man \
+ uninstall-man5 uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_group/README b/modules/pam_group/README
new file mode 100644
index 0000000..9d6d097
--- /dev/null
+++ b/modules/pam_group/README
@@ -0,0 +1,52 @@
+pam_group — PAM module for group access
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+The pam_group PAM module does not authenticate the user, but instead it grants
+group memberships (in the credential setting phase of the authentication
+module) to the user. Such memberships are based on the service they are
+applying for.
+
+By default rules for group memberships are taken from config file /etc/security
+/group.conf.
+
+This module's usefulness relies on the file-systems accessible to the user. The
+point being that once granted the membership of a group, the user may attempt
+to create a setgid binary with a restricted group ownership. Later, when the
+user is not given membership to this group, they can recover group membership
+with the precompiled binary. The reason that the file-systems that the user has
+access to are so significant, is the fact that when a system is mounted nosuid
+the user is unable to create or execute such a binary file. For this module to
+provide any level of security, all file-systems that the user has write access
+to should be mounted nosuid.
+
+The pam_group module functions in parallel with the /etc/group file. If the
+user is granted any groups based on the behavior of this module, they are
+granted in addition to those entries /etc/group (or equivalent).
+
+EXAMPLES
+
+These are some example lines which might be specified in /etc/security/
+group.conf.
+
+Running 'xsh' on tty* (any ttyXXX device), the user 'us' is given access to the
+floppy (through membership of the floppy group)
+
+xsh;tty*&!ttyp*;us;Al0000-2400;floppy
+
+Running 'xsh' on tty* (any ttyXXX device), the users 'sword', 'pike' and
+'shield' are given access to games (through membership of the floppy group)
+after work hours.
+
+xsh; tty* ;sword|pike|shield;!Wk0900-1800;games, sound
+xsh; tty* ;*;Al0900-1800;floppy
+
+
+Any member of the group 'admin' running 'xsh' on tty*, is granted access (at
+any time) to the group 'plugdev'
+
+xsh; tty* ;%admin;Al0000-2400;plugdev
+
+
diff --git a/modules/pam_group/README.xml b/modules/pam_group/README.xml
new file mode 100644
index 0000000..387d698
--- /dev/null
+++ b/modules/pam_group/README.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamgroup SYSTEM "pam_group.8.xml">
+-->
+<!--
+<!ENTITY groupconf SYSTEM "group.conf.5.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_group.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_group-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_group.8.xml" xpointer='xpointer(//refsect1[@id = "pam_group-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="group.conf.5.xml" xpointer='xpointer(//refsect1[@id = "group.conf-examples"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_group/group.conf b/modules/pam_group/group.conf
new file mode 100644
index 0000000..7c07a26
--- /dev/null
+++ b/modules/pam_group/group.conf
@@ -0,0 +1,106 @@
+#
+# This is the configuration file for the pam_group module.
+#
+
+#
+# *** Please note that giving group membership on a session basis is
+# *** NOT inherently secure. If a user can create an executable that
+# *** is setgid a group that they are infrequently given membership
+# *** of, they can basically obtain group membership any time they
+# *** like. Example: games are allowed between the hours of 6pm and 6am
+# *** user joe logs in at 7pm writes a small C-program toplay.c that
+# *** invokes their favorite shell, compiles it and does
+# *** "chgrp play toplay; chmod g+s toplay". They are basically able
+# *** to play games any time... You have been warned. AGM
+#
+
+#
+# The syntax of the lines is as follows:
+#
+# services;ttys;users;times;groups
+#
+# white space is ignored and lines maybe extended with '\\n' (escaped
+# newlines). From reading these comments, it is clear that
+# text following a '#' is ignored to the end of the line.
+#
+# the combination of individual users/terminals etc is a logic list
+# namely individual tokens that are optionally prefixed with '!' (logical
+# not) and separated with '&' (logical and) and '|' (logical or).
+#
+# services
+# is a logic list of PAM service names that the rule applies to.
+#
+# ttys
+# is a logic list of terminal names that this rule applies to.
+#
+# users
+# is a logic list of users or a netgroup of users to whom this
+# rule applies.
+#
+# NB. For these items the simple wildcard '*' may be used only once.
+# With netgroups no wildcards or logic operators are allowed.
+#
+# times
+# It is used to indicate "when" these groups are to be given to the
+# user. The format here is a logic list of day/time-range
+# entries the days are specified by a sequence of two character
+# entries, MoTuSa for example is Monday Tuesday and Saturday. Note
+# that repeated days are unset MoMo = no day, and MoWk = all weekdays
+# bar Monday. The two character combinations accepted are
+#
+# Mo Tu We Th Fr Sa Su Wk Wd Al
+#
+# the last two being week-end days and all 7 days of the week
+# respectively. As a final example, AlFr means all days except Friday.
+#
+# Each day/time-range can be prefixed with a '!' to indicate "anything
+# but"
+#
+# The time-range part is two 24-hour times HHMM separated by a hyphen
+# indicating the start and finish time (if the finish time is smaller
+# than the start time it is deemed to apply on the following day).
+#
+# groups
+# The (comma or space separated) list of groups that the user
+# inherits membership of. These groups are added if the previous
+# fields are satisfied by the user's request
+#
+# For a rule to be active, ALL of service+ttys+users must be satisfied
+# by the applying process.
+#
+
+#
+# Note, to get this to work as it is currently typed you need
+#
+# 1. to run an application as root
+# 2. add the following groups to the /etc/group file:
+# floppy, play, sound
+#
+
+#
+# Here is a simple example: running 'xsh' on tty* (any ttyXXX device),
+# the user 'us' is given access to the floppy (through membership of
+# the floppy group)
+#
+
+#xsh;tty*&!ttyp*;us;Al0000-2400;floppy
+
+#
+# another example: running 'xsh' on tty* (any ttyXXX device),
+# the user 'sword' is given access to games (through membership of
+# the sound and play group) after work hours.
+#
+
+#xsh; tty* ;sword;!Wk0900-1800;sound, play
+#xsh; tty* ;*;Al0900-1800;floppy
+
+#
+# yet another example: any member of the group 'admin' running
+# 'xsh' on tty*, is granted access (at any time) to the group 'plugdev'
+#
+
+#xsh; tty* ;%admin;Al0000-2400;plugdev
+
+#
+# End of group.conf file
+#
diff --git a/modules/pam_group/group.conf.5 b/modules/pam_group/group.conf.5
new file mode 100644
index 0000000..bbbe307
--- /dev/null
+++ b/modules/pam_group/group.conf.5
@@ -0,0 +1,121 @@
+'\" t
+.\" Title: group.conf
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "GROUP\&.CONF" "5" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+group.conf \- configuration file for the pam_group module
+.SH "DESCRIPTION"
+.PP
+The pam_group PAM module does not authenticate the user, but instead it grants group memberships (in the credential setting phase of the authentication module) to the user\&. Such memberships are based on the service they are applying for\&.
+.PP
+For this module to function correctly there must be a correctly formatted
+/etc/security/group\&.conf
+file present\&. White spaces are ignored and lines maybe extended with \*(Aq\e\*(Aq (escaped newlines)\&. Text following a \*(Aq#\*(Aq is ignored to the end of the line\&.
+.PP
+The syntax of the lines is as follows:
+.PP
+\fIservices\fR;\fIttys\fR;\fIusers\fR;\fItimes\fR;\fIgroups\fR
+.PP
+The first field, the
+\fIservices\fR
+field, is a logic list of PAM service names that the rule applies to\&.
+.PP
+The second field, the
+\fItty\fR
+field, is a logic list of terminal names that this rule applies to\&.
+.PP
+The third field, the
+\fIusers\fR
+field, is a logic list of users, or a UNIX group, or a netgroup of users to whom this rule applies\&. Group names are preceded by a \*(Aq%\*(Aq symbol, while netgroup names are preceded by a \*(Aq@\*(Aq symbol\&.
+.PP
+A logic list namely means individual tokens that are optionally prefixed with \*(Aq!\*(Aq (logical not) and separated with \*(Aq&\*(Aq (logical and) and \*(Aq|\*(Aq (logical or)\&.
+.PP
+For these items the simple wildcard \*(Aq*\*(Aq may be used only once\&. With UNIX groups or netgroups no wildcards or logic operators are allowed\&.
+.PP
+The
+\fItimes\fR
+field is used to indicate "when" these groups are to be given to the user\&. The format here is a logic list of day/time\-range entries\&. The days are specified by a sequence of two character entries, MoTuSa for example is Monday Tuesday and Saturday\&. Note that repeated days are unset MoMo = no day, and MoWk = all weekdays bar Monday\&. The two character combinations accepted are Mo Tu We Th Fr Sa Su Wk Wd Al, the last two being week\-end days and all 7 days of the week respectively\&. As a final example, AlFr means all days except Friday\&.
+.PP
+Each day/time\-range can be prefixed with a \*(Aq!\*(Aq to indicate "anything but"\&. The time\-range part is two 24\-hour times HHMM, separated by a hyphen, indicating the start and finish time (if the finish time is smaller than the start time it is deemed to apply on the following day)\&.
+.PP
+The
+\fIgroups\fR
+field is a comma or space separated list of groups that the user inherits membership of\&. These groups are added if the previous fields are satisfied by the user\*(Aqs request\&.
+.PP
+For a rule to be active, ALL of service+ttys+users must be satisfied by the applying process\&.
+.SH "EXAMPLES"
+.PP
+These are some example lines which might be specified in
+/etc/security/group\&.conf\&.
+.PP
+Running \*(Aqxsh\*(Aq on tty* (any ttyXXX device), the user \*(Aqus\*(Aq is given access to the floppy (through membership of the floppy group)
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+xsh;tty*&!ttyp*;us;Al0000\-2400;floppy
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Running \*(Aqxsh\*(Aq on tty* (any ttyXXX device), the users \*(Aqsword\*(Aq, \*(Aqpike\*(Aq and \*(Aqshield\*(Aq are given access to games (through membership of the floppy group) after work hours\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+xsh; tty* ;sword|pike|shield;!Wk0900\-1800;games, sound
+xsh; tty* ;*;Al0900\-1800;floppy
+
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Any member of the group \*(Aqadmin\*(Aq running \*(Aqxsh\*(Aq on tty*, is granted access (at any time) to the group \*(Aqplugdev\*(Aq
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+xsh; tty* ;%admin;Al0000\-2400;plugdev
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+.PP
+\fBpam_group\fR(8),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_group was written by Andrew G\&. Morgan <morgan@kernel\&.org>\&.
diff --git a/modules/pam_group/group.conf.5.xml b/modules/pam_group/group.conf.5.xml
new file mode 100644
index 0000000..2b7fb34
--- /dev/null
+++ b/modules/pam_group/group.conf.5.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="group.conf">
+
+ <refmeta>
+ <refentrytitle>group.conf</refentrytitle>
+ <manvolnum>5</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>group.conf</refname>
+ <refpurpose>configuration file for the pam_group module</refpurpose>
+ </refnamediv>
+
+ <refsect1 id='group.conf-description'>
+ <title>DESCRIPTION</title>
+
+ <para>
+ The pam_group PAM module does not authenticate the user, but instead
+ it grants group memberships (in the credential setting phase of the
+ authentication module) to the user. Such memberships are based on the
+ service they are applying for.
+ </para>
+ <para>
+ For this module to function correctly there must be a correctly
+ formatted <filename>/etc/security/group.conf</filename> file present.
+ White spaces are ignored and lines maybe extended with '\' (escaped
+ newlines). Text following a '#' is ignored to the end of the line.
+ </para>
+
+ <para>
+ The syntax of the lines is as follows:
+ </para>
+
+ <para>
+ <replaceable>services</replaceable>;<replaceable>ttys</replaceable>;<replaceable>users</replaceable>;<replaceable>times</replaceable>;<replaceable>groups</replaceable>
+ </para>
+
+
+ <para>
+ The first field, the <replaceable>services</replaceable> field, is a logic list
+ of PAM service names that the rule applies to.
+ </para>
+
+ <para>
+ The second field, the <replaceable>tty</replaceable>
+ field, is a logic list of terminal names that this rule applies to.
+ </para>
+
+ <para>
+ The third field, the <replaceable>users</replaceable>
+ field, is a logic list of users, or a UNIX group, or a netgroup of
+ users to whom this rule applies. Group names are preceded by a '%'
+ symbol, while netgroup names are preceded by a '@' symbol.
+ </para>
+
+ <para>
+ A logic list namely means individual tokens that are optionally prefixed
+ with '!' (logical not) and separated with '&amp;' (logical and) and '|'
+ (logical or).
+ </para>
+
+ <para>
+ For these items the simple wildcard '*' may be used only once.
+ With UNIX groups or netgroups no wildcards or logic operators
+ are allowed.
+ </para>
+
+ <para>
+ The <replaceable>times</replaceable> field is used to indicate "when"
+ these groups are to be given to the user. The format here is a logic
+ list of day/time-range entries. The days are specified by a sequence of
+ two character entries, MoTuSa for example is Monday Tuesday and Saturday.
+ Note that repeated days are unset MoMo = no day, and MoWk = all weekdays
+ bar Monday. The two character combinations accepted are Mo Tu We Th Fr Sa
+ Su Wk Wd Al, the last two being week-end days and all 7 days of the week
+ respectively. As a final example, AlFr means all days except Friday.
+ </para>
+ <para>
+ Each day/time-range can be prefixed with a '!' to indicate "anything but".
+ The time-range part is two 24-hour times HHMM, separated by a hyphen,
+ indicating the start and finish time (if the finish time is smaller
+ than the start time it is deemed to apply on the following day).
+ </para>
+
+ <para>
+ The <replaceable>groups</replaceable> field is a comma or space
+ separated list of groups that the user inherits membership of. These
+ groups are added if the previous fields are satisfied by the user's request.
+ </para>
+
+ <para>
+ For a rule to be active, ALL of service+ttys+users must be satisfied
+ by the applying process.
+ </para>
+ </refsect1>
+
+ <refsect1 id="group.conf-examples">
+ <title>EXAMPLES</title>
+ <para>
+ These are some example lines which might be specified in
+ <filename>/etc/security/group.conf</filename>.
+ </para>
+
+ <para>
+ Running 'xsh' on tty* (any ttyXXX device), the user 'us' is given access
+ to the floppy (through membership of the floppy group)
+ </para>
+ <programlisting>xsh;tty*&amp;!ttyp*;us;Al0000-2400;floppy</programlisting>
+
+ <para>
+ Running 'xsh' on tty* (any ttyXXX device), the users 'sword', 'pike' and
+ 'shield' are given access to games (through membership of the floppy group) after work hours.
+ </para>
+ <programlisting>
+xsh; tty* ;sword|pike|shield;!Wk0900-1800;games, sound
+xsh; tty* ;*;Al0900-1800;floppy
+ </programlisting>
+ <para>
+ Any member of the group 'admin' running 'xsh' on tty*,
+ is granted access (at any time) to the group 'plugdev'
+ </para>
+ <programlisting>
+xsh; tty* ;%admin;Al0000-2400;plugdev
+ </programlisting>
+
+ </refsect1>
+
+ <refsect1 id="group.conf-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry><refentrytitle>pam_group</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id="group.conf-author">
+ <title>AUTHOR</title>
+ <para>
+ pam_group was written by Andrew G. Morgan &lt;morgan@kernel.org&gt;.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_group/pam_group.8 b/modules/pam_group/pam_group.8
new file mode 100644
index 0000000..77c7341
--- /dev/null
+++ b/modules/pam_group/pam_group.8
@@ -0,0 +1,109 @@
+'\" t
+.\" Title: pam_group
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_GROUP" "8" "09/03/2021" "Linux-PAM Manual" "Linux-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_group \- PAM module for group access
+.SH "SYNOPSIS"
+.HP \w'\fBpam_group\&.so\fR\ 'u
+\fBpam_group\&.so\fR
+.SH "DESCRIPTION"
+.PP
+The pam_group PAM module does not authenticate the user, but instead it grants group memberships (in the credential setting phase of the authentication module) to the user\&. Such memberships are based on the service they are applying for\&.
+.PP
+By default rules for group memberships are taken from config file
+/etc/security/group\&.conf\&.
+.PP
+This module\*(Aqs usefulness relies on the file\-systems accessible to the user\&. The point being that once granted the membership of a group, the user may attempt to create a
+\fBsetgid\fR
+binary with a restricted group ownership\&. Later, when the user is not given membership to this group, they can recover group membership with the precompiled binary\&. The reason that the file\-systems that the user has access to are so significant, is the fact that when a system is mounted
+\fInosuid\fR
+the user is unable to create or execute such a binary file\&. For this module to provide any level of security, all file\-systems that the user has write access to should be mounted
+\fInosuid\fR\&.
+.PP
+The pam_group module functions in parallel with the
+/etc/group
+file\&. If the user is granted any groups based on the behavior of this module, they are granted
+\fIin addition\fR
+to those entries
+/etc/group
+(or equivalent)\&.
+.SH "OPTIONS"
+.PP
+This module does not recognise any options\&.
+.SH "MODULE TYPES PROVIDED"
+.PP
+Only the
+\fBauth\fR
+module type is provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_SUCCESS
+.RS 4
+group membership was granted\&.
+.RE
+.PP
+PAM_ABORT
+.RS 4
+Not all relevant data could be gotten\&.
+.RE
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_CRED_ERR
+.RS 4
+Group membership was not granted\&.
+.RE
+.PP
+PAM_IGNORE
+.RS 4
+\fBpam_sm_authenticate\fR
+was called which does nothing\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+The user is not known to the system\&.
+.RE
+.SH "FILES"
+.PP
+/etc/security/group\&.conf
+.RS 4
+Default configuration file
+.RE
+.SH "SEE ALSO"
+.PP
+\fBgroup.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)\&.
+.SH "AUTHORS"
+.PP
+pam_group was written by Andrew G\&. Morgan <morgan@kernel\&.org>\&.
diff --git a/modules/pam_group/pam_group.8.xml b/modules/pam_group/pam_group.8.xml
new file mode 100644
index 0000000..2c1c905
--- /dev/null
+++ b/modules/pam_group/pam_group.8.xml
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+
+<refentry id='pam_group'>
+
+ <refmeta>
+ <refentrytitle>pam_group</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id='pam_group-name'>
+ <refname>pam_group</refname>
+ <refpurpose>
+ PAM module for group access
+ </refpurpose>
+ </refnamediv>
+
+<!-- body begins here -->
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_group-cmdsynopsis">
+ <command>pam_group.so</command>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1 id="pam_group-description">
+ <title>DESCRIPTION</title>
+ <para>
+ The pam_group PAM module does not authenticate the user, but instead
+ it grants group memberships (in the credential setting phase of the
+ authentication module) to the user. Such memberships are based on the
+ service they are applying for.
+ </para>
+ <para>
+ By default rules for group memberships are taken from config file
+ <filename>/etc/security/group.conf</filename>.
+ </para>
+ <para>
+ This module's usefulness relies on the file-systems
+ accessible to the user. The point being that once granted the
+ membership of a group, the user may attempt to create a
+ <function>setgid</function> binary with a restricted group ownership.
+ Later, when the user is not given membership to this group, they can
+ recover group membership with the precompiled binary. The reason that
+ the file-systems that the user has access to are so significant, is the
+ fact that when a system is mounted <emphasis>nosuid</emphasis> the user
+ is unable to create or execute such a binary file. For this module to
+ provide any level of security, all file-systems that the user has write
+ access to should be mounted <emphasis>nosuid</emphasis>.
+ </para>
+ <para>
+ The pam_group module functions in parallel with the
+ <filename>/etc/group</filename> file. If the user is granted any groups
+ based on the behavior of this module, they are granted
+ <emphasis>in addition</emphasis> to those entries
+ <filename>/etc/group</filename> (or equivalent).
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_group-options">
+ <title>OPTIONS</title>
+ <para>This module does not recognise any options.</para>
+ </refsect1>
+
+ <refsect1 id="pam_group-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ Only the <option>auth</option> module type is provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_group-return_values">
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ group membership was granted.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_ABORT</term>
+ <listitem>
+ <para>
+ Not all relevant data could be gotten.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory buffer error.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_CRED_ERR</term>
+ <listitem>
+ <para>
+ Group membership was not granted.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ <function>pam_sm_authenticate</function> was called which does nothing.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ The user is not known to the system.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_group-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/security/group.conf</filename></term>
+ <listitem>
+ <para>Default configuration file</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_group-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>group.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_group-authors">
+ <title>AUTHORS</title>
+ <para>
+ pam_group was written by Andrew G. Morgan &lt;morgan@kernel.org&gt;.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_group/pam_group.c b/modules/pam_group/pam_group.c
new file mode 100644
index 0000000..d9a35ea
--- /dev/null
+++ b/modules/pam_group/pam_group.c
@@ -0,0 +1,815 @@
+/*
+ * pam_group module
+ *
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/7/6
+ * Field parsing rewritten by Tomas Mraz <tm@t8m.info>
+ */
+
+#include "config.h"
+
+#include <sys/file.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <time.h>
+#include <syslog.h>
+#include <string.h>
+
+#include <grp.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <netdb.h>
+
+#define PAM_GROUP_BUFLEN 1000
+#define FIELD_SEPARATOR ';' /* this is new as of .02 */
+
+#ifndef TRUE
+# define TRUE 1
+#endif
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+typedef enum { AND, OR } operator;
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+
+/* --- static functions for checking whether the user should be let in --- */
+
+static char *
+shift_buf(char *mem, int from)
+{
+ char *start = mem;
+ while ((*mem = mem[from]) != '\0')
+ ++mem;
+ memset(mem, '\0', PAM_GROUP_BUFLEN - (mem - start));
+ return mem;
+}
+
+static void
+trim_spaces(char *buf, char *from)
+{
+ while (from > buf) {
+ --from;
+ if (*from == ' ')
+ *from = '\0';
+ else
+ break;
+ }
+}
+
+#define STATE_NL 0 /* new line starting */
+#define STATE_COMMENT 1 /* inside comment */
+#define STATE_FIELD 2 /* field following */
+#define STATE_EOF 3 /* end of file or error */
+
+static int
+read_field(const pam_handle_t *pamh, int fd, char **buf, int *from, int *state)
+{
+ char *to;
+ char *src;
+ int i;
+ char c;
+ int onspace;
+
+ /* is buf set ? */
+ if (! *buf) {
+ *buf = (char *) calloc(1, PAM_GROUP_BUFLEN+1);
+ if (! *buf) {
+ pam_syslog(pamh, LOG_CRIT, "out of memory");
+ D(("no memory"));
+ *state = STATE_EOF;
+ return -1;
+ }
+ *from = 0;
+ *state = STATE_NL;
+ fd = open(PAM_GROUP_CONF, O_RDONLY);
+ if (fd < 0) {
+ pam_syslog(pamh, LOG_ERR, "error opening %s: %m", PAM_GROUP_CONF);
+ _pam_drop(*buf);
+ *state = STATE_EOF;
+ return -1;
+ }
+ }
+
+ if (*from > 0)
+ to = shift_buf(*buf, *from);
+ else
+ to = *buf;
+
+ while (fd != -1 && to - *buf < PAM_GROUP_BUFLEN) {
+ i = pam_modutil_read(fd, to, PAM_GROUP_BUFLEN - (to - *buf));
+ if (i < 0) {
+ pam_syslog(pamh, LOG_ERR, "error reading %s: %m", PAM_GROUP_CONF);
+ close(fd);
+ memset(*buf, 0, PAM_GROUP_BUFLEN);
+ _pam_drop(*buf);
+ *state = STATE_EOF;
+ return -1;
+ } else if (!i) {
+ close(fd);
+ fd = -1; /* end of file reached */
+ }
+
+ to += i;
+ }
+
+ if (to == *buf) {
+ /* nothing previously in buf, nothing read */
+ _pam_drop(*buf);
+ *state = STATE_EOF;
+ return -1;
+ }
+
+ memset(to, '\0', PAM_GROUP_BUFLEN - (to - *buf));
+
+ to = *buf;
+ onspace = 1; /* delete any leading spaces */
+
+ for (src = to; (c=*src) != '\0'; ++src) {
+ if (*state == STATE_COMMENT && c != '\n') {
+ continue;
+ }
+
+ switch (c) {
+ case '\n':
+ *state = STATE_NL;
+ *to = '\0';
+ *from = (src - *buf) + 1;
+ trim_spaces(*buf, to);
+ return fd;
+
+ case '\t':
+ case ' ':
+ if (!onspace) {
+ onspace = 1;
+ *to++ = ' ';
+ }
+ break;
+
+ case '!':
+ onspace = 1; /* ignore following spaces */
+ *to++ = '!';
+ break;
+
+ case '#':
+ *state = STATE_COMMENT;
+ break;
+
+ case FIELD_SEPARATOR:
+ *state = STATE_FIELD;
+ *to = '\0';
+ *from = (src - *buf) + 1;
+ trim_spaces(*buf, to);
+ return fd;
+
+ case '\\':
+ if (src[1] == '\n') {
+ ++src; /* skip it */
+ break;
+ }
+ /* fallthrough */
+ default:
+ *to++ = c;
+ onspace = 0;
+ }
+ if (src > to)
+ *src = '\0'; /* clearing */
+ }
+
+ if (*state != STATE_COMMENT) {
+ *state = STATE_COMMENT;
+ pam_syslog(pamh, LOG_ERR, "field too long - ignored");
+ **buf = '\0';
+ } else {
+ *to = '\0';
+ trim_spaces(*buf, to);
+ }
+
+ *from = 0;
+ return fd;
+}
+
+/* read a member from a field */
+
+static int logic_member(const char *string, int *at)
+{
+ int c,to;
+ int done=0;
+ int token=0;
+
+ to=*at;
+ do {
+ c = string[to++];
+
+ switch (c) {
+
+ case '\0':
+ --to;
+ done = 1;
+ break;
+
+ case '&':
+ case '|':
+ case '!':
+ if (token) {
+ --to;
+ }
+ done = 1;
+ break;
+
+ default:
+ if (isalpha(c) || c == '*' || isdigit(c) || c == '_'
+ || c == '-' || c == '.' || c == '/' || c == ':') {
+ token = 1;
+ } else if (token) {
+ --to;
+ done = 1;
+ } else {
+ ++*at;
+ }
+ }
+ } while (!done);
+
+ return to - *at;
+}
+
+typedef enum { VAL, OP } expect;
+
+static int
+logic_field (const pam_handle_t *pamh, const void *me,
+ const char *x, int rule,
+ int (*agrees)(const pam_handle_t *pamh, const void *,
+ const char *, int, int))
+{
+ int left=FALSE, right, not=FALSE;
+ operator oper=OR;
+ int at=0, l;
+ expect next=VAL;
+
+ while ((l = logic_member(x,&at))) {
+ int c = x[at];
+
+ if (next == VAL) {
+ if (c == '!')
+ not = !not;
+ else if (isalpha(c) || c == '*' || isdigit(c) || c == '_'
+ || c == '-' || c == '.' || c == '/' || c == ':') {
+ right = not ^ agrees(pamh, me, x+at, l, rule);
+ if (oper == AND)
+ left &= right;
+ else
+ left |= right;
+ next = OP;
+ } else {
+ pam_syslog(pamh, LOG_ERR,
+ "garbled syntax; expected name (rule #%d)",
+ rule);
+ return FALSE;
+ }
+ } else { /* OP */
+ switch (c) {
+ case '&':
+ oper = AND;
+ break;
+ case '|':
+ oper = OR;
+ break;
+ default:
+ pam_syslog(pamh, LOG_ERR,
+ "garbled syntax; expected & or | (rule #%d)",
+ rule);
+ D(("%c at %d",c,at));
+ return FALSE;
+ }
+ next = VAL;
+ not = FALSE;
+ }
+ at += l;
+ }
+
+ return left;
+}
+
+static int
+is_same (const pam_handle_t *pamh UNUSED,
+ const void *A, const char *b, int len, int rule UNUSED)
+{
+ int i;
+ const char *a;
+
+ a = A;
+ for (i=0; len > 0; ++i, --len) {
+ if (b[i] != a[i]) {
+ if (b[i++] == '*') {
+ return (!--len || !strncmp(b+i,a+strlen(a)-len,len));
+ } else
+ return FALSE;
+ }
+ }
+
+ /* Ok, we know that b is a substring from A and does not contain
+ wildcards, but now the length of both strings must be the same,
+ too. In this case it means, a[i] has to be the end of the string. */
+ if (a[i] != '\0')
+ return FALSE;
+
+ return ( !len );
+}
+
+typedef struct {
+ int day; /* array of 7 bits, one set for today */
+ int minute; /* integer, hour*100+minute for now */
+} TIME;
+
+static struct day {
+ const char *d;
+ int bit;
+} const days[11] = {
+ { "su", 01 },
+ { "mo", 02 },
+ { "tu", 04 },
+ { "we", 010 },
+ { "th", 020 },
+ { "fr", 040 },
+ { "sa", 0100 },
+ { "wk", 076 },
+ { "wd", 0101 },
+ { "al", 0177 },
+ { NULL, 0 }
+};
+
+static TIME time_now(void)
+{
+ struct tm *local;
+ time_t the_time;
+ TIME this;
+
+ the_time = time((time_t *)0); /* get the current time */
+ local = localtime(&the_time);
+ this.day = days[local->tm_wday].bit;
+ this.minute = local->tm_hour*100 + local->tm_min;
+
+ D(("day: 0%o, time: %.4d", this.day, this.minute));
+ return this;
+}
+
+/* take the current date and see if the range "date" passes it */
+static int
+check_time (const pam_handle_t *pamh, const void *AT,
+ const char *times, int len, int rule)
+{
+ int not,pass;
+ int marked_day, time_start, time_end;
+ const TIME *at;
+ int i,j=0;
+
+ at = AT;
+ D(("checking: 0%o/%.4d vs. %s", at->day, at->minute, times));
+
+ if (times == NULL) {
+ /* this should not happen */
+ pam_syslog(pamh, LOG_CRIT, "internal error in file %s at line %d",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ if (times[j] == '!') {
+ ++j;
+ not = TRUE;
+ } else {
+ not = FALSE;
+ }
+
+ for (marked_day = 0; len > 0 && isalpha(times[j]); --len) {
+ int this_day=-1;
+
+ D(("%c%c ?", times[j], times[j+1]));
+ for (i=0; days[i].d != NULL; ++i) {
+ if (tolower(times[j]) == days[i].d[0]
+ && tolower(times[j+1]) == days[i].d[1] ) {
+ this_day = days[i].bit;
+ break;
+ }
+ }
+ j += 2;
+ if (this_day == -1) {
+ pam_syslog(pamh, LOG_ERR, "bad day specified (rule #%d)", rule);
+ return FALSE;
+ }
+ marked_day ^= this_day;
+ }
+ if (marked_day == 0) {
+ pam_syslog(pamh, LOG_ERR, "no day specified");
+ return FALSE;
+ }
+ D(("day range = 0%o", marked_day));
+
+ time_start = 0;
+ for (i=0; len > 0 && i < 4 && isdigit(times[i+j]); ++i, --len) {
+ time_start *= 10;
+ time_start += times[i+j]-'0'; /* is this portable? */
+ }
+ j += i;
+
+ if (times[j] == '-') {
+ time_end = 0;
+ for (i=1; len > 0 && i < 5 && isdigit(times[i+j]); ++i, --len) {
+ time_end *= 10;
+ time_end += times[i+j]-'0'; /* is this portable? */
+ }
+ j += i;
+ } else
+ time_end = -1;
+
+ D(("i=%d, time_end=%d, times[j]='%c'", i, time_end, times[j]));
+ if (i != 5 || time_end == -1) {
+ pam_syslog(pamh, LOG_ERR, "no/bad times specified (rule #%d)", rule);
+ return TRUE;
+ }
+ D(("times(%d to %d)", time_start,time_end));
+ D(("marked_day = 0%o", marked_day));
+
+ /* compare with the actual time now */
+
+ pass = FALSE;
+ if (time_start < time_end) { /* start < end ? --> same day */
+ if ((at->day & marked_day) && (at->minute >= time_start)
+ && (at->minute < time_end)) {
+ D(("time is listed"));
+ pass = TRUE;
+ }
+ } else { /* spans two days */
+ if ((at->day & marked_day) && (at->minute >= time_start)) {
+ D(("caught on first day"));
+ pass = TRUE;
+ } else {
+ marked_day <<= 1;
+ marked_day |= (marked_day & 0200) ? 1:0;
+ D(("next day = 0%o", marked_day));
+ if ((at->day & marked_day) && (at->minute <= time_end)) {
+ D(("caught on second day"));
+ pass = TRUE;
+ }
+ }
+ }
+
+ return (not ^ pass);
+}
+
+static int find_member(const char *string, int *at)
+{
+ int c,to;
+ int done=0;
+ int token=0;
+
+ to=*at;
+ do {
+ c = string[to++];
+
+ switch (c) {
+
+ case '\0':
+ --to;
+ done = 1;
+ break;
+
+ case '&':
+ case '|':
+ case '!':
+ if (token) {
+ --to;
+ }
+ done = 1;
+ break;
+
+ default:
+ if (isalpha(c) || isdigit(c) || c == '_' || c == '*'
+ || c == '-') {
+ token = 1;
+ } else if (token) {
+ --to;
+ done = 1;
+ } else {
+ ++*at;
+ }
+ }
+ } while (!done);
+
+ return to - *at;
+}
+
+#define GROUP_BLK 10
+#define blk_size(len) (((len-1 + GROUP_BLK)/GROUP_BLK)*GROUP_BLK)
+
+static int mkgrplist(pam_handle_t *pamh, char *buf, gid_t **list, int len)
+{
+ int l,at=0;
+ int blks;
+
+ blks = blk_size(len);
+ D(("cf. blks=%d and len=%d", blks,len));
+
+ while ((l = find_member(buf,&at))) {
+ int edge;
+
+ if (len >= blks) {
+ gid_t *tmp;
+
+ D(("allocating new block"));
+ tmp = (gid_t *) realloc((*list)
+ , sizeof(gid_t) * (blks += GROUP_BLK));
+ if (tmp != NULL) {
+ (*list) = tmp;
+ } else {
+ pam_syslog(pamh, LOG_ERR, "out of memory for group list");
+ free(*list);
+ (*list) = NULL;
+ return -1;
+ }
+ }
+
+ /* '\0' terminate the entry */
+
+ edge = (buf[at+l]) ? 1:0;
+ buf[at+l] = '\0';
+ D(("found group: %s",buf+at));
+
+ /* this is where we convert a group name to a gid_t */
+ {
+ const struct group *grp;
+
+ grp = pam_modutil_getgrnam(pamh, buf+at);
+ if (grp == NULL) {
+ pam_syslog(pamh, LOG_ERR, "bad group: %s", buf+at);
+ } else {
+ D(("group %s exists", buf+at));
+ (*list)[len++] = grp->gr_gid;
+ }
+ }
+
+ /* next entry along */
+
+ at += l + edge;
+ }
+ D(("returning with [%p/len=%d]->%p",list,len,*list));
+ return len;
+}
+
+
+static int check_account(pam_handle_t *pamh, const char *service,
+ const char *tty, const char *user)
+{
+ int from=0, state=STATE_NL, fd=-1;
+ char *buffer=NULL;
+ int count=0;
+ TIME here_and_now;
+ int retval=PAM_SUCCESS;
+ gid_t *grps;
+ int no_grps;
+
+ /*
+ * first we get the current list of groups - the application
+ * will have previously done an initgroups(), or equivalent.
+ */
+
+ D(("counting supplementary groups"));
+ no_grps = getgroups(0, NULL); /* find the current number of groups */
+ if (no_grps > 0) {
+ grps = calloc( blk_size(no_grps) , sizeof(gid_t) );
+ D(("copying current list into grps [%d big]",blk_size(no_grps)));
+ if (getgroups(no_grps, grps) < 0) {
+ D(("getgroups call failed"));
+ no_grps = 0;
+ _pam_drop(grps);
+ }
+#ifdef PAM_DEBUG
+ {
+ int z;
+ for (z=0; z<no_grps; ++z) {
+ D(("gid[%d]=%d", z, grps[z]));
+ }
+ }
+#endif
+ } else {
+ D(("no supplementary groups known"));
+ no_grps = 0;
+ grps = NULL;
+ }
+
+ here_and_now = time_now(); /* find current time */
+
+ /* parse the rules in the configuration file */
+ do {
+ int good=TRUE;
+
+ /* here we get the service name field */
+
+ fd = read_field(pamh, fd, &buffer, &from, &state);
+ if (!buffer || !buffer[0]) {
+ /* empty line .. ? */
+ continue;
+ }
+ ++count;
+ D(("working on rule #%d",count));
+
+ if (state != STATE_FIELD) {
+ pam_syslog(pamh, LOG_ERR,
+ "%s: malformed rule #%d", PAM_GROUP_CONF, count);
+ continue;
+ }
+
+ good = logic_field(pamh,service, buffer, count, is_same);
+ D(("with service: %s", good ? "passes":"fails" ));
+
+ /* here we get the terminal name field */
+
+ fd = read_field(pamh, fd, &buffer, &from, &state);
+ if (state != STATE_FIELD) {
+ pam_syslog(pamh, LOG_ERR,
+ "%s: malformed rule #%d", PAM_GROUP_CONF, count);
+ continue;
+ }
+ good &= logic_field(pamh,tty, buffer, count, is_same);
+ D(("with tty: %s", good ? "passes":"fails" ));
+
+ /* here we get the username field */
+
+ fd = read_field(pamh, fd, &buffer, &from, &state);
+ if (state != STATE_FIELD) {
+ pam_syslog(pamh, LOG_ERR,
+ "%s: malformed rule #%d", PAM_GROUP_CONF, count);
+ continue;
+ }
+ /* If buffer starts with @, we are using netgroups */
+ if (buffer[0] == '@')
+#ifdef HAVE_INNETGR
+ good &= innetgr (&buffer[1], NULL, user, NULL);
+#else
+ pam_syslog (pamh, LOG_ERR, "pam_group does not have netgroup support");
+#endif
+ /* otherwise, if the buffer starts with %, it's a UNIX group */
+ else if (buffer[0] == '%')
+ good &= pam_modutil_user_in_group_nam_nam(pamh, user, &buffer[1]);
+ else
+ good &= logic_field(pamh,user, buffer, count, is_same);
+ D(("with user: %s", good ? "passes":"fails" ));
+
+ /* here we get the time field */
+
+ fd = read_field(pamh, fd, &buffer, &from, &state);
+ if (state != STATE_FIELD) {
+ pam_syslog(pamh, LOG_ERR,
+ "%s: malformed rule #%d", PAM_GROUP_CONF, count);
+ continue;
+ }
+
+ good &= logic_field(pamh,&here_and_now, buffer, count, check_time);
+ D(("with time: %s", good ? "passes":"fails" ));
+
+ fd = read_field(pamh, fd, &buffer, &from, &state);
+ if (state == STATE_FIELD) {
+ pam_syslog(pamh, LOG_ERR,
+ "%s: poorly terminated rule #%d", PAM_GROUP_CONF, count);
+ continue;
+ }
+
+ /*
+ * so we have a list of groups, we need to turn it into
+ * something to send to setgroups(2)
+ */
+
+ if (good) {
+ D(("adding %s to gid list", buffer));
+ good = mkgrplist(pamh, buffer, &grps, no_grps);
+ if (good < 0) {
+ no_grps = 0;
+ } else {
+ no_grps = good;
+ }
+ }
+
+ if (good > 0) {
+ D(("rule #%d passed, added %d groups", count, good));
+ } else if (good < 0) {
+ retval = PAM_BUF_ERR;
+ } else {
+ D(("rule #%d failed", count));
+ }
+
+ } while (state != STATE_EOF);
+
+ /* now set the groups for the user */
+
+ if (no_grps > 0) {
+#ifdef PAM_DEBUG
+ int err;
+#endif
+ D(("trying to set %d groups", no_grps));
+#ifdef PAM_DEBUG
+ for (err=0; err<no_grps; ++err) {
+ D(("gid[%d]=%d", err, grps[err]));
+ }
+#endif
+ if (setgroups(no_grps, grps) != 0) {
+ D(("but couldn't set groups %m"));
+ pam_syslog(pamh, LOG_ERR,
+ "unable to set the group membership for user: %m");
+ retval = PAM_CRED_ERR;
+ }
+ }
+
+ if (grps) { /* tidy up */
+ memset(grps, 0, sizeof(gid_t) * blk_size(no_grps));
+ _pam_drop(grps);
+ no_grps = 0;
+ }
+
+ return retval;
+}
+
+/* --- public authentication management functions --- */
+
+int
+pam_sm_authenticate (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_IGNORE;
+}
+
+int
+pam_sm_setcred (pam_handle_t *pamh, int flags,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ const void *service=NULL, *void_tty=NULL;
+ const char *user=NULL;
+ const char *tty;
+ int retval;
+ unsigned setting;
+
+ /* only interested in establishing credentials */
+
+ setting = flags;
+ if (!(setting & (PAM_ESTABLISH_CRED | PAM_REINITIALIZE_CRED))) {
+ D(("ignoring call - not for establishing credentials"));
+ return PAM_SUCCESS; /* don't fail because of this */
+ }
+
+ /* set service name */
+
+ if (pam_get_item(pamh, PAM_SERVICE, &service)
+ != PAM_SUCCESS || service == NULL) {
+ pam_syslog(pamh, LOG_ERR, "cannot find the current service name");
+ return PAM_ABORT;
+ }
+
+ /* set username */
+
+ if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS || *user == '\0') {
+ pam_syslog(pamh, LOG_NOTICE, "cannot determine user name");
+ return PAM_USER_UNKNOWN;
+ }
+
+ /* set tty name */
+
+ if (pam_get_item(pamh, PAM_TTY, &void_tty) != PAM_SUCCESS
+ || void_tty == NULL) {
+ D(("PAM_TTY not set, probing stdin"));
+ tty = ttyname(STDIN_FILENO);
+ if (tty == NULL) {
+ tty = "";
+ }
+ if (pam_set_item(pamh, PAM_TTY, tty) != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR, "couldn't set tty name");
+ return PAM_ABORT;
+ }
+ }
+ else
+ tty = (const char *) void_tty;
+
+ if (tty[0] == '/') { /* full path */
+ const char *t;
+ tty++;
+ if ((t = strchr(tty, '/')) != NULL) {
+ tty = t + 1;
+ }
+ }
+
+ /* good, now we have the service name, the user and the terminal name */
+
+ D(("service=%s", service));
+ D(("user=%s", user));
+ D(("tty=%s", tty));
+
+ retval = check_account(pamh,service,tty,user); /* get groups */
+
+ return retval;
+}
+
+/* end of module definition */
diff --git a/modules/pam_group/tst-pam_group b/modules/pam_group/tst-pam_group
new file mode 100755
index 0000000..29f7ba0
--- /dev/null
+++ b/modules/pam_group/tst-pam_group
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_group.so
diff --git a/modules/pam_issue/Makefile.am b/modules/pam_issue/Makefile.am
new file mode 100644
index 0000000..1b26c31
--- /dev/null
+++ b/modules/pam_issue/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_issue.8
+endif
+XMLS = README.xml pam_issue.8.xml
+dist_check_SCRIPTS = tst-pam_issue
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_issue.la
+pam_issue_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_issue/Makefile.in b/modules/pam_issue/Makefile.in
new file mode 100644
index 0000000..91627c5
--- /dev/null
+++ b/modules/pam_issue/Makefile.in
@@ -0,0 +1,1150 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_issue
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_issue_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_issue_la_SOURCES = pam_issue.c
+pam_issue_la_OBJECTS = pam_issue.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_issue.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_issue.c
+DIST_SOURCES = pam_issue.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_issue.8
+XMLS = README.xml pam_issue.8.xml
+dist_check_SCRIPTS = tst-pam_issue
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_issue.la
+pam_issue_la_LIBADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_issue/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_issue/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_issue.la: $(pam_issue_la_OBJECTS) $(pam_issue_la_DEPENDENCIES) $(EXTRA_pam_issue_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_issue_la_OBJECTS) $(pam_issue_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_issue.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_issue.log: tst-pam_issue
+ @p='tst-pam_issue'; \
+ b='tst-pam_issue'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_issue.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_issue.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_issue/README b/modules/pam_issue/README
new file mode 100644
index 0000000..e3192be
--- /dev/null
+++ b/modules/pam_issue/README
@@ -0,0 +1,79 @@
+pam_issue — PAM module to add issue file to user prompt
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+pam_issue is a PAM module to prepend an issue file to the username prompt. It
+also by default parses escape codes in the issue file similar to some common
+getty's (using \x format).
+
+Recognized escapes:
+
+\d
+
+ current day
+
+\l
+
+ name of this tty
+
+\m
+
+ machine architecture (uname -m)
+
+\n
+
+ machine's network node hostname (uname -n)
+
+\o
+
+ domain name of this system
+
+\r
+
+ release number of operating system (uname -r)
+
+\t
+
+ current time
+
+\s
+
+ operating system name (uname -s)
+
+\u
+
+ number of users currently logged in
+
+\U
+
+ same as \u except it is suffixed with "user" or "users" (eg. "1 user" or
+ "10 users")
+
+\v
+
+ operating system version and build date (uname -v)
+
+OPTIONS
+
+noesc
+
+ Turns off escape code parsing.
+
+issue=issue-file-name
+
+ The file to output if not using the default.
+
+EXAMPLES
+
+Add the following line to /etc/pam.d/login to set the user specific issue at
+login:
+
+ auth optional pam_issue.so issue=/etc/issue
+
+
+AUTHOR
+
+pam_issue was written by Ben Collins <bcollins@debian.org>.
+
diff --git a/modules/pam_issue/README.xml b/modules/pam_issue/README.xml
new file mode 100644
index 0000000..b5b61c3
--- /dev/null
+++ b/modules/pam_issue/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_issue.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_issue.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_issue-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_issue.8.xml" xpointer='xpointer(//refsect1[@id = "pam_issue-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_issue.8.xml" xpointer='xpointer(//refsect1[@id = "pam_issue-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_issue.8.xml" xpointer='xpointer(//refsect1[@id = "pam_issue-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_issue.8.xml" xpointer='xpointer(//refsect1[@id = "pam_issue-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_issue/pam_issue.8 b/modules/pam_issue/pam_issue.8
new file mode 100644
index 0000000..810406e
--- /dev/null
+++ b/modules/pam_issue/pam_issue.8
@@ -0,0 +1,158 @@
+'\" t
+.\" Title: pam_issue
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_ISSUE" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_issue \- PAM module to add issue file to user prompt
+.SH "SYNOPSIS"
+.HP \w'\fBpam_issue\&.so\fR\ 'u
+\fBpam_issue\&.so\fR [noesc] [issue=\fIissue\-file\-name\fR]
+.SH "DESCRIPTION"
+.PP
+pam_issue is a PAM module to prepend an issue file to the username prompt\&. It also by default parses escape codes in the issue file similar to some common getty\*(Aqs (using \ex format)\&.
+.PP
+Recognized escapes:
+.PP
+\fB\ed\fR
+.RS 4
+current day
+.RE
+.PP
+\fB\el\fR
+.RS 4
+name of this tty
+.RE
+.PP
+\fB\em\fR
+.RS 4
+machine architecture (uname \-m)
+.RE
+.PP
+\fB\en\fR
+.RS 4
+machine\*(Aqs network node hostname (uname \-n)
+.RE
+.PP
+\fB\eo\fR
+.RS 4
+domain name of this system
+.RE
+.PP
+\fB\er\fR
+.RS 4
+release number of operating system (uname \-r)
+.RE
+.PP
+\fB\et\fR
+.RS 4
+current time
+.RE
+.PP
+\fB\es\fR
+.RS 4
+operating system name (uname \-s)
+.RE
+.PP
+\fB\eu\fR
+.RS 4
+number of users currently logged in
+.RE
+.PP
+\fB\eU\fR
+.RS 4
+same as \eu except it is suffixed with "user" or "users" (eg\&. "1 user" or "10 users")
+.RE
+.PP
+\fB\ev\fR
+.RS 4
+operating system version and build date (uname \-v)
+.RE
+.SH "OPTIONS"
+.PP
+.PP
+\fBnoesc\fR
+.RS 4
+Turns off escape code parsing\&.
+.RE
+.PP
+\fBissue=\fR\fB\fIissue\-file\-name\fR\fR
+.RS 4
+The file to output if not using the default\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+Only the
+\fBauth\fR
+module type is provided\&.
+.SH "RETURN VALUES"
+.PP
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_IGNORE
+.RS 4
+The prompt was already changed\&.
+.RE
+.PP
+PAM_SERVICE_ERR
+.RS 4
+A service module error occurred\&.
+.RE
+.PP
+PAM_SUCCESS
+.RS 4
+The new prompt was set successfully\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Add the following line to
+/etc/pam\&.d/login
+to set the user specific issue at login:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ auth optional pam_issue\&.so issue=/etc/issue
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.PP
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_issue was written by Ben Collins <bcollins@debian\&.org>\&.
diff --git a/modules/pam_issue/pam_issue.8.xml b/modules/pam_issue/pam_issue.8.xml
new file mode 100644
index 0000000..fb9b737
--- /dev/null
+++ b/modules/pam_issue/pam_issue.8.xml
@@ -0,0 +1,234 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_issue">
+
+ <refmeta>
+ <refentrytitle>pam_issue</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_issue-name">
+ <refname>pam_issue</refname>
+ <refpurpose>PAM module to add issue file to user prompt</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_issue-cmdsynopsis">
+ <command>pam_issue.so</command>
+ <arg choice="opt">
+ noesc
+ </arg>
+ <arg choice="opt">
+ issue=<replaceable>issue-file-name</replaceable>
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_issue-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ pam_issue is a PAM module to prepend an issue file to the username
+ prompt. It also by default parses escape codes in the issue file
+ similar to some common getty's (using &bsol;x format).
+ </para>
+ <para>
+ Recognized escapes:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term><emphasis remap='B'>&bsol;d</emphasis></term>
+ <listitem>
+ <para>current day</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>&bsol;l</emphasis></term>
+ <listitem>
+ <para>name of this tty</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>&bsol;m</emphasis></term>
+ <listitem>
+ <para>machine architecture (uname -m)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>&bsol;n</emphasis></term>
+ <listitem>
+ <para>machine's network node hostname (uname -n)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>&bsol;o</emphasis></term>
+ <listitem>
+ <para>domain name of this system</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>&bsol;r</emphasis></term>
+ <listitem>
+ <para>release number of operating system (uname -r)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>&bsol;t</emphasis></term>
+ <listitem>
+ <para>current time</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>&bsol;s</emphasis></term>
+ <listitem>
+ <para>operating system name (uname -s)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>&bsol;u</emphasis></term>
+ <listitem>
+ <para>number of users currently logged in</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>&bsol;U</emphasis></term>
+ <listitem>
+ <para>
+ same as &bsol;u except it is suffixed with "user" or
+ "users" (eg. "1 user" or "10 users")
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><emphasis remap='B'>&bsol;v</emphasis></term>
+ <listitem>
+ <para>operating system version and build date (uname -v)</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </refsect1>
+
+ <refsect1 id="pam_issue-options">
+
+ <title>OPTIONS</title>
+ <para>
+ <variablelist>
+
+ <varlistentry>
+ <term>
+ <option>noesc</option>
+ </term>
+ <listitem>
+ <para>
+ Turns off escape code parsing.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>issue=<replaceable>issue-file-name</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The file to output if not using the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_issue-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ Only the <option>auth</option> module type is provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_issue-return_values'>
+ <title>RETURN VALUES</title>
+ <para>
+ <variablelist>
+
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory buffer error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ The prompt was already changed.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ A service module error occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ The new prompt was set successfully.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_issue-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ Add the following line to <filename>/etc/pam.d/login</filename> to
+ set the user specific issue at login:
+ <programlisting>
+ auth optional pam_issue.so issue=/etc/issue
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_issue-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_issue-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_issue was written by Ben Collins &lt;bcollins@debian.org&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_issue/pam_issue.c b/modules/pam_issue/pam_issue.c
new file mode 100644
index 0000000..5b6a466
--- /dev/null
+++ b/modules/pam_issue/pam_issue.c
@@ -0,0 +1,306 @@
+/*
+ * pam_issue module - a simple /etc/issue parser to set PAM_USER_PROMPT
+ *
+ * Copyright 1999 by Ben Collins <bcollins@debian.org>
+ *
+ * Needs to be called before any other auth modules so we can setup the
+ * user prompt before it's first used. Allows one argument option, which
+ * is the full path to a file to be used for issue (uses /etc/issue as a
+ * default) such as "issue=/etc/issue.telnet".
+ *
+ * We can also parse escapes within the the issue file (enabled by
+ * default, but can be disabled with the "noesc" option). It's the exact
+ * same parsing as util-linux's agetty program performs.
+ *
+ * Released under the GNU LGPL version 2 or later
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/utsname.h>
+#include <utmp.h>
+#include <time.h>
+#include <syslog.h>
+
+#include <security/_pam_macros.h>
+#include <security/pam_modules.h>
+#include <security/pam_ext.h>
+#include "pam_inline.h"
+
+static int _user_prompt_set = 0;
+
+static int read_issue_raw(pam_handle_t *pamh, FILE *fp, char **prompt);
+static int read_issue_quoted(pam_handle_t *pamh, FILE *fp, char **prompt);
+
+/* --- authentication management functions (only) --- */
+
+int
+pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ int retval = PAM_SERVICE_ERR;
+ FILE *fp;
+ const char *issue_file = NULL;
+ int parse_esc = 1;
+ const void *item = NULL;
+ const char *cur_prompt;
+ char *issue_prompt = NULL;
+
+ /* If we've already set the prompt, don't set it again */
+ if(_user_prompt_set)
+ return PAM_IGNORE;
+
+ /* We set this here so if we fail below, we won't get further
+ than this next time around (only one real failure) */
+ _user_prompt_set = 1;
+
+ for ( ; argc-- > 0 ; ++argv ) {
+ const char *str;
+
+ if ((str = pam_str_skip_prefix(*argv, "issue=")) != NULL) {
+ issue_file = str;
+ D(("set issue_file to: %s", issue_file));
+ } else if (!strcmp(*argv,"noesc")) {
+ parse_esc = 0;
+ D(("turning off escape parsing by request"));
+ } else
+ D(("unknown option passed: %s", *argv));
+ }
+
+ if (issue_file == NULL)
+ issue_file = "/etc/issue";
+
+ if ((fp = fopen(issue_file, "r")) == NULL) {
+ pam_syslog(pamh, LOG_ERR, "error opening %s: %m", issue_file);
+ return PAM_SERVICE_ERR;
+ }
+
+ if ((retval = pam_get_item(pamh, PAM_USER_PROMPT, &item)) != PAM_SUCCESS) {
+ fclose(fp);
+ return retval;
+ }
+
+ cur_prompt = item;
+ if (cur_prompt == NULL)
+ cur_prompt = "";
+
+ if (parse_esc)
+ retval = read_issue_quoted(pamh, fp, &issue_prompt);
+ else
+ retval = read_issue_raw(pamh, fp, &issue_prompt);
+
+ fclose(fp);
+
+ if (retval != PAM_SUCCESS)
+ goto out;
+
+ {
+ size_t size = strlen(issue_prompt) + strlen(cur_prompt) + 1;
+ char *new_prompt = realloc(issue_prompt, size);
+
+ if (new_prompt == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "out of memory");
+ retval = PAM_BUF_ERR;
+ goto out;
+ }
+ issue_prompt = new_prompt;
+ }
+
+ strcat(issue_prompt, cur_prompt);
+ retval = pam_set_item(pamh, PAM_USER_PROMPT,
+ (const void *) issue_prompt);
+ out:
+ _pam_drop(issue_prompt);
+ return (retval == PAM_SUCCESS) ? PAM_IGNORE : retval;
+}
+
+int
+pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_IGNORE;
+}
+
+static int
+read_issue_raw(pam_handle_t *pamh, FILE *fp, char **prompt)
+{
+ char *issue;
+ struct stat st;
+
+ *prompt = NULL;
+
+ if (fstat(fileno(fp), &st) < 0) {
+ pam_syslog(pamh, LOG_ERR, "stat error: %m");
+ return PAM_SERVICE_ERR;
+ }
+
+ if ((issue = malloc(st.st_size + 1)) == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "out of memory");
+ return PAM_BUF_ERR;
+ }
+
+ if ((off_t)fread(issue, 1, st.st_size, fp) != st.st_size) {
+ pam_syslog(pamh, LOG_ERR, "read error: %m");
+ _pam_drop(issue);
+ return PAM_SERVICE_ERR;
+ }
+
+ issue[st.st_size] = '\0';
+ *prompt = issue;
+ return PAM_SUCCESS;
+}
+
+static int
+read_issue_quoted(pam_handle_t *pamh, FILE *fp, char **prompt)
+{
+ int c;
+ size_t size = 1024;
+ size_t issue_len = 0;
+ char *issue;
+ struct utsname uts;
+
+ *prompt = NULL;
+
+ if ((issue = malloc(size)) == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "out of memory");
+ return PAM_BUF_ERR;
+ }
+
+ (void) uname(&uts);
+
+ while ((c = getc(fp)) != EOF) {
+ const char *src = NULL;
+ size_t len = 0;
+ char buf[1024] = "";
+
+ if (c == '\\') {
+ if ((c = getc(fp)) == EOF)
+ break;
+ switch (c) {
+ case 's':
+ src = uts.sysname;
+ len = strnlen(uts.sysname, sizeof(uts.sysname));
+ break;
+ case 'n':
+ src = uts.nodename;
+ len = strnlen(uts.nodename, sizeof(uts.nodename));
+ break;
+ case 'r':
+ src = uts.release;
+ len = strnlen(uts.release, sizeof(uts.release));
+ break;
+ case 'v':
+ src = uts.version;
+ len = strnlen(uts.version, sizeof(uts.version));
+ break;
+ case 'm':
+ src = uts.machine;
+ len = strnlen(uts.machine, sizeof(uts.machine));
+ break;
+ case 'o':
+#ifdef HAVE_GETDOMAINNAME
+ if (getdomainname(buf, sizeof(buf)) >= 0)
+ buf[sizeof(buf) - 1] = '\0';
+#endif
+ break;
+ case 'd':
+ case 't':
+ {
+ const char *weekday[] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu",
+ "Fri", "Sat" };
+ const char *month[] = {
+ "Jan", "Feb", "Mar", "Apr", "May",
+ "Jun", "Jul", "Aug", "Sep", "Oct",
+ "Nov", "Dec" };
+ time_t now;
+ struct tm *tm;
+
+ (void) time (&now);
+ tm = localtime(&now);
+
+ if (c == 'd')
+ snprintf (buf, sizeof buf, "%s %s %d %d",
+ weekday[tm->tm_wday], month[tm->tm_mon],
+ tm->tm_mday, tm->tm_year + 1900);
+ else
+ snprintf (buf, sizeof buf, "%02d:%02d:%02d",
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ }
+ break;
+ case 'l':
+ {
+ const char *ttyn = ttyname(1);
+ if (ttyn) {
+ const char *str = pam_str_skip_prefix(ttyn, "/dev/");
+ if (str != NULL)
+ ttyn = str;
+ src = ttyn;
+ len = strlen(ttyn);
+ }
+ }
+ break;
+ case 'u':
+ case 'U':
+ {
+ unsigned int users = 0;
+ struct utmp *ut;
+ setutent();
+ while ((ut = getutent())) {
+ if (ut->ut_type == USER_PROCESS)
+ ++users;
+ }
+ endutent();
+ if (c == 'U')
+ snprintf (buf, sizeof buf, "%u %s", users,
+ (users == 1) ? "user" : "users");
+ else
+ snprintf (buf, sizeof buf, "%u", users);
+ break;
+ }
+ default:
+ buf[0] = c; buf[1] = '\0';
+ }
+ } else {
+ buf[0] = c; buf[1] = '\0';
+ }
+
+ if (src == NULL) {
+ src = buf;
+ len = strlen(buf);
+ }
+ if (issue_len + len + 1 > size) {
+ char *new_issue;
+
+ size += len + 1;
+ new_issue = realloc (issue, size);
+ if (new_issue == NULL) {
+ _pam_drop(issue);
+ return PAM_BUF_ERR;
+ }
+ issue = new_issue;
+ }
+ memcpy(issue + issue_len, src, len);
+ issue_len += len;
+ }
+
+ issue[issue_len] = '\0';
+
+ if (ferror(fp)) {
+ pam_syslog(pamh, LOG_ERR, "read error: %m");
+ _pam_drop(issue);
+ return PAM_SERVICE_ERR;
+ }
+
+ *prompt = issue;
+ return PAM_SUCCESS;
+}
+
+/* end of module definition */
diff --git a/modules/pam_issue/tst-pam_issue b/modules/pam_issue/tst-pam_issue
new file mode 100755
index 0000000..0fe4f76
--- /dev/null
+++ b/modules/pam_issue/tst-pam_issue
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_issue.so
diff --git a/modules/pam_keyinit/Makefile.am b/modules/pam_keyinit/Makefile.am
new file mode 100644
index 0000000..e195331
--- /dev/null
+++ b/modules/pam_keyinit/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2006, 2009 David Howells <dhowells@redhat.com>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_keyinit.8
+endif
+XMLS = README.xml pam_keyinit.8.xml
+dist_check_SCRIPTS = tst-pam_keyinit
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_keyinit.la
+pam_keyinit_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_keyinit/Makefile.in b/modules/pam_keyinit/Makefile.in
new file mode 100644
index 0000000..600c19c
--- /dev/null
+++ b/modules/pam_keyinit/Makefile.in
@@ -0,0 +1,1150 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2006, 2009 David Howells <dhowells@redhat.com>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_keyinit
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_keyinit_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_keyinit_la_SOURCES = pam_keyinit.c
+pam_keyinit_la_OBJECTS = pam_keyinit.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_keyinit.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_keyinit.c
+DIST_SOURCES = pam_keyinit.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_keyinit.8
+XMLS = README.xml pam_keyinit.8.xml
+dist_check_SCRIPTS = tst-pam_keyinit
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_keyinit.la
+pam_keyinit_la_LIBADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_keyinit/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_keyinit/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_keyinit.la: $(pam_keyinit_la_OBJECTS) $(pam_keyinit_la_DEPENDENCIES) $(EXTRA_pam_keyinit_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_keyinit_la_OBJECTS) $(pam_keyinit_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_keyinit.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_keyinit.log: tst-pam_keyinit
+ @p='tst-pam_keyinit'; \
+ b='tst-pam_keyinit'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_keyinit.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_keyinit.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_keyinit/README b/modules/pam_keyinit/README
new file mode 100644
index 0000000..fa50370
--- /dev/null
+++ b/modules/pam_keyinit/README
@@ -0,0 +1,67 @@
+pam_keyinit — Kernel session keyring initialiser module
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+The pam_keyinit PAM module ensures that the invoking process has a session
+keyring other than the user default session keyring.
+
+The module checks to see if the process's session keyring is the
+user-session-keyring(7), and, if it is, creates a new session-keyring(7) with
+which to replace it. If a new session keyring is created, it will install a
+link to the user-keyring(7) in the session keyring so that keys common to the
+user will be automatically accessible through it. The session keyring of the
+invoking process will thenceforth be inherited by all its children unless they
+override it.
+
+In order to allow other PAM modules to attach tokens to the keyring, this
+module provides both an auth (limited to pam_setcred(3) and a session
+component. The session keyring is created in the module called. Moreover this
+module should be included as early as possible in a PAM configuration.
+
+This module is intended primarily for use by login processes. Be aware that
+after the session keyring has been replaced, the old session keyring and the
+keys it contains will no longer be accessible.
+
+This module should not, generally, be invoked by programs like su, since it is
+usually desirable for the key set to percolate through to the alternate
+context. The keys have their own permissions system to manage this.
+
+The keyutils package is used to manipulate keys more directly. This can be
+obtained from:
+
+Keyutils
+
+OPTIONS
+
+debug
+
+ Log debug information with syslog(3).
+
+force
+
+ Causes the session keyring of the invoking process to be replaced
+ unconditionally.
+
+revoke
+
+ Causes the session keyring of the invoking process to be revoked when the
+ invoking process exits if the session keyring was created for this process
+ in the first place.
+
+EXAMPLES
+
+Add this line to your login entries to start each login session with its own
+session keyring:
+
+session required pam_keyinit.so
+
+
+This will prevent keys from one session leaking into another session for the
+same user.
+
+AUTHOR
+
+pam_keyinit was written by David Howells, <dhowells@redhat.com>.
+
diff --git a/modules/pam_keyinit/README.xml b/modules/pam_keyinit/README.xml
new file mode 100644
index 0000000..47659e8
--- /dev/null
+++ b/modules/pam_keyinit/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_keyinit.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_keyinit.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_keyinit-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_keyinit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_keyinit-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_keyinit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_keyinit-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_keyinit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_keyinit-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_keyinit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_keyinit-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_keyinit/pam_keyinit.8 b/modules/pam_keyinit/pam_keyinit.8
new file mode 100644
index 0000000..01bfa52
--- /dev/null
+++ b/modules/pam_keyinit/pam_keyinit.8
@@ -0,0 +1,150 @@
+'\" t
+.\" Title: pam_keyinit
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_KEYINIT" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_keyinit \- Kernel session keyring initialiser module
+.SH "SYNOPSIS"
+.HP \w'\fBpam_keyinit\&.so\fR\ 'u
+\fBpam_keyinit\&.so\fR [debug] [force] [revoke]
+.SH "DESCRIPTION"
+.PP
+The pam_keyinit PAM module ensures that the invoking process has a session keyring other than the user default session keyring\&.
+.PP
+The module checks to see if the process\*(Aqs session keyring is the
+\fBuser-session-keyring\fR(7), and, if it is, creates a new
+\fBsession-keyring\fR(7)
+with which to replace it\&. If a new session keyring is created, it will install a link to the
+\fBuser-keyring\fR(7)
+in the session keyring so that keys common to the user will be automatically accessible through it\&. The session keyring of the invoking process will thenceforth be inherited by all its children unless they override it\&.
+.PP
+In order to allow other PAM modules to attach tokens to the keyring, this module provides both an
+\fIauth\fR
+(limited to
+\fBpam_setcred\fR(3)
+and a
+\fIsession\fR
+component\&. The session keyring is created in the module called\&. Moreover this module should be included as early as possible in a PAM configuration\&.
+.PP
+This module is intended primarily for use by login processes\&. Be aware that after the session keyring has been replaced, the old session keyring and the keys it contains will no longer be accessible\&.
+.PP
+This module should not, generally, be invoked by programs like
+\fBsu\fR, since it is usually desirable for the key set to percolate through to the alternate context\&. The keys have their own permissions system to manage this\&.
+.PP
+The keyutils package is used to manipulate keys more directly\&. This can be obtained from:
+.PP
+\m[blue]\fBKeyutils\fR\m[]\&\s-2\u[1]\d\s+2
+.SH "OPTIONS"
+.PP
+\fBdebug\fR
+.RS 4
+Log debug information with
+\fBsyslog\fR(3)\&.
+.RE
+.PP
+\fBforce\fR
+.RS 4
+Causes the session keyring of the invoking process to be replaced unconditionally\&.
+.RE
+.PP
+\fBrevoke\fR
+.RS 4
+Causes the session keyring of the invoking process to be revoked when the invoking process exits if the session keyring was created for this process in the first place\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+Only the
+\fBsession\fR
+module type is provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_SUCCESS
+.RS 4
+This module will usually return this value
+.RE
+.PP
+PAM_AUTH_ERR
+.RS 4
+Authentication failure\&.
+.RE
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_IGNORE
+.RS 4
+The return value should be ignored by PAM dispatch\&.
+.RE
+.PP
+PAM_SERVICE_ERR
+.RS 4
+Cannot determine the user name\&.
+.RE
+.PP
+PAM_SESSION_ERR
+.RS 4
+This module will return this value if its arguments are invalid or if a system error such as ENOMEM occurs\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+User not known\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Add this line to your login entries to start each login session with its own session keyring:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+session required pam_keyinit\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+This will prevent keys from one session leaking into another session for the same user\&.
+.SH "SEE ALSO"
+.PP
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8),
+\fBkeyctl\fR(1)
+.SH "AUTHOR"
+.PP
+pam_keyinit was written by David Howells, <dhowells@redhat\&.com>\&.
+.SH "NOTES"
+.IP " 1." 4
+Keyutils
+.RS 4
+\%http://people.redhat.com/~dhowells/keyutils/
+.RE
diff --git a/modules/pam_keyinit/pam_keyinit.8.xml b/modules/pam_keyinit/pam_keyinit.8.xml
new file mode 100644
index 0000000..ff1e7d0
--- /dev/null
+++ b/modules/pam_keyinit/pam_keyinit.8.xml
@@ -0,0 +1,250 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_keyinit">
+
+ <refmeta>
+ <refentrytitle>pam_keyinit</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_keyinit-name">
+ <refname>pam_keyinit</refname>
+ <refpurpose>Kernel session keyring initialiser module</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_keyinit-cmdsynopsis">
+ <command>pam_keyinit.so</command>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ force
+ </arg>
+ <arg choice="opt">
+ revoke
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_keyinit-description">
+ <title>DESCRIPTION</title>
+ <para>
+ The pam_keyinit PAM module ensures that the invoking process has a
+ session keyring other than the user default session keyring.
+ </para>
+ <para>
+ The module checks to see if the process's session keyring is the
+ <citerefentry>
+ <refentrytitle>user-session-keyring</refentrytitle><manvolnum>7</manvolnum>
+ </citerefentry>,
+ and, if it is, creates a new
+ <citerefentry>
+ <refentrytitle>session-keyring</refentrytitle><manvolnum>7</manvolnum>
+ </citerefentry>
+ with which to replace it. If a new session keyring is created, it will
+ install a link to the
+ <citerefentry>
+ <refentrytitle>user-keyring</refentrytitle><manvolnum>7</manvolnum>
+ </citerefentry>
+ in the session keyring so that keys common to the user will be
+ automatically accessible through it. The session keyring of the invoking
+ process will thenceforth be inherited by all its children unless they override it.
+ </para>
+ <para>
+ In order to allow other PAM modules to attach tokens to the keyring, this module
+ provides both an <emphasis>auth</emphasis> (limited to
+ <citerefentry>
+ <refentrytitle>pam_setcred</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>
+ and a <emphasis>session</emphasis> component. The session keyring is created
+ in the module called. Moreover this module should be included as early as
+ possible in a PAM configuration.
+ </para>
+ <para>
+ This module is intended primarily for use by login processes. Be aware
+ that after the session keyring has been replaced, the old session keyring
+ and the keys it contains will no longer be accessible.
+ </para>
+ <para>
+ This module should not, generally, be invoked by programs like
+ <emphasis remap='B'>su</emphasis>, since it is usually desirable for the
+ key set to percolate through to the alternate context. The keys have
+ their own permissions system to manage this.
+ </para>
+ <para>
+ The keyutils package is used to manipulate keys more directly. This
+ can be obtained from:
+ </para>
+ <para>
+ <ulink url="http://people.redhat.com/~dhowells/keyutils/">
+ Keyutils
+ </ulink>
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_keyinit-options">
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Log debug information with <citerefentry>
+ <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>force</option>
+ </term>
+ <listitem>
+ <para>
+ Causes the session keyring of the invoking process to be replaced
+ unconditionally.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>revoke</option>
+ </term>
+ <listitem>
+ <para>
+ Causes the session keyring of the invoking process to be revoked
+ when the invoking process exits if the session keyring was created
+ for this process in the first place.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_keyinit-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ Only the <option>session</option> module type is provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_keyinit-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ This module will usually return this value
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_AUTH_ERR</term>
+ <listitem>
+ <para>
+ Authentication failure.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory buffer error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ The return value should be ignored by PAM dispatch.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ Cannot determine the user name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SESSION_ERR</term>
+ <listitem>
+ <para>
+ This module will return this value if its arguments are invalid or
+ if a system error such as ENOMEM occurs.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ User not known.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_keyinit-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ Add this line to your login entries to start each login session with its
+ own session keyring:
+ <programlisting>
+session required pam_keyinit.so
+ </programlisting>
+ </para>
+ <para>
+ This will prevent keys from one session leaking into another session for
+ the same user.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_keyinit-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>keyctl</refentrytitle><manvolnum>1</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_keyinit-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_keyinit was written by David Howells, &lt;dhowells@redhat.com&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_keyinit/pam_keyinit.c b/modules/pam_keyinit/pam_keyinit.c
new file mode 100644
index 0000000..92e4953
--- /dev/null
+++ b/modules/pam_keyinit/pam_keyinit.c
@@ -0,0 +1,298 @@
+/*
+ * pam_keyinit: Initialise the session keyring on login through a PAM module
+ *
+ * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include "config.h"
+#include <stdarg.h>
+#include <string.h>
+#include <syslog.h>
+#include <pwd.h>
+#include <unistd.h>
+#include <errno.h>
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+#include <sys/syscall.h>
+
+#define KEY_SPEC_SESSION_KEYRING -3 /* ID for session keyring */
+#define KEY_SPEC_USER_KEYRING -4 /* ID for UID-specific keyring */
+#define KEY_SPEC_USER_SESSION_KEYRING -5 /* - key ID for UID-session keyring */
+
+#define KEYCTL_GET_KEYRING_ID 0 /* ask for a keyring's ID */
+#define KEYCTL_JOIN_SESSION_KEYRING 1 /* start named session keyring */
+#define KEYCTL_REVOKE 3 /* revoke a key */
+#define KEYCTL_LINK 8 /* link a key into a keyring */
+
+static int my_session_keyring = 0;
+static int session_counter = 0;
+static int do_revoke = 0;
+static uid_t revoke_as_uid;
+static gid_t revoke_as_gid;
+static int xdebug = 0;
+
+static void debug(pam_handle_t *pamh, const char *fmt, ...)
+ __attribute__((format(printf, 2, 3)));
+
+static void debug(pam_handle_t *pamh, const char *fmt, ...)
+{
+ va_list va;
+
+ if (xdebug) {
+ va_start(va, fmt);
+ pam_vsyslog(pamh, LOG_DEBUG, fmt, va);
+ va_end(va);
+ }
+}
+
+static void error(pam_handle_t *pamh, const char *fmt, ...)
+ __attribute__((format(printf, 2, 3)));
+
+static void error(pam_handle_t *pamh, const char *fmt, ...)
+{
+ va_list va;
+
+ va_start(va, fmt);
+ pam_vsyslog(pamh, LOG_ERR, fmt, va);
+ va_end(va);
+}
+
+/*
+ * initialise the session keyring for this process
+ */
+static int init_keyrings(pam_handle_t *pamh, int force, int error_ret)
+{
+ int session, usession, ret;
+
+ if (!force) {
+ /* get the IDs of the session keyring and the user session
+ * keyring */
+ session = syscall(__NR_keyctl,
+ KEYCTL_GET_KEYRING_ID,
+ KEY_SPEC_SESSION_KEYRING,
+ 0);
+ debug(pamh, "GET SESSION = %d", session);
+ if (session < 0) {
+ /* don't worry about keyrings if facility not
+ * installed */
+ if (errno == ENOSYS)
+ return PAM_SUCCESS;
+ return error_ret;
+ }
+
+ usession = syscall(__NR_keyctl,
+ KEYCTL_GET_KEYRING_ID,
+ KEY_SPEC_USER_SESSION_KEYRING,
+ 0);
+ debug(pamh, "GET SESSION = %d", usession);
+ if (usession < 0)
+ return error_ret;
+
+ /* if the user session keyring is our keyring, then we don't
+ * need to do anything if we're not forcing */
+ if (session != usession)
+ return PAM_SUCCESS;
+ }
+
+ /* create a session keyring, discarding the old one */
+ ret = syscall(__NR_keyctl,
+ KEYCTL_JOIN_SESSION_KEYRING,
+ NULL);
+ debug(pamh, "JOIN = %d", ret);
+ if (ret < 0)
+ return error_ret;
+
+ my_session_keyring = ret;
+
+ /* make a link from the session keyring to the user keyring */
+ ret = syscall(__NR_keyctl,
+ KEYCTL_LINK,
+ KEY_SPEC_USER_KEYRING,
+ KEY_SPEC_SESSION_KEYRING);
+
+ return ret < 0 ? error_ret : PAM_SUCCESS;
+}
+
+/*
+ * revoke the session keyring for this process
+ */
+static int kill_keyrings(pam_handle_t *pamh, int error_ret)
+{
+ uid_t old_uid;
+ gid_t old_gid;
+ int ret = PAM_SUCCESS;
+
+ /* revoke the session keyring we created earlier */
+ if (my_session_keyring > 0) {
+ debug(pamh, "REVOKE %d", my_session_keyring);
+
+ old_uid = geteuid();
+ old_gid = getegid();
+ debug(pamh, "UID:%d [%d] GID:%d [%d]",
+ revoke_as_uid, old_uid, revoke_as_gid, old_gid);
+
+ /* switch to the real UID and GID so that we have permission to
+ * revoke the key */
+ if (revoke_as_gid != old_gid && setregid(-1, revoke_as_gid) < 0) {
+ error(pamh, "Unable to change GID to %d temporarily\n", revoke_as_gid);
+ return error_ret;
+ }
+
+ if (revoke_as_uid != old_uid && setresuid(-1, revoke_as_uid, old_uid) < 0) {
+ error(pamh, "Unable to change UID to %d temporarily\n", revoke_as_uid);
+ if (getegid() != old_gid && setregid(-1, old_gid) < 0)
+ error(pamh, "Unable to change GID back to %d\n", old_gid);
+ return error_ret;
+ }
+
+ if (syscall(__NR_keyctl, KEYCTL_REVOKE, my_session_keyring) < 0) {
+ ret = error_ret;
+ }
+
+ /* return to the original UID and GID (probably root) */
+ if (revoke_as_uid != old_uid && setreuid(-1, old_uid) < 0) {
+ error(pamh, "Unable to change UID back to %d\n", old_uid);
+ ret = error_ret;
+ }
+
+ if (revoke_as_gid != old_gid && setregid(-1, old_gid) < 0) {
+ error(pamh, "Unable to change GID back to %d\n", old_gid);
+ ret = error_ret;
+ }
+
+ my_session_keyring = 0;
+ }
+ return ret;
+}
+
+static int do_keyinit(pam_handle_t *pamh, int argc, const char **argv, int error_ret)
+{
+ struct passwd *pw;
+ const char *username;
+ int ret, loop, force = 0;
+ uid_t old_uid, uid;
+ gid_t old_gid, gid;
+
+ for (loop = 0; loop < argc; loop++) {
+ if (strcmp(argv[loop], "force") == 0)
+ force = 1;
+ else if (strcmp(argv[loop], "debug") == 0)
+ xdebug = 1;
+ else if (strcmp(argv[loop], "revoke") == 0)
+ do_revoke = 1;
+ }
+
+ /* don't do anything if already created a keyring (will be called
+ * multiple times if mentioned more than once in a pam script)
+ */
+ if (my_session_keyring > 0)
+ return PAM_SUCCESS;
+
+ /* look up the target UID */
+ ret = pam_get_user(pamh, &username, "key user");
+ if (ret != PAM_SUCCESS)
+ return ret;
+
+ pw = pam_modutil_getpwnam(pamh, username);
+ if (!pw) {
+ pam_syslog(pamh, LOG_NOTICE, "Unable to look up user \"%s\"\n",
+ username);
+ return PAM_USER_UNKNOWN;
+ }
+
+ revoke_as_uid = uid = pw->pw_uid;
+ old_uid = getuid();
+ revoke_as_gid = gid = pw->pw_gid;
+ old_gid = getgid();
+ debug(pamh, "UID:%d [%d] GID:%d [%d]", uid, old_uid, gid, old_gid);
+
+ /* switch to the real UID and GID so that the keyring ends up owned by
+ * the right user */
+ if (gid != old_gid && setregid(gid, -1) < 0) {
+ error(pamh, "Unable to change GID to %d temporarily\n", gid);
+ return error_ret;
+ }
+
+ if (uid != old_uid && setreuid(uid, -1) < 0) {
+ error(pamh, "Unable to change UID to %d temporarily\n", uid);
+ if (setregid(old_gid, -1) < 0)
+ error(pamh, "Unable to change GID back to %d\n", old_gid);
+ return error_ret;
+ }
+
+ ret = init_keyrings(pamh, force, error_ret);
+
+ /* return to the original UID and GID (probably root) */
+ if (uid != old_uid && setreuid(old_uid, -1) < 0) {
+ error(pamh, "Unable to change UID back to %d\n", old_uid);
+ ret = error_ret;
+ }
+
+ if (gid != old_gid && setregid(old_gid, -1) < 0) {
+ error(pamh, "Unable to change GID back to %d\n", old_gid);
+ ret = error_ret;
+ }
+
+ return ret;
+}
+
+/*
+ * Dummy
+ */
+int pam_sm_authenticate(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_IGNORE;
+}
+
+/*
+ * since setcred and open_session are called in different orders, a
+ * session ring is invoked by the first of these functions called.
+ */
+int pam_sm_setcred(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ if (flags & PAM_ESTABLISH_CRED) {
+ debug(pamh, "ESTABLISH_CRED");
+ return do_keyinit(pamh, argc, argv, PAM_CRED_ERR);
+ }
+ if (flags & PAM_DELETE_CRED && my_session_keyring > 0 && do_revoke) {
+ debug(pamh, "DELETE_CRED");
+ return kill_keyrings(pamh, PAM_CRED_ERR);
+ }
+ return PAM_IGNORE;
+}
+
+int pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ session_counter++;
+
+ debug(pamh, "OPEN %d", session_counter);
+
+ return do_keyinit(pamh, argc, argv, PAM_SESSION_ERR);
+}
+
+/*
+ * close a PAM session by revoking the session keyring if requested
+ */
+int pam_sm_close_session(pam_handle_t *pamh, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ debug(pamh, "CLOSE %d,%d,%d",
+ session_counter, my_session_keyring, do_revoke);
+
+ session_counter--;
+
+ if (session_counter <= 0 && my_session_keyring > 0 && do_revoke)
+ kill_keyrings(pamh, PAM_SESSION_ERR);
+
+ return PAM_SUCCESS;
+}
diff --git a/modules/pam_keyinit/tst-pam_keyinit b/modules/pam_keyinit/tst-pam_keyinit
new file mode 100755
index 0000000..f0a7b9b
--- /dev/null
+++ b/modules/pam_keyinit/tst-pam_keyinit
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_keyinit.so
diff --git a/modules/pam_lastlog/Makefile.am b/modules/pam_lastlog/Makefile.am
new file mode 100644
index 0000000..dc0c7c4
--- /dev/null
+++ b/modules/pam_lastlog/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_lastlog.8
+endif
+XMLS = README.xml pam_lastlog.8.xml
+dist_check_SCRIPTS = tst-pam_lastlog
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_lastlog.la
+pam_lastlog_la_LIBADD = $(top_builddir)/libpam/libpam.la -lutil
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_lastlog/Makefile.in b/modules/pam_lastlog/Makefile.in
new file mode 100644
index 0000000..16baea8
--- /dev/null
+++ b/modules/pam_lastlog/Makefile.in
@@ -0,0 +1,1150 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_lastlog
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_lastlog_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_lastlog_la_SOURCES = pam_lastlog.c
+pam_lastlog_la_OBJECTS = pam_lastlog.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_lastlog.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_lastlog.c
+DIST_SOURCES = pam_lastlog.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_lastlog.8
+XMLS = README.xml pam_lastlog.8.xml
+dist_check_SCRIPTS = tst-pam_lastlog
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_lastlog.la
+pam_lastlog_la_LIBADD = $(top_builddir)/libpam/libpam.la -lutil
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_lastlog/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_lastlog/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_lastlog.la: $(pam_lastlog_la_OBJECTS) $(pam_lastlog_la_DEPENDENCIES) $(EXTRA_pam_lastlog_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_lastlog_la_OBJECTS) $(pam_lastlog_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_lastlog.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_lastlog.log: tst-pam_lastlog
+ @p='tst-pam_lastlog'; \
+ b='tst-pam_lastlog'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_lastlog.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_lastlog.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_lastlog/README b/modules/pam_lastlog/README
new file mode 100644
index 0000000..9b0cff9
--- /dev/null
+++ b/modules/pam_lastlog/README
@@ -0,0 +1,96 @@
+pam_lastlog — PAM module to display date of last login and perform inactive
+account lock out
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+pam_lastlog is a PAM module to display a line of information about the last
+login of the user. In addition, the module maintains the /var/log/lastlog file.
+
+Some applications may perform this function themselves. In such cases, this
+module is not necessary.
+
+The module checks LASTLOG_UID_MAX option in /etc/login.defs and does not update
+or display last login records for users with UID higher than its value. If the
+option is not present or its value is invalid, no user ID limit is applied.
+
+If the module is called in the auth or account phase, the accounts that were
+not used recently enough will be disallowed to log in. The check is not
+performed for the root account so the root is never locked out. It is also not
+performed for users with UID higher than the LASTLOG_UID_MAX value.
+
+OPTIONS
+
+debug
+
+ Print debug information.
+
+silent
+
+ Don't inform the user about any previous login, just update the /var/log/
+ lastlog file. This option does not affect display of bad login attempts.
+
+never
+
+ If the /var/log/lastlog file does not contain any old entries for the user,
+ indicate that the user has never previously logged in with a welcome
+ message.
+
+nodate
+
+ Don't display the date of the last login.
+
+noterm
+
+ Don't display the terminal name on which the last login was attempted.
+
+nohost
+
+ Don't indicate from which host the last login was attempted.
+
+nowtmp
+
+ Don't update the wtmp entry.
+
+noupdate
+
+ Don't update any file.
+
+showfailed
+
+ Display number of failed login attempts and the date of the last failed
+ attempt from btmp. The date is not displayed when nodate is specified.
+
+inactive=<days>
+
+ This option is specific for the auth or account phase. It specifies the
+ number of days after the last login of the user when the user will be
+ locked out by the module. The default value is 90.
+
+unlimited
+
+ If the fsize limit is set, this option can be used to override it,
+ preventing failures on systems with large UID values that lead lastlog to
+ become a huge sparse file.
+
+EXAMPLES
+
+Add the following line to /etc/pam.d/login to display the last login time of a
+user:
+
+ session required pam_lastlog.so nowtmp
+
+
+To reject the user if he did not login during the previous 50 days the
+following line can be used:
+
+ auth required pam_lastlog.so inactive=50
+
+
+AUTHOR
+
+pam_lastlog was written by Andrew G. Morgan <morgan@kernel.org>.
+
+Inactive account lock out added by Tomáš Mráz <tm@t8m.info>.
+
diff --git a/modules/pam_lastlog/README.xml b/modules/pam_lastlog/README.xml
new file mode 100644
index 0000000..7fe7033
--- /dev/null
+++ b/modules/pam_lastlog/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_lastlog.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_lastlog.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_lastlog-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_lastlog.8.xml" xpointer='xpointer(//refsect1[@id = "pam_lastlog-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_lastlog.8.xml" xpointer='xpointer(//refsect1[@id = "pam_lastlog-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_lastlog.8.xml" xpointer='xpointer(//refsect1[@id = "pam_lastlog-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_lastlog.8.xml" xpointer='xpointer(//refsect1[@id = "pam_lastlog-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_lastlog/pam_lastlog.8 b/modules/pam_lastlog/pam_lastlog.8
new file mode 100644
index 0000000..325456e
--- /dev/null
+++ b/modules/pam_lastlog/pam_lastlog.8
@@ -0,0 +1,197 @@
+'\" t
+.\" Title: pam_lastlog
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_LASTLOG" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_lastlog \- PAM module to display date of last login and perform inactive account lock out
+.SH "SYNOPSIS"
+.HP \w'\fBpam_lastlog\&.so\fR\ 'u
+\fBpam_lastlog\&.so\fR [debug] [silent] [never] [nodate] [nohost] [noterm] [nowtmp] [noupdate] [showfailed] [inactive=<days>] [unlimited]
+.SH "DESCRIPTION"
+.PP
+pam_lastlog is a PAM module to display a line of information about the last login of the user\&. In addition, the module maintains the
+/var/log/lastlog
+file\&.
+.PP
+Some applications may perform this function themselves\&. In such cases, this module is not necessary\&.
+.PP
+The module checks
+\fBLASTLOG_UID_MAX\fR
+option in
+/etc/login\&.defs
+and does not update or display last login records for users with UID higher than its value\&. If the option is not present or its value is invalid, no user ID limit is applied\&.
+.PP
+If the module is called in the auth or account phase, the accounts that were not used recently enough will be disallowed to log in\&. The check is not performed for the root account so the root is never locked out\&. It is also not performed for users with UID higher than the
+\fBLASTLOG_UID_MAX\fR
+value\&.
+.SH "OPTIONS"
+.PP
+\fBdebug\fR
+.RS 4
+Print debug information\&.
+.RE
+.PP
+\fBsilent\fR
+.RS 4
+Don\*(Aqt inform the user about any previous login, just update the
+/var/log/lastlog
+file\&. This option does not affect display of bad login attempts\&.
+.RE
+.PP
+\fBnever\fR
+.RS 4
+If the
+/var/log/lastlog
+file does not contain any old entries for the user, indicate that the user has never previously logged in with a welcome message\&.
+.RE
+.PP
+\fBnodate\fR
+.RS 4
+Don\*(Aqt display the date of the last login\&.
+.RE
+.PP
+\fBnoterm\fR
+.RS 4
+Don\*(Aqt display the terminal name on which the last login was attempted\&.
+.RE
+.PP
+\fBnohost\fR
+.RS 4
+Don\*(Aqt indicate from which host the last login was attempted\&.
+.RE
+.PP
+\fBnowtmp\fR
+.RS 4
+Don\*(Aqt update the wtmp entry\&.
+.RE
+.PP
+\fBnoupdate\fR
+.RS 4
+Don\*(Aqt update any file\&.
+.RE
+.PP
+\fBshowfailed\fR
+.RS 4
+Display number of failed login attempts and the date of the last failed attempt from btmp\&. The date is not displayed when
+\fBnodate\fR
+is specified\&.
+.RE
+.PP
+\fBinactive=<days>\fR
+.RS 4
+This option is specific for the auth or account phase\&. It specifies the number of days after the last login of the user when the user will be locked out by the module\&. The default value is 90\&.
+.RE
+.PP
+\fBunlimited\fR
+.RS 4
+If the
+\fIfsize\fR
+limit is set, this option can be used to override it, preventing failures on systems with large UID values that lead lastlog to become a huge sparse file\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+The
+\fBauth\fR
+and
+\fBaccount\fR
+module type allows one to lock out users who did not login recently enough\&. The
+\fBsession\fR
+module type is provided for displaying the information about the last login and/or updating the lastlog and wtmp files\&.
+.SH "RETURN VALUES"
+.PP
+.PP
+PAM_SUCCESS
+.RS 4
+Everything was successful\&.
+.RE
+.PP
+PAM_SERVICE_ERR
+.RS 4
+Internal service module error\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+User not known\&.
+.RE
+.PP
+PAM_AUTH_ERR
+.RS 4
+User locked out in the auth or account phase due to inactivity\&.
+.RE
+.PP
+PAM_IGNORE
+.RS 4
+There was an error during reading the lastlog file in the auth or account phase and thus inactivity of the user cannot be determined\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Add the following line to
+/etc/pam\&.d/login
+to display the last login time of a user:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ session required pam_lastlog\&.so nowtmp
+
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To reject the user if he did not login during the previous 50 days the following line can be used:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ auth required pam_lastlog\&.so inactive=50
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "FILES"
+.PP
+/var/log/lastlog
+.RS 4
+Lastlog logging file
+.RE
+.SH "SEE ALSO"
+.PP
+\fBlimits.conf\fR(5),
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_lastlog was written by Andrew G\&. Morgan <morgan@kernel\&.org>\&.
+.PP
+Inactive account lock out added by Tomáš Mráz <tm@t8m\&.info>\&.
diff --git a/modules/pam_lastlog/pam_lastlog.8.xml b/modules/pam_lastlog/pam_lastlog.8.xml
new file mode 100644
index 0000000..bada2ea
--- /dev/null
+++ b/modules/pam_lastlog/pam_lastlog.8.xml
@@ -0,0 +1,343 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_lastlog">
+
+ <refmeta>
+ <refentrytitle>pam_lastlog</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_lastlog-name">
+ <refname>pam_lastlog</refname>
+ <refpurpose>PAM module to display date of last login and perform inactive account lock out</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_lastlog-cmdsynopsis">
+ <command>pam_lastlog.so</command>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ silent
+ </arg>
+ <arg choice="opt">
+ never
+ </arg>
+ <arg choice="opt">
+ nodate
+ </arg>
+ <arg choice="opt">
+ nohost
+ </arg>
+ <arg choice="opt">
+ noterm
+ </arg>
+ <arg choice="opt">
+ nowtmp
+ </arg>
+ <arg choice="opt">
+ noupdate
+ </arg>
+ <arg choice="opt">
+ showfailed
+ </arg>
+ <arg choice="opt">
+ inactive=&lt;days&gt;
+ </arg>
+ <arg choice="opt">
+ unlimited
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_lastlog-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ pam_lastlog is a PAM module to display a line of information
+ about the last login of the user. In addition, the module maintains
+ the <filename>/var/log/lastlog</filename> file.
+ </para>
+ <para>
+ Some applications may perform this function themselves. In such
+ cases, this module is not necessary.
+ </para>
+ <para>
+ The module checks <option>LASTLOG_UID_MAX</option> option in
+ <filename>/etc/login.defs</filename> and does not update or display
+ last login records for users with UID higher than its value.
+ If the option is not present or its value is invalid, no user ID
+ limit is applied.
+ </para>
+ <para>
+ If the module is called in the auth or account phase, the accounts that
+ were not used recently enough will be disallowed to log in. The
+ check is not performed for the root account so the root is never
+ locked out. It is also not performed for users with UID higher
+ than the <option>LASTLOG_UID_MAX</option> value.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_lastlog-options">
+
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Print debug information.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>silent</option>
+ </term>
+ <listitem>
+ <para>
+ Don't inform the user about any previous login,
+ just update the <filename>/var/log/lastlog</filename> file.
+ This option does not affect display of bad login attempts.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>never</option>
+ </term>
+ <listitem>
+ <para>
+ If the <filename>/var/log/lastlog</filename> file does
+ not contain any old entries for the user, indicate that
+ the user has never previously logged in with a welcome
+ message.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>nodate</option>
+ </term>
+ <listitem>
+ <para>
+ Don't display the date of the last login.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>noterm</option>
+ </term>
+ <listitem>
+ <para>
+ Don't display the terminal name on which the
+ last login was attempted.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>nohost</option>
+ </term>
+ <listitem>
+ <para>
+ Don't indicate from which host the last login was
+ attempted.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>nowtmp</option>
+ </term>
+ <listitem>
+ <para>
+ Don't update the wtmp entry.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>noupdate</option>
+ </term>
+ <listitem>
+ <para>
+ Don't update any file.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>showfailed</option>
+ </term>
+ <listitem>
+ <para>
+ Display number of failed login attempts and the date of the
+ last failed attempt from btmp. The date is not displayed
+ when <option>nodate</option> is specified.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>inactive=&lt;days&gt;</option>
+ </term>
+ <listitem>
+ <para>
+ This option is specific for the auth or account phase. It
+ specifies the number of days after the last login of the user
+ when the user will be locked out by the module. The default
+ value is 90.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>unlimited</option>
+ </term>
+ <listitem>
+ <para>
+ If the <emphasis>fsize</emphasis> limit is set, this option can be
+ used to override it, preventing failures on systems with large UID
+ values that lead lastlog to become a huge sparse file.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_lastlog-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ The <option>auth</option> and <option>account</option> module type
+ allows one to lock out users who did not login recently enough.
+ The <option>session</option> module type is provided for displaying
+ the information about the last login and/or updating the lastlog and
+ wtmp files.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_lastlog-return_values'>
+ <title>RETURN VALUES</title>
+ <para>
+ <variablelist>
+
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Everything was successful.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ Internal service module error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ User not known.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_AUTH_ERR</term>
+ <listitem>
+ <para>
+ User locked out in the auth or account phase due to
+ inactivity.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ There was an error during reading the lastlog file
+ in the auth or account phase and thus inactivity
+ of the user cannot be determined.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_lastlog-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ Add the following line to <filename>/etc/pam.d/login</filename> to
+ display the last login time of a user:
+ </para>
+ <programlisting>
+ session required pam_lastlog.so nowtmp
+ </programlisting>
+ <para>
+ To reject the user if he did not login during the previous 50 days
+ the following line can be used:
+ </para>
+ <programlisting>
+ auth required pam_lastlog.so inactive=50
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id="pam_lastlog-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/var/log/lastlog</filename></term>
+ <listitem>
+ <para>Lastlog logging file</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_lastlog-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>limits.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_lastlog-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_lastlog was written by Andrew G. Morgan &lt;morgan@kernel.org&gt;.
+ </para>
+ <para>
+ Inactive account lock out added by Tomáš Mráz &lt;tm@t8m.info&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_lastlog/pam_lastlog.c b/modules/pam_lastlog/pam_lastlog.c
new file mode 100644
index 0000000..abd048d
--- /dev/null
+++ b/modules/pam_lastlog/pam_lastlog.c
@@ -0,0 +1,804 @@
+/*
+ * pam_lastlog module
+ *
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
+ *
+ * This module does the necessary work to display the last login
+ * time+date for this user, it then updates this entry for the
+ * present (login) service.
+ */
+
+#include "config.h"
+
+#include <fcntl.h>
+#include <time.h>
+#include <errno.h>
+#ifdef HAVE_UTMP_H
+# include <utmp.h>
+#else
+# include <lastlog.h>
+#endif
+#include <pwd.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#if defined(hpux) || defined(sunos) || defined(solaris)
+# ifndef _PATH_LASTLOG
+# define _PATH_LASTLOG "/usr/adm/lastlog"
+# endif /* _PATH_LASTLOG */
+# ifndef UT_HOSTSIZE
+# define UT_HOSTSIZE 16
+# endif /* UT_HOSTSIZE */
+# ifndef UT_LINESIZE
+# define UT_LINESIZE 12
+# endif /* UT_LINESIZE */
+#endif
+#if defined(hpux)
+struct lastlog {
+ time_t ll_time;
+ char ll_line[UT_LINESIZE];
+ char ll_host[UT_HOSTSIZE]; /* same as in utmp */
+};
+#endif /* hpux */
+
+#ifndef _PATH_BTMP
+# define _PATH_BTMP "/var/log/btmp"
+#endif
+
+#ifndef PATH_LOGIN_DEFS
+# define PATH_LOGIN_DEFS "/etc/login.defs"
+#endif
+
+/* XXX - time before ignoring lock. Is 1 sec enough? */
+#define LASTLOG_IGNORE_LOCK_TIME 1
+
+#define DEFAULT_HOST "" /* "[no.where]" */
+#define DEFAULT_TERM "" /* "tt???" */
+
+#define DEFAULT_INACTIVE_DAYS 90
+#define MAX_INACTIVE_DAYS 100000
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+#include "pam_inline.h"
+
+/* argument parsing */
+
+#define LASTLOG_DATE 01 /* display the date of the last login */
+#define LASTLOG_HOST 02 /* display the last host used (if set) */
+#define LASTLOG_LINE 04 /* display the last terminal used */
+#define LASTLOG_NEVER 010 /* display a welcome message for first login */
+#define LASTLOG_DEBUG 020 /* send info to syslog(3) */
+#define LASTLOG_QUIET 040 /* keep quiet about things */
+#define LASTLOG_WTMP 0100 /* log to wtmp as well as lastlog */
+#define LASTLOG_BTMP 0200 /* display failed login info from btmp */
+#define LASTLOG_UPDATE 0400 /* update the lastlog and wtmp files (default) */
+#define LASTLOG_UNLIMITED 01000 /* unlimited file size (ignore 'fsize' limit) */
+
+static int
+_pam_auth_parse(pam_handle_t *pamh, int flags, int argc, const char **argv,
+ time_t *inactive)
+{
+ int ctrl = 0;
+
+ *inactive = DEFAULT_INACTIVE_DAYS;
+
+ /* does the application require quiet? */
+ if (flags & PAM_SILENT) {
+ ctrl |= LASTLOG_QUIET;
+ }
+
+ /* step through arguments */
+ for (; argc-- > 0; ++argv) {
+ const char *str;
+ char *ep = NULL;
+ long l;
+
+ if (!strcmp(*argv,"debug")) {
+ ctrl |= LASTLOG_DEBUG;
+ } else if (!strcmp(*argv,"silent")) {
+ ctrl |= LASTLOG_QUIET;
+ } else if ((str = pam_str_skip_prefix(*argv, "inactive=")) != NULL) {
+ l = strtol(str, &ep, 10);
+ if (ep != str && l > 0 && l < MAX_INACTIVE_DAYS)
+ *inactive = l;
+ else {
+ pam_syslog(pamh, LOG_ERR, "bad option value: %s", *argv);
+ }
+ } else {
+ pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
+ }
+ }
+
+ D(("ctrl = %o", ctrl));
+ return ctrl;
+}
+
+static int
+_pam_session_parse(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ int ctrl=(LASTLOG_DATE|LASTLOG_HOST|LASTLOG_LINE|LASTLOG_WTMP|LASTLOG_UPDATE);
+
+ /* step through arguments */
+ for (; argc-- > 0; ++argv) {
+
+ /* generic options */
+
+ if (!strcmp(*argv,"debug")) {
+ ctrl |= LASTLOG_DEBUG;
+ } else if (!strcmp(*argv,"nodate")) {
+ ctrl &= ~LASTLOG_DATE;
+ } else if (!strcmp(*argv,"noterm")) {
+ ctrl &= ~LASTLOG_LINE;
+ } else if (!strcmp(*argv,"nohost")) {
+ ctrl &= ~LASTLOG_HOST;
+ } else if (!strcmp(*argv,"silent")) {
+ ctrl |= LASTLOG_QUIET;
+ } else if (!strcmp(*argv,"never")) {
+ ctrl |= LASTLOG_NEVER;
+ } else if (!strcmp(*argv,"nowtmp")) {
+ ctrl &= ~LASTLOG_WTMP;
+ } else if (!strcmp(*argv,"noupdate")) {
+ ctrl &= ~(LASTLOG_WTMP|LASTLOG_UPDATE);
+ } else if (!strcmp(*argv,"showfailed")) {
+ ctrl |= LASTLOG_BTMP;
+ } else if (!strcmp(*argv,"unlimited")) {
+ ctrl |= LASTLOG_UNLIMITED;
+ } else {
+ pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
+ }
+ }
+
+ /* does the application require quiet? */
+ if (flags & PAM_SILENT) {
+ ctrl |= LASTLOG_QUIET;
+ ctrl &= ~LASTLOG_BTMP;
+ }
+
+ D(("ctrl = %o", ctrl));
+ return ctrl;
+}
+
+static const char *
+get_tty(pam_handle_t *pamh)
+{
+ const void *void_terminal_line = NULL;
+ const char *terminal_line;
+ const char *str;
+
+ if (pam_get_item(pamh, PAM_TTY, &void_terminal_line) != PAM_SUCCESS
+ || void_terminal_line == NULL) {
+ terminal_line = DEFAULT_TERM;
+ } else {
+ terminal_line = void_terminal_line;
+ }
+
+ /* strip leading "/dev/" from tty. */
+ str = pam_str_skip_prefix(terminal_line, "/dev/");
+ if (str != NULL)
+ terminal_line = str;
+
+ D(("terminal = %s", terminal_line));
+ return terminal_line;
+}
+
+#define MAX_UID_VALUE 0xFFFFFFFFUL
+
+static uid_t
+get_lastlog_uid_max(pam_handle_t *pamh)
+{
+ uid_t uid_max = MAX_UID_VALUE;
+ unsigned long ul;
+ char *s, *ep;
+
+ s = pam_modutil_search_key(pamh, PATH_LOGIN_DEFS, "LASTLOG_UID_MAX");
+ if (s == NULL)
+ return uid_max;
+
+ ep = s + strlen(s);
+ while (ep > s && isspace(*(--ep))) {
+ *ep = '\0';
+ }
+ errno = 0;
+ ul = strtoul(s, &ep, 10);
+ if (!(ul >= MAX_UID_VALUE
+ || (uid_t)ul >= MAX_UID_VALUE
+ || (errno != 0 && ul == 0)
+ || s == ep
+ || *ep != '\0')) {
+ uid_max = (uid_t)ul;
+ }
+ free(s);
+
+ return uid_max;
+}
+
+static int
+last_login_open(pam_handle_t *pamh, int announce, uid_t uid)
+{
+ int last_fd;
+
+ /* obtain the last login date and all the relevant info */
+ last_fd = open(_PATH_LASTLOG, announce&LASTLOG_UPDATE ? O_RDWR : O_RDONLY);
+ if (last_fd < 0) {
+ if (errno == ENOENT && (announce & LASTLOG_UPDATE)) {
+ last_fd = open(_PATH_LASTLOG, O_RDWR|O_CREAT,
+ S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+ if (last_fd < 0) {
+ pam_syslog(pamh, LOG_ERR,
+ "unable to create %s: %m", _PATH_LASTLOG);
+ D(("unable to create %s file", _PATH_LASTLOG));
+ return -1;
+ }
+ pam_syslog(pamh, LOG_NOTICE,
+ "file %s created", _PATH_LASTLOG);
+ D(("file %s created", _PATH_LASTLOG));
+ } else {
+ pam_syslog(pamh, LOG_ERR, "unable to open %s: %m", _PATH_LASTLOG);
+ D(("unable to open %s file", _PATH_LASTLOG));
+ return -1;
+ }
+ }
+
+ if (lseek(last_fd, sizeof(struct lastlog) * (off_t) uid, SEEK_SET) < 0) {
+ pam_syslog(pamh, LOG_ERR, "failed to lseek %s: %m", _PATH_LASTLOG);
+ D(("unable to lseek %s file", _PATH_LASTLOG));
+ close(last_fd);
+ return -1;
+ }
+
+ return last_fd;
+}
+
+
+static int
+last_login_read(pam_handle_t *pamh, int announce, int last_fd, uid_t uid, time_t *lltime)
+{
+ struct flock last_lock;
+ struct lastlog last_login;
+ int retval = PAM_SUCCESS;
+ char the_time[256];
+ char *date = NULL;
+ char *host = NULL;
+ char *line = NULL;
+
+ memset(&last_lock, 0, sizeof(last_lock));
+ last_lock.l_type = F_RDLCK;
+ last_lock.l_whence = SEEK_SET;
+ last_lock.l_start = sizeof(last_login) * (off_t) uid;
+ last_lock.l_len = sizeof(last_login);
+
+ if (fcntl(last_fd, F_SETLK, &last_lock) < 0) {
+ D(("locking %s failed..(waiting a little)", _PATH_LASTLOG));
+ pam_syslog(pamh, LOG_WARNING,
+ "file %s is locked/read", _PATH_LASTLOG);
+ sleep(LASTLOG_IGNORE_LOCK_TIME);
+ }
+
+ if (pam_modutil_read(last_fd, (char *) &last_login,
+ sizeof(last_login)) != sizeof(last_login)) {
+ memset(&last_login, 0, sizeof(last_login));
+ }
+
+ last_lock.l_type = F_UNLCK;
+ (void) fcntl(last_fd, F_SETLK, &last_lock); /* unlock */
+
+ *lltime = last_login.ll_time;
+ if (!last_login.ll_time) {
+ if (announce & LASTLOG_DEBUG) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "first login for user with uid %lu",
+ (unsigned long int)uid);
+ }
+ }
+
+ if (!(announce & LASTLOG_QUIET)) {
+
+ if (last_login.ll_time) {
+
+ /* we want the date? */
+ if (announce & LASTLOG_DATE) {
+ struct tm *tm, tm_buf;
+ time_t ll_time;
+
+ ll_time = last_login.ll_time;
+ if ((tm = localtime_r (&ll_time, &tm_buf)) != NULL) {
+ strftime (the_time, sizeof (the_time),
+ /* TRANSLATORS: "strftime options for date of last login" */
+ _(" %a %b %e %H:%M:%S %Z %Y"), tm);
+ date = the_time;
+ }
+ }
+
+ /* we want & have the host? */
+ if ((announce & LASTLOG_HOST)
+ && (last_login.ll_host[0] != '\0')) {
+ /* TRANSLATORS: " from <host>" */
+ if (asprintf(&host, _(" from %.*s"), UT_HOSTSIZE,
+ last_login.ll_host) < 0) {
+ pam_syslog(pamh, LOG_CRIT, "out of memory");
+ retval = PAM_BUF_ERR;
+ goto cleanup;
+ }
+ }
+
+ /* we want and have the terminal? */
+ if ((announce & LASTLOG_LINE)
+ && (last_login.ll_line[0] != '\0')) {
+ /* TRANSLATORS: " on <terminal>" */
+ if (asprintf(&line, _(" on %.*s"), UT_LINESIZE,
+ last_login.ll_line) < 0) {
+ pam_syslog(pamh, LOG_CRIT, "out of memory");
+ retval = PAM_BUF_ERR;
+ goto cleanup;
+ }
+ }
+
+ if (date != NULL || host != NULL || line != NULL)
+ /* TRANSLATORS: "Last login: <date> from <host> on <terminal>" */
+ retval = pam_info(pamh, _("Last login:%s%s%s"),
+ date ? date : "",
+ host ? host : "",
+ line ? line : "");
+ } else if (announce & LASTLOG_NEVER) {
+ D(("this is the first time this user has logged in"));
+ retval = pam_info(pamh, "%s", _("Welcome to your new account!"));
+ }
+ }
+
+ /* cleanup */
+ cleanup:
+ memset(&last_login, 0, sizeof(last_login));
+ _pam_overwrite(date);
+ _pam_overwrite(host);
+ _pam_drop(host);
+ _pam_overwrite(line);
+ _pam_drop(line);
+
+ return retval;
+}
+
+static int
+last_login_write(pam_handle_t *pamh, int announce, int last_fd,
+ uid_t uid, const char *user)
+{
+ static struct rlimit no_limit = {
+ RLIM_INFINITY,
+ RLIM_INFINITY
+ };
+ struct rlimit old_limit;
+ int setrlimit_res;
+ struct flock last_lock;
+ struct lastlog last_login;
+ time_t ll_time;
+ const void *void_remote_host = NULL;
+ const char *remote_host;
+ const char *terminal_line;
+ int retval = PAM_SUCCESS;
+
+ /* rewind */
+ if (lseek(last_fd, sizeof(last_login) * (off_t) uid, SEEK_SET) < 0) {
+ pam_syslog(pamh, LOG_ERR, "failed to lseek %s: %m", _PATH_LASTLOG);
+ return PAM_SERVICE_ERR;
+ }
+
+ memset(&last_login, 0, sizeof(last_login));
+
+ /* set this login date */
+ D(("set the most recent login time"));
+ (void) time(&ll_time); /* set the time */
+ last_login.ll_time = ll_time;
+
+ /* set the remote host */
+ if (pam_get_item(pamh, PAM_RHOST, &void_remote_host) != PAM_SUCCESS
+ || void_remote_host == NULL) {
+ remote_host = DEFAULT_HOST;
+ } else {
+ remote_host = void_remote_host;
+ }
+
+ /* copy to last_login */
+ strncat(last_login.ll_host, remote_host, sizeof(last_login.ll_host)-1);
+
+ /* set the terminal line */
+ terminal_line = get_tty(pamh);
+
+ /* copy to last_login */
+ strncat(last_login.ll_line, terminal_line, sizeof(last_login.ll_line)-1);
+ terminal_line = NULL;
+
+ D(("locking lastlog file"));
+
+ /* now we try to lock this file-record exclusively; non-blocking */
+ memset(&last_lock, 0, sizeof(last_lock));
+ last_lock.l_type = F_WRLCK;
+ last_lock.l_whence = SEEK_SET;
+ last_lock.l_start = sizeof(last_login) * (off_t) uid;
+ last_lock.l_len = sizeof(last_login);
+
+ if (fcntl(last_fd, F_SETLK, &last_lock) < 0) {
+ D(("locking %s failed..(waiting a little)", _PATH_LASTLOG));
+ pam_syslog(pamh, LOG_WARNING, "file %s is locked/write", _PATH_LASTLOG);
+ sleep(LASTLOG_IGNORE_LOCK_TIME);
+ }
+
+ /*
+ * Failing to set the 'fsize' limit is not a fatal error. We try to write
+ * lastlog anyway, under the risk of dying due to a SIGXFSZ.
+ */
+ D(("setting limit for 'fsize'"));
+
+ if ((announce & LASTLOG_UNLIMITED) == 0) { /* don't set to unlimited */
+ setrlimit_res = -1;
+ } else if (getrlimit(RLIMIT_FSIZE, &old_limit) == 0) {
+ if (old_limit.rlim_cur == RLIM_INFINITY) { /* already unlimited */
+ setrlimit_res = -1;
+ } else {
+ setrlimit_res = setrlimit(RLIMIT_FSIZE, &no_limit);
+ if (setrlimit_res != 0)
+ pam_syslog(pamh, LOG_WARNING, "Could not set limit for 'fsize': %m");
+ }
+ } else {
+ setrlimit_res = -1;
+ if (errno == EINVAL) {
+ pam_syslog(pamh, LOG_INFO, "Limit for 'fsize' not supported: %m");
+ } else {
+ pam_syslog(pamh, LOG_WARNING, "Could not get limit for 'fsize': %m");
+ }
+ }
+
+ D(("writing to the lastlog file"));
+ if (pam_modutil_write (last_fd, (char *) &last_login,
+ sizeof (last_login)) != sizeof(last_login)) {
+ pam_syslog(pamh, LOG_ERR, "failed to write %s: %m", _PATH_LASTLOG);
+ retval = PAM_SERVICE_ERR;
+ }
+
+ /*
+ * Failing to restore the 'fsize' limit is a fatal error.
+ */
+ D(("restoring limit for 'fsize'"));
+ if (setrlimit_res == 0) {
+ setrlimit_res = setrlimit(RLIMIT_FSIZE, &old_limit);
+ if (setrlimit_res != 0) {
+ pam_syslog(pamh, LOG_ERR, "Could not restore limit for 'fsize': %m");
+ retval = PAM_SERVICE_ERR;
+ }
+ }
+
+ last_lock.l_type = F_UNLCK;
+ (void) fcntl(last_fd, F_SETLK, &last_lock); /* unlock */
+ D(("unlocked"));
+
+ if (announce & LASTLOG_WTMP) {
+ /* write wtmp entry for user */
+ logwtmp(last_login.ll_line, user, remote_host);
+ }
+
+ /* cleanup */
+ memset(&last_login, 0, sizeof(last_login));
+
+ return retval;
+}
+
+static int
+last_login_date(pam_handle_t *pamh, int announce, uid_t uid, const char *user, time_t *lltime)
+{
+ int retval;
+ int last_fd;
+
+ if (uid > get_lastlog_uid_max(pamh)) {
+ return PAM_SUCCESS;
+ }
+
+ /* obtain the last login date and all the relevant info */
+ last_fd = last_login_open(pamh, announce, uid);
+ if (last_fd < 0) {
+ return PAM_SERVICE_ERR;
+ }
+
+ retval = last_login_read(pamh, announce, last_fd, uid, lltime);
+ if (retval != PAM_SUCCESS)
+ {
+ close(last_fd);
+ D(("error while reading lastlog file"));
+ return retval;
+ }
+
+ if (announce & LASTLOG_UPDATE) {
+ retval = last_login_write(pamh, announce, last_fd, uid, user);
+ }
+
+ close(last_fd);
+ D(("all done with last login"));
+
+ return retval;
+}
+
+static int
+last_login_failed(pam_handle_t *pamh, int announce, const char *user, time_t lltime)
+{
+ int retval;
+ int fd;
+ struct utmp ut;
+ struct utmp utuser;
+ int failed = 0;
+ char the_time[256];
+ char *date = NULL;
+ char *host = NULL;
+ char *line = NULL;
+
+ if (strlen(user) > UT_NAMESIZE) {
+ pam_syslog(pamh, LOG_WARNING, "username too long, output might be inaccurate");
+ }
+
+ /* obtain the failed login attempt records from btmp */
+ fd = open(_PATH_BTMP, O_RDONLY);
+ if (fd < 0) {
+ int save_errno = errno;
+ pam_syslog(pamh, LOG_ERR, "unable to open %s: %m", _PATH_BTMP);
+ D(("unable to open %s file", _PATH_BTMP));
+ if (save_errno == ENOENT)
+ return PAM_SUCCESS;
+ else
+ return PAM_SERVICE_ERR;
+ }
+
+ while ((retval=pam_modutil_read(fd, (void *)&ut,
+ sizeof(ut))) == sizeof(ut)) {
+ if (ut.ut_tv.tv_sec >= lltime && strncmp(ut.ut_user, user, UT_NAMESIZE) == 0) {
+ memcpy(&utuser, &ut, sizeof(utuser));
+ failed++;
+ }
+ }
+
+ if (retval != 0)
+ pam_syslog(pamh, LOG_ERR, "corruption detected in %s", _PATH_BTMP);
+ retval = PAM_SUCCESS;
+
+ if (failed) {
+ /* we want the date? */
+ if (announce & LASTLOG_DATE) {
+ struct tm *tm, tm_buf;
+ time_t lf_time;
+
+ lf_time = utuser.ut_tv.tv_sec;
+ tm = localtime_r (&lf_time, &tm_buf);
+ strftime (the_time, sizeof (the_time),
+ /* TRANSLATORS: "strftime options for date of last login" */
+ _(" %a %b %e %H:%M:%S %Z %Y"), tm);
+
+ date = the_time;
+ }
+
+ /* we want & have the host? */
+ if ((announce & LASTLOG_HOST)
+ && (utuser.ut_host[0] != '\0')) {
+ /* TRANSLATORS: " from <host>" */
+ if (asprintf(&host, _(" from %.*s"), UT_HOSTSIZE,
+ utuser.ut_host) < 0) {
+ pam_syslog(pamh, LOG_CRIT, "out of memory");
+ retval = PAM_BUF_ERR;
+ goto cleanup;
+ }
+ }
+
+ /* we want and have the terminal? */
+ if ((announce & LASTLOG_LINE)
+ && (utuser.ut_line[0] != '\0')) {
+ /* TRANSLATORS: " on <terminal>" */
+ if (asprintf(&line, _(" on %.*s"), UT_LINESIZE,
+ utuser.ut_line) < 0) {
+ pam_syslog(pamh, LOG_CRIT, "out of memory");
+ retval = PAM_BUF_ERR;
+ goto cleanup;
+ }
+ }
+
+ if (line != NULL || date != NULL || host != NULL) {
+ /* TRANSLATORS: "Last failed login: <date> from <host> on <terminal>" */
+ pam_info(pamh, _("Last failed login:%s%s%s"),
+ date ? date : "",
+ host ? host : "",
+ line ? line : "");
+ }
+
+ _pam_drop(line);
+#if defined HAVE_DNGETTEXT && defined ENABLE_NLS
+ retval = asprintf (&line, dngettext(PACKAGE,
+ "There was %d failed login attempt since the last successful login.",
+ "There were %d failed login attempts since the last successful login.",
+ failed),
+ failed);
+#else
+ if (failed == 1)
+ retval = asprintf(&line,
+ _("There was %d failed login attempt since the last successful login."),
+ failed);
+ else
+ retval = asprintf(&line,
+ /* TRANSLATORS: only used if dngettext is not supported */
+ _("There were %d failed login attempts since the last successful login."),
+ failed);
+#endif
+ if (retval >= 0)
+ retval = pam_info(pamh, "%s", line);
+ else {
+ retval = PAM_BUF_ERR;
+ line = NULL;
+ }
+ }
+
+cleanup:
+ free(host);
+ free(line);
+ close(fd);
+ D(("all done with btmp"));
+
+ return retval;
+}
+
+/* --- authentication (locking out inactive users) functions --- */
+int
+pam_sm_authenticate(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ int retval, ctrl;
+ const char *user = NULL;
+ const struct passwd *pwd;
+ uid_t uid;
+ time_t lltime = 0;
+ time_t inactive_days = 0;
+ int last_fd;
+
+ /*
+ * Lock out the user if he did not login recently enough.
+ */
+
+ ctrl = _pam_auth_parse(pamh, flags, argc, argv, &inactive_days);
+
+ /* which user? */
+
+ if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE, "cannot determine user name");
+ return PAM_USER_UNKNOWN;
+ }
+
+ /* what uid? */
+
+ pwd = pam_modutil_getpwnam (pamh, user);
+ if (pwd == NULL) {
+ pam_syslog(pamh, LOG_NOTICE, "user unknown");
+ return PAM_USER_UNKNOWN;
+ }
+ uid = pwd->pw_uid;
+ pwd = NULL; /* tidy up */
+
+ if (uid == 0 || uid > get_lastlog_uid_max(pamh))
+ return PAM_SUCCESS;
+
+ /* obtain the last login date and all the relevant info */
+ last_fd = last_login_open(pamh, ctrl, uid);
+ if (last_fd < 0) {
+ return PAM_IGNORE;
+ }
+
+ retval = last_login_read(pamh, ctrl|LASTLOG_QUIET, last_fd, uid, &lltime);
+ close(last_fd);
+
+ if (retval != PAM_SUCCESS) {
+ D(("error while reading lastlog file"));
+ return PAM_IGNORE;
+ }
+
+ if (lltime == 0) { /* user never logged in before */
+ if (ctrl & LASTLOG_DEBUG)
+ pam_syslog(pamh, LOG_DEBUG, "user never logged in - pass");
+ return PAM_SUCCESS;
+ }
+
+ lltime = (time(NULL) - lltime) / (24*60*60);
+
+ if (lltime > inactive_days) {
+ pam_syslog(pamh, LOG_INFO, "user %s inactive for %ld days - denied",
+ user, (long) lltime);
+ return PAM_AUTH_ERR;
+ }
+
+ return PAM_SUCCESS;
+}
+
+int
+pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
+
+int
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+/* --- session management functions --- */
+
+int
+pam_sm_open_session(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ int retval, ctrl;
+ const void *user;
+ const struct passwd *pwd;
+ uid_t uid;
+ time_t lltime = 0;
+
+ /*
+ * this module gets the uid of the PAM_USER. Uses it to display
+ * last login info and then updates the lastlog for that user.
+ */
+
+ ctrl = _pam_session_parse(pamh, flags, argc, argv);
+
+ /* which user? */
+
+ retval = pam_get_item(pamh, PAM_USER, &user);
+ if (retval != PAM_SUCCESS || user == NULL || *(const char *)user == '\0') {
+ pam_syslog(pamh, LOG_NOTICE, "user unknown");
+ return PAM_USER_UNKNOWN;
+ }
+
+ /* what uid? */
+
+ pwd = pam_modutil_getpwnam (pamh, user);
+ if (pwd == NULL) {
+ D(("couldn't identify user %s", user));
+ return PAM_USER_UNKNOWN;
+ }
+ uid = pwd->pw_uid;
+ pwd = NULL; /* tidy up */
+
+ /* process the current login attempt (indicate last) */
+
+ retval = last_login_date(pamh, ctrl, uid, user, &lltime);
+
+ if ((ctrl & LASTLOG_BTMP) && retval == PAM_SUCCESS) {
+ retval = last_login_failed(pamh, ctrl, user, lltime);
+ }
+
+ /* indicate success or failure */
+
+ uid = -1; /* forget this */
+
+ return retval;
+}
+
+int
+pam_sm_close_session (pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ const char *terminal_line;
+
+ if (!(_pam_session_parse(pamh, flags, argc, argv) & LASTLOG_WTMP))
+ return PAM_SUCCESS;
+
+ terminal_line = get_tty(pamh);
+
+ /* Wipe out utmp logout entry */
+ logwtmp(terminal_line, "", "");
+
+ return PAM_SUCCESS;
+}
+
+/* end of module definition */
diff --git a/modules/pam_lastlog/tst-pam_lastlog b/modules/pam_lastlog/tst-pam_lastlog
new file mode 100755
index 0000000..ea9a5eb
--- /dev/null
+++ b/modules/pam_lastlog/tst-pam_lastlog
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_lastlog.so
diff --git a/modules/pam_limits/Makefile.am b/modules/pam_limits/Makefile.am
new file mode 100644
index 0000000..911b07b
--- /dev/null
+++ b/modules/pam_limits/Makefile.am
@@ -0,0 +1,40 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = limits.conf.5 pam_limits.8
+endif
+XMLS = README.xml limits.conf.5.xml pam_limits.8.xml
+dist_check_SCRIPTS = tst-pam_limits
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+limits_conf_dir = $(SCONFIGDIR)/limits.d
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DLIMITS_FILE_DIR=\"$(limits_conf_dir)/*.conf\" \
+ -DLIMITS_FILE=\"$(SCONFIGDIR)/limits.conf\" $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_limits.la
+pam_limits_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+dist_secureconf_DATA = limits.conf
+
+install-data-local:
+ mkdir -p $(DESTDIR)$(limits_conf_dir)
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_limits/Makefile.in b/modules/pam_limits/Makefile.in
new file mode 100644
index 0000000..ac26508
--- /dev/null
+++ b/modules/pam_limits/Makefile.in
@@ -0,0 +1,1227 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_limits
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(dist_secureconf_DATA) \
+ $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man5dir)" \
+ "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(secureconfdir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_limits_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_limits_la_SOURCES = pam_limits.c
+pam_limits_la_OBJECTS = pam_limits.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_limits.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_limits.c
+DIST_SOURCES = pam_limits.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man5dir = $(mandir)/man5
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA) $(dist_secureconf_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = limits.conf.5 pam_limits.8
+XMLS = README.xml limits.conf.5.xml pam_limits.8.xml
+dist_check_SCRIPTS = tst-pam_limits
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+limits_conf_dir = $(SCONFIGDIR)/limits.d
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DLIMITS_FILE_DIR=\"$(limits_conf_dir)/*.conf\" \
+ -DLIMITS_FILE=\"$(SCONFIGDIR)/limits.conf\" $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_limits.la
+pam_limits_la_LIBADD = $(top_builddir)/libpam/libpam.la
+dist_secureconf_DATA = limits.conf
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_limits/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_limits/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_limits.la: $(pam_limits_la_OBJECTS) $(pam_limits_la_DEPENDENCIES) $(EXTRA_pam_limits_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_limits_la_OBJECTS) $(pam_limits_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_limits.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man5: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man5dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.5[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man5:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man5dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.5[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir)
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+install-dist_secureconfDATA: $(dist_secureconf_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_secureconf_DATA)'; test -n "$(secureconfdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(secureconfdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(secureconfdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(secureconfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(secureconfdir)" || exit $$?; \
+ done
+
+uninstall-dist_secureconfDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_secureconf_DATA)'; test -n "$(secureconfdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(secureconfdir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_limits.log: tst-pam_limits
+ @p='tst-pam_limits'; \
+ b='tst-pam_limits'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(secureconfdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_limits.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-data-local install-dist_secureconfDATA \
+ install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man5 install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_limits.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-dist_secureconfDATA uninstall-man \
+ uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man5 uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-data-local install-dist_secureconfDATA \
+ install-dvi install-dvi-am install-exec install-exec-am \
+ install-html install-html-am install-info install-info-am \
+ install-man install-man5 install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am \
+ uninstall-dist_secureconfDATA uninstall-man uninstall-man5 \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+
+install-data-local:
+ mkdir -p $(DESTDIR)$(limits_conf_dir)
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_limits/README b/modules/pam_limits/README
new file mode 100644
index 0000000..ed104d6
--- /dev/null
+++ b/modules/pam_limits/README
@@ -0,0 +1,70 @@
+pam_limits — PAM module to limit resources
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+The pam_limits PAM module sets limits on the system resources that can be
+obtained in a user-session. Users of uid=0 are affected by this limits, too.
+
+By default limits are taken from the /etc/security/limits.conf config file.
+Then individual *.conf files from the /etc/security/limits.d/ directory are
+read. The files are parsed one after another in the order of "C" locale. The
+effect of the individual files is the same as if all the files were
+concatenated together in the order of parsing. If a config file is explicitly
+specified with a module option then the files in the above directory are not
+parsed.
+
+The module must not be called by a multithreaded application.
+
+If Linux PAM is compiled with audit support the module will report when it
+denies access based on limit of maximum number of concurrent login sessions.
+
+OPTIONS
+
+conf=/path/to/limits.conf
+
+ Indicate an alternative limits.conf style configuration file to override
+ the default.
+
+debug
+
+ Print debug information.
+
+set_all
+
+ Set the limits for which no value is specified in the configuration file to
+ the one from the process with the PID 1. Please note that if the init
+ process is systemd these limits will not be the kernel default limits and
+ this option should not be used.
+
+utmp_early
+
+ Some broken applications actually allocate a utmp entry for the user before
+ the user is admitted to the system. If some of the services you are
+ configuring PAM for do this, you can selectively use this module argument
+ to compensate for this behavior and at the same time maintain system-wide
+ consistency with a single limits.conf file.
+
+noaudit
+
+ Do not report exceeded maximum logins count to the audit subsystem.
+
+EXAMPLES
+
+These are some example lines which might be specified in /etc/security/
+limits.conf.
+
+* soft core 0
+* hard nofile 512
+@student hard nproc 20
+@faculty soft nproc 20
+@faculty hard nproc 50
+ftp hard nproc 0
+@student - maxlogins 4
+@student - nonewprivs 1
+:123 hard cpu 5000
+@500: soft cpu 10000
+600:700 hard locks 10
+
+
diff --git a/modules/pam_limits/README.xml b/modules/pam_limits/README.xml
new file mode 100644
index 0000000..964a5a2
--- /dev/null
+++ b/modules/pam_limits/README.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamlimits SYSTEM "pam_limits.8.xml">
+-->
+<!--
+<!ENTITY limitsconf SYSTEM "limits.conf.5.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_limits.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_limits-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_limits.8.xml" xpointer='xpointer(//refsect1[@id = "pam_limits-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_limits.8.xml" xpointer='xpointer(//refsect1[@id = "pam_limits-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="limits.conf.5.xml" xpointer='xpointer(//refsect1[@id = "limits.conf-examples"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_limits/limits.conf b/modules/pam_limits/limits.conf
new file mode 100644
index 0000000..e8a746c
--- /dev/null
+++ b/modules/pam_limits/limits.conf
@@ -0,0 +1,61 @@
+# /etc/security/limits.conf
+#
+#This file sets the resource limits for the users logged in via PAM.
+#It does not affect resource limits of the system services.
+#
+#Also note that configuration files in /etc/security/limits.d directory,
+#which are read in alphabetical order, override the settings in this
+#file in case the domain is the same or more specific.
+#That means, for example, that setting a limit for wildcard domain here
+#can be overridden with a wildcard setting in a config file in the
+#subdirectory, but a user specific setting here can be overridden only
+#with a user specific setting in the subdirectory.
+#
+#Each line describes a limit for a user in the form:
+#
+#<domain> <type> <item> <value>
+#
+#Where:
+#<domain> can be:
+# - a user name
+# - a group name, with @group syntax
+# - the wildcard *, for default entry
+# - the wildcard %, can be also used with %group syntax,
+# for maxlogin limit
+#
+#<type> can have the two values:
+# - "soft" for enforcing the soft limits
+# - "hard" for enforcing hard limits
+#
+#<item> can be one of the following:
+# - core - limits the core file size (KB)
+# - data - max data size (KB)
+# - fsize - maximum filesize (KB)
+# - memlock - max locked-in-memory address space (KB)
+# - nofile - max number of open file descriptors
+# - rss - max resident set size (KB)
+# - stack - max stack size (KB)
+# - cpu - max CPU time (MIN)
+# - nproc - max number of processes
+# - as - address space limit (KB)
+# - maxlogins - max number of logins for this user
+# - maxsyslogins - max number of logins on the system
+# - priority - the priority to run user process with
+# - locks - max number of file locks the user can hold
+# - sigpending - max number of pending signals
+# - msgqueue - max memory used by POSIX message queues (bytes)
+# - nice - max nice priority allowed to raise to values: [-20, 19]
+# - rtprio - max realtime priority
+#
+#<domain> <type> <item> <value>
+#
+
+#* soft core 0
+#* hard rss 10000
+#@student hard nproc 20
+#@faculty soft nproc 20
+#@faculty hard nproc 50
+#ftp hard nproc 0
+#@student - maxlogins 4
+
+# End of file
diff --git a/modules/pam_limits/limits.conf.5 b/modules/pam_limits/limits.conf.5
new file mode 100644
index 0000000..a4a0ed3
--- /dev/null
+++ b/modules/pam_limits/limits.conf.5
@@ -0,0 +1,349 @@
+'\" t
+.\" Title: limits.conf
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "LIMITS\&.CONF" "5" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+limits.conf \- configuration file for the pam_limits module
+.SH "DESCRIPTION"
+.PP
+The
+\fIpam_limits\&.so\fR
+module applies ulimit limits, nice priority and number of simultaneous login sessions limit to user login sessions\&. This description of the configuration file syntax applies to the
+/etc/security/limits\&.conf
+file and
+*\&.conf
+files in the
+/etc/security/limits\&.d
+directory\&.
+.PP
+The syntax of the lines is as follows:
+.PP
+\fI<domain>\fR
+\fI<type>\fR
+\fI<item>\fR
+\fI<value>\fR
+.PP
+The fields listed above should be filled as follows:
+.PP
+\fB<domain>\fR
+.RS 4
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+a username
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+a groupname, with
+\fB@group\fR
+syntax\&. This should not be confused with netgroups\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+the wildcard
+\fB*\fR, for default entry\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+the wildcard
+\fB%\fR, for maxlogins limit only, can also be used with
+\fB%group\fR
+syntax\&. If the
+\fB%\fR
+wildcard is used alone it is identical to using
+\fB*\fR
+with maxsyslogins limit\&. With a group specified after
+\fB%\fR
+it limits the total number of logins of all users that are member of the group\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+an uid range specified as
+\fI<min_uid>\fR\fB:\fR\fI<max_uid>\fR\&. If min_uid is omitted, the match is exact for the max_uid\&. If max_uid is omitted, all uids greater than or equal min_uid match\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+a gid range specified as
+\fB@\fR\fI<min_gid>\fR\fB:\fR\fI<max_gid>\fR\&. If min_gid is omitted, the match is exact for the max_gid\&. If max_gid is omitted, all gids greater than or equal min_gid match\&. For the exact match all groups including the user\*(Aqs supplementary groups are examined\&. For the range matches only the user\*(Aqs primary group is examined\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+a gid specified as
+\fB%:\fR\fI<gid>\fR
+applicable to maxlogins limit only\&. It limits the total number of logins of all users that are member of the group with the specified gid\&.
+.RE
+.RE
+.PP
+\fB<type>\fR
+.RS 4
+.PP
+\fBhard\fR
+.RS 4
+for enforcing
+\fBhard\fR
+resource limits\&. These limits are set by the superuser and enforced by the Kernel\&. The user cannot raise his requirement of system resources above such values\&.
+.RE
+.PP
+\fBsoft\fR
+.RS 4
+for enforcing
+\fBsoft\fR
+resource limits\&. These limits are ones that the user can move up or down within the permitted range by any pre\-existing
+\fBhard\fR
+limits\&. The values specified with this token can be thought of as
+\fIdefault\fR
+values, for normal system usage\&.
+.RE
+.PP
+\fB\-\fR
+.RS 4
+for enforcing both
+\fBsoft\fR
+and
+\fBhard\fR
+resource limits together\&.
+.sp
+Note, if you specify a type of \*(Aq\-\*(Aq but neglect to supply the item and value fields then the module will never enforce any limits on the specified user/group etc\&. \&.
+.RE
+.RE
+.PP
+\fB<item>\fR
+.RS 4
+.PP
+\fBcore\fR
+.RS 4
+limits the core file size (KB)
+.RE
+.PP
+\fBdata\fR
+.RS 4
+maximum data size (KB)
+.RE
+.PP
+\fBfsize\fR
+.RS 4
+maximum filesize (KB)
+.RE
+.PP
+\fBmemlock\fR
+.RS 4
+maximum locked\-in\-memory address space (KB)
+.RE
+.PP
+\fBnofile\fR
+.RS 4
+maximum number of open file descriptors
+.RE
+.PP
+\fBrss\fR
+.RS 4
+maximum resident set size (KB) (Ignored in Linux 2\&.4\&.30 and higher)
+.RE
+.PP
+\fBstack\fR
+.RS 4
+maximum stack size (KB)
+.RE
+.PP
+\fBcpu\fR
+.RS 4
+maximum CPU time (minutes)
+.RE
+.PP
+\fBnproc\fR
+.RS 4
+maximum number of processes
+.RE
+.PP
+\fBas\fR
+.RS 4
+address space limit (KB)
+.RE
+.PP
+\fBmaxlogins\fR
+.RS 4
+maximum number of logins for this user (this limit does not apply to user with
+\fIuid=0\fR)
+.RE
+.PP
+\fBmaxsyslogins\fR
+.RS 4
+maximum number of all logins on system; user is not allowed to log\-in if total number of all user logins is greater than specified number (this limit does not apply to user with
+\fIuid=0\fR)
+.RE
+.PP
+\fBnonewprivs\fR
+.RS 4
+value of 0 or 1; if set to 1 disables acquiring new privileges by invoking prctl(PR_SET_NO_NEW_PRIVS)
+.RE
+.PP
+\fBpriority\fR
+.RS 4
+the priority to run user process with (negative values boost process priority)
+.RE
+.PP
+\fBlocks\fR
+.RS 4
+maximum locked files (Linux 2\&.4 and higher)
+.RE
+.PP
+\fBsigpending\fR
+.RS 4
+maximum number of pending signals (Linux 2\&.6 and higher)
+.RE
+.PP
+\fBmsgqueue\fR
+.RS 4
+maximum memory used by POSIX message queues (bytes) (Linux 2\&.6 and higher)
+.RE
+.PP
+\fBnice\fR
+.RS 4
+maximum nice priority allowed to raise to (Linux 2\&.6\&.12 and higher) values: [\-20,19]
+.RE
+.PP
+\fBrtprio\fR
+.RS 4
+maximum realtime priority allowed for non\-privileged processes (Linux 2\&.6\&.12 and higher)
+.RE
+.RE
+.PP
+All items support the values
+\fI\-1\fR,
+\fIunlimited\fR
+or
+\fIinfinity\fR
+indicating no limit, except for
+\fBpriority\fR,
+\fBnice\fR, and
+\fBnonewprivs\fR\&. If
+\fBnofile\fR
+is to be set to one of these values, it will be set to the contents of /proc/sys/fs/nr_open instead (see setrlimit(3))\&.
+.PP
+If a hard limit or soft limit of a resource is set to a valid value, but outside of the supported range of the local system, the system may reject the new limit or unexpected behavior may occur\&. If the control value
+\fIrequired\fR
+is used, the module will reject the login if a limit could not be set\&.
+.PP
+In general, individual limits have priority over group limits, so if you impose no limits for
+\fIadmin\fR
+group, but one of the members in this group have a limits line, the user will have its limits set according to this line\&.
+.PP
+Also, please note that all limit settings are set
+\fIper login\fR\&. They are not global, nor are they permanent; existing only for the duration of the session\&. One exception is the
+\fImaxlogin\fR
+option, this one is system wide\&. But there is a race, concurrent logins at the same time will not always be detect as such but only counted as one\&.
+.PP
+In the
+\fIlimits\fR
+configuration file, the \*(Aq\fB#\fR\*(Aq character introduces a comment \- after which the rest of the line is ignored\&.
+.PP
+The pam_limits module does report configuration problems found in its configuration file and errors via
+\fBsyslog\fR(3)\&.
+.SH "EXAMPLES"
+.PP
+These are some example lines which might be specified in
+/etc/security/limits\&.conf\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+* soft core 0
+* hard nofile 512
+@student hard nproc 20
+@faculty soft nproc 20
+@faculty hard nproc 50
+ftp hard nproc 0
+@student \- maxlogins 4
+@student \- nonewprivs 1
+:123 hard cpu 5000
+@500: soft cpu 10000
+600:700 hard locks 10
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+.PP
+\fBpam_limits\fR(8),
+\fBpam.d\fR(5),
+\fBpam\fR(8),
+\fBgetrlimit\fR(2),
+\fBgetrlimit\fR(3p)
+.SH "AUTHOR"
+.PP
+pam_limits was initially written by Cristian Gafton <gafton@redhat\&.com>
diff --git a/modules/pam_limits/limits.conf.5.xml b/modules/pam_limits/limits.conf.5.xml
new file mode 100644
index 0000000..c5bd676
--- /dev/null
+++ b/modules/pam_limits/limits.conf.5.xml
@@ -0,0 +1,360 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="limits.conf">
+
+ <refmeta>
+ <refentrytitle>limits.conf</refentrytitle>
+ <manvolnum>5</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>limits.conf</refname>
+ <refpurpose>configuration file for the pam_limits module</refpurpose>
+ </refnamediv>
+
+ <refsect1 id='limits.conf-description'>
+ <title>DESCRIPTION</title>
+ <para>
+ The <emphasis>pam_limits.so</emphasis> module applies ulimit limits,
+ nice priority and number of simultaneous login sessions limit to user
+ login sessions. This description of the configuration file syntax
+ applies to the <filename>/etc/security/limits.conf</filename> file and
+ <filename>*.conf</filename> files in the
+ <filename>/etc/security/limits.d</filename> directory.
+ </para>
+ <para>
+ The syntax of the lines is as follows:
+ </para>
+ <para>
+ <replaceable>&lt;domain&gt;</replaceable> <replaceable>&lt;type&gt;</replaceable>
+ <replaceable>&lt;item&gt;</replaceable> <replaceable>&lt;value&gt;</replaceable>
+ </para>
+ <para>
+ The fields listed above should be filled as follows:
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>&lt;domain&gt;</option>
+ </term>
+ <listitem>
+ <itemizedlist>
+ <listitem>
+ <para>
+ a username
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ a groupname, with <emphasis remap='B'>@group</emphasis> syntax.
+ This should not be confused with netgroups.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ the wildcard <emphasis remap='B'>*</emphasis>, for default entry.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ the wildcard <emphasis remap='B'>%</emphasis>, for maxlogins limit only,
+ can also be used with <emphasis remap='B'>%group</emphasis> syntax. If the
+ <emphasis remap='B'>%</emphasis> wildcard is used alone it is identical
+ to using <emphasis remap='B'>*</emphasis> with maxsyslogins limit. With
+ a group specified after <emphasis remap='B'>%</emphasis> it limits the total
+ number of logins of all users that are member of the group.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ an uid range specified as <replaceable>&lt;min_uid&gt;</replaceable><emphasis
+ remap='B'>:</emphasis><replaceable>&lt;max_uid&gt;</replaceable>. If min_uid
+ is omitted, the match is exact for the max_uid. If max_uid is omitted, all
+ uids greater than or equal min_uid match.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ a gid range specified as <emphasis
+ remap='B'>@</emphasis><replaceable>&lt;min_gid&gt;</replaceable><emphasis
+ remap='B'>:</emphasis><replaceable>&lt;max_gid&gt;</replaceable>. If min_gid
+ is omitted, the match is exact for the max_gid. If max_gid is omitted, all
+ gids greater than or equal min_gid match. For the exact match all groups including
+ the user's supplementary groups are examined. For the range matches only
+ the user's primary group is examined.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ a gid specified as <emphasis
+ remap='B'>%:</emphasis><replaceable>&lt;gid&gt;</replaceable> applicable
+ to maxlogins limit only. It limits the total number of logins of all users
+ that are member of the group with the specified gid.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>&lt;type&gt;</option>
+ </term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term><option>hard</option></term>
+ <listitem>
+ <para>
+ for enforcing <emphasis remap='B'>hard</emphasis> resource limits.
+ These limits are set by the superuser and enforced by the Kernel.
+ The user cannot raise his requirement of system resources above such values.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>soft</option></term>
+ <listitem>
+ <para>
+ for enforcing <emphasis remap='B'>soft</emphasis> resource limits.
+ These limits are ones that the user can move up or down within the
+ permitted range by any pre-existing <emphasis remap='B'>hard</emphasis>
+ limits. The values specified with this token can be thought of as
+ <emphasis>default</emphasis> values, for normal system usage.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>-</option></term>
+ <listitem>
+ <para>
+ for enforcing both <emphasis remap='B'>soft</emphasis> and
+ <emphasis remap='B'>hard</emphasis> resource limits together.
+ </para>
+ <para>
+ Note, if you specify a type of '-' but neglect to supply the
+ item and value fields then the module will never enforce any
+ limits on the specified user/group etc. .
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>&lt;item&gt;</option>
+ </term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term><option>core</option></term>
+ <listitem>
+ <para>limits the core file size (KB)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>data</option></term>
+ <listitem>
+ <para>maximum data size (KB)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>fsize</option></term>
+ <listitem>
+ <para>maximum filesize (KB)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>memlock</option></term>
+ <listitem>
+ <para>maximum locked-in-memory address space (KB)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>nofile</option></term>
+ <listitem>
+ <para>maximum number of open file descriptors</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>rss</option></term>
+ <listitem>
+ <para>maximum resident set size (KB) (Ignored in Linux 2.4.30 and higher)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>stack</option></term>
+ <listitem>
+ <para>maximum stack size (KB)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>cpu</option></term>
+ <listitem>
+ <para>maximum CPU time (minutes)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>nproc</option></term>
+ <listitem>
+ <para>maximum number of processes</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>as</option></term>
+ <listitem>
+ <para>address space limit (KB)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>maxlogins</option></term>
+ <listitem>
+ <para>maximum number of logins for this user (this limit does
+ not apply to user with <emphasis>uid=0</emphasis>)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>maxsyslogins</option></term>
+ <listitem>
+ <para>maximum number of all logins on system; user is not
+ allowed to log-in if total number of all user logins is
+ greater than specified number (this limit does not apply to
+ user with <emphasis>uid=0</emphasis>)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>nonewprivs</option></term>
+ <listitem>
+ <para>value of 0 or 1; if set to 1 disables acquiring new
+ privileges by invoking prctl(PR_SET_NO_NEW_PRIVS)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>priority</option></term>
+ <listitem>
+ <para>the priority to run user process with (negative
+ values boost process priority)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>locks</option></term>
+ <listitem>
+ <para>maximum locked files (Linux 2.4 and higher)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>sigpending</option></term>
+ <listitem>
+ <para>maximum number of pending signals (Linux 2.6 and higher)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>msgqueue</option></term>
+ <listitem>
+ <para>maximum memory used by POSIX message queues (bytes)
+ (Linux 2.6 and higher)</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>nice</option></term>
+ <listitem>
+ <para>maximum nice priority allowed to raise to (Linux 2.6.12 and higher) values: [-20,19]</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>rtprio</option></term>
+ <listitem>
+ <para>maximum realtime priority allowed for non-privileged processes
+ (Linux 2.6.12 and higher)</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ <para>
+ All items support the values <emphasis>-1</emphasis>,
+ <emphasis>unlimited</emphasis> or <emphasis>infinity</emphasis> indicating no limit,
+ except for <emphasis remap='B'>priority</emphasis>, <emphasis remap='B'>nice</emphasis>,
+ and <emphasis remap='B'>nonewprivs</emphasis>.
+ If <emphasis remap='B'>nofile</emphasis> is to be set to one of these values,
+ it will be set to the contents of /proc/sys/fs/nr_open instead (see setrlimit(3)).
+ </para>
+ <para>
+ If a hard limit or soft limit of a resource is set to a valid value,
+ but outside of the supported range of the local system, the system
+ may reject the new limit or unexpected behavior may occur. If the
+ control value <emphasis>required</emphasis> is used, the module will
+ reject the login if a limit could not be set.
+ </para>
+ <para>
+ In general, individual limits have priority over group limits, so if
+ you impose no limits for <emphasis>admin</emphasis> group, but one of
+ the members in this group have a limits line, the user will have its
+ limits set according to this line.
+ </para>
+ <para>
+ Also, please note that all limit settings are set
+ <emphasis>per login</emphasis>. They are not global, nor are they
+ permanent; existing only for the duration of the session.
+ One exception is the <emphasis>maxlogin</emphasis> option, this one
+ is system wide. But there is a race, concurrent logins at the same
+ time will not always be detect as such but only counted as one.
+ </para>
+ <para>
+ In the <emphasis>limits</emphasis> configuration file, the
+ '<emphasis remap='B'>#</emphasis>' character introduces a comment
+ - after which the rest of the line is ignored.
+ </para>
+ <para>
+ The pam_limits module does report configuration problems
+ found in its configuration file and errors via <citerefentry>
+ <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="limits.conf-examples">
+ <title>EXAMPLES</title>
+ <para>
+ These are some example lines which might be specified in
+ <filename>/etc/security/limits.conf</filename>.
+ </para>
+ <programlisting>
+* soft core 0
+* hard nofile 512
+@student hard nproc 20
+@faculty soft nproc 20
+@faculty hard nproc 50
+ftp hard nproc 0
+@student - maxlogins 4
+@student - nonewprivs 1
+:123 hard cpu 5000
+@500: soft cpu 10000
+600:700 hard locks 10
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id="limits.conf-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry><refentrytitle>pam_limits</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>getrlimit</refentrytitle><manvolnum>2</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>getrlimit</refentrytitle><manvolnum>3p</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id="limits.conf-author">
+ <title>AUTHOR</title>
+ <para>
+ pam_limits was initially written by Cristian Gafton &lt;gafton@redhat.com&gt;
+ </para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_limits/pam_limits.8 b/modules/pam_limits/pam_limits.8
new file mode 100644
index 0000000..50e9a10
--- /dev/null
+++ b/modules/pam_limits/pam_limits.8
@@ -0,0 +1,152 @@
+'\" t
+.\" Title: pam_limits
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_LIMITS" "8" "09/03/2021" "Linux-PAM Manual" "Linux-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_limits \- PAM module to limit resources
+.SH "SYNOPSIS"
+.HP \w'\fBpam_limits\&.so\fR\ 'u
+\fBpam_limits\&.so\fR [conf=\fI/path/to/limits\&.conf\fR] [debug] [set_all] [utmp_early] [noaudit]
+.SH "DESCRIPTION"
+.PP
+The pam_limits PAM module sets limits on the system resources that can be obtained in a user\-session\&. Users of
+\fIuid=0\fR
+are affected by this limits, too\&.
+.PP
+By default limits are taken from the
+/etc/security/limits\&.conf
+config file\&. Then individual *\&.conf files from the
+/etc/security/limits\&.d/
+directory are read\&. The files are parsed one after another in the order of "C" locale\&. The effect of the individual files is the same as if all the files were concatenated together in the order of parsing\&. If a config file is explicitly specified with a module option then the files in the above directory are not parsed\&.
+.PP
+The module must not be called by a multithreaded application\&.
+.PP
+If Linux PAM is compiled with audit support the module will report when it denies access based on limit of maximum number of concurrent login sessions\&.
+.SH "OPTIONS"
+.PP
+\fBconf=\fR\fB\fI/path/to/limits\&.conf\fR\fR
+.RS 4
+Indicate an alternative limits\&.conf style configuration file to override the default\&.
+.RE
+.PP
+\fBdebug\fR
+.RS 4
+Print debug information\&.
+.RE
+.PP
+\fBset_all\fR
+.RS 4
+Set the limits for which no value is specified in the configuration file to the one from the process with the PID 1\&. Please note that if the init process is systemd these limits will not be the kernel default limits and this option should not be used\&.
+.RE
+.PP
+\fButmp_early\fR
+.RS 4
+Some broken applications actually allocate a utmp entry for the user before the user is admitted to the system\&. If some of the services you are configuring PAM for do this, you can selectively use this module argument to compensate for this behavior and at the same time maintain system\-wide consistency with a single limits\&.conf file\&.
+.RE
+.PP
+\fBnoaudit\fR
+.RS 4
+Do not report exceeded maximum logins count to the audit subsystem\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+Only the
+\fBsession\fR
+module type is provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_ABORT
+.RS 4
+Cannot get current limits\&.
+.RE
+.PP
+PAM_IGNORE
+.RS 4
+No limits found for this user\&.
+.RE
+.PP
+PAM_PERM_DENIED
+.RS 4
+New limits could not be set\&.
+.RE
+.PP
+PAM_SERVICE_ERR
+.RS 4
+Cannot read config file\&.
+.RE
+.PP
+PAM_SESSION_ERR
+.RS 4
+Error recovering account name\&.
+.RE
+.PP
+PAM_SUCCESS
+.RS 4
+Limits were changed\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+The user is not known to the system\&.
+.RE
+.SH "FILES"
+.PP
+/etc/security/limits\&.conf
+.RS 4
+Default configuration file
+.RE
+.SH "EXAMPLES"
+.PP
+For the services you need resources limits (login for example) put a the following line in
+/etc/pam\&.d/login
+as the last line for that service (usually after the pam_unix session line):
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+#%PAM\-1\&.0
+#
+# Resource limits imposed on login sessions via pam_limits
+#
+session required pam_limits\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Replace "login" for each service you are using this module\&.
+.SH "SEE ALSO"
+.PP
+\fBlimits.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)\&.
+.SH "AUTHORS"
+.PP
+pam_limits was initially written by Cristian Gafton <gafton@redhat\&.com>
diff --git a/modules/pam_limits/pam_limits.8.xml b/modules/pam_limits/pam_limits.8.xml
new file mode 100644
index 0000000..bc46cbf
--- /dev/null
+++ b/modules/pam_limits/pam_limits.8.xml
@@ -0,0 +1,257 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+
+<refentry id='pam_limits'>
+
+ <refmeta>
+ <refentrytitle>pam_limits</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id='pam_limits-name'>
+ <refname>pam_limits</refname>
+ <refpurpose>
+ PAM module to limit resources
+ </refpurpose>
+ </refnamediv>
+
+<!-- body begins here -->
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_limits-cmdsynopsis">
+ <command>pam_limits.so</command>
+ <arg choice="opt">
+ conf=<replaceable>/path/to/limits.conf</replaceable>
+ </arg>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ set_all
+ </arg>
+ <arg choice="opt">
+ utmp_early
+ </arg>
+ <arg choice="opt">
+ noaudit
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1 id="pam_limits-description">
+ <title>DESCRIPTION</title>
+ <para>
+ The pam_limits PAM module sets limits on the system resources that can be
+ obtained in a user-session. Users of <emphasis>uid=0</emphasis> are affected
+ by this limits, too.
+ </para>
+ <para>
+ By default limits are taken from the <filename>/etc/security/limits.conf</filename>
+ config file. Then individual *.conf files from the <filename>/etc/security/limits.d/</filename>
+ directory are read. The files are parsed one after another in the order of "C" locale.
+ The effect of the individual files is the same as if all the files were
+ concatenated together in the order of parsing.
+ If a config file is explicitly specified with a module option then the
+ files in the above directory are not parsed.
+ </para>
+ <para>
+ The module must not be called by a multithreaded application.
+ </para>
+ <para>
+ If Linux PAM is compiled with audit support the module will report
+ when it denies access based on limit of maximum number of concurrent
+ login sessions.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_limits-options">
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>conf=<replaceable>/path/to/limits.conf</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Indicate an alternative limits.conf style configuration file to
+ override the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Print debug information.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>set_all</option>
+ </term>
+ <listitem>
+ <para>
+ Set the limits for which no value is specified in the
+ configuration file to the one from the process with the
+ PID 1. Please note that if the init process is systemd
+ these limits will not be the kernel default limits and
+ this option should not be used.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>utmp_early</option>
+ </term>
+ <listitem>
+ <para>
+ Some broken applications actually allocate a utmp entry for
+ the user before the user is admitted to the system. If some
+ of the services you are configuring PAM for do this, you can
+ selectively use this module argument to compensate for this
+ behavior and at the same time maintain system-wide consistency
+ with a single limits.conf file.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>noaudit</option>
+ </term>
+ <listitem>
+ <para>
+ Do not report exceeded maximum logins count to the audit subsystem.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_limits-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ Only the <option>session</option> module type is provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_limits-return_values">
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_ABORT</term>
+ <listitem>
+ <para>
+ Cannot get current limits.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ No limits found for this user.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_PERM_DENIED</term>
+ <listitem>
+ <para>
+ New limits could not be set.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ Cannot read config file.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SESSION_ERR</term>
+ <listitem>
+ <para>
+ Error recovering account name.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Limits were changed.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ The user is not known to the system.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_limits-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/security/limits.conf</filename></term>
+ <listitem>
+ <para>Default configuration file</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_limits-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ For the services you need resources limits (login for example) put a
+ the following line in <filename>/etc/pam.d/login</filename> as the last
+ line for that service (usually after the pam_unix session line):
+ </para>
+ <programlisting>
+#%PAM-1.0
+#
+# Resource limits imposed on login sessions via pam_limits
+#
+session required pam_limits.so
+ </programlisting>
+ <para>
+ Replace "login" for each service you are using this module.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_limits-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>limits.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_limits-authors">
+ <title>AUTHORS</title>
+ <para>
+ pam_limits was initially written by Cristian Gafton &lt;gafton@redhat.com&gt;
+ </para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_limits/pam_limits.c b/modules/pam_limits/pam_limits.c
new file mode 100644
index 0000000..7cc45d7
--- /dev/null
+++ b/modules/pam_limits/pam_limits.c
@@ -0,0 +1,1215 @@
+/*
+ * pam_limits - impose resource limits when opening a user session
+ *
+ * 1.6 - modified for PLD (added process priority settings)
+ * by Marcin Korzonek <mkorz@shadow.eu.org>
+ * 1.5 - Elliot Lee's "max system logins patch"
+ * 1.4 - addressed bug in configuration file parser
+ * 1.3 - modified the configuration file format
+ * 1.2 - added 'debug' and 'conf=' arguments
+ * 1.1 - added @group support
+ * 1.0 - initial release - Linux ONLY
+ *
+ * See end for Copyright information
+ */
+
+#if !defined(linux) && !defined(__linux)
+#warning THIS CODE IS KNOWN TO WORK ONLY ON LINUX !!!
+#endif
+
+#include "config.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <signal.h>
+#include <sys/prctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/resource.h>
+#include <limits.h>
+#include <glob.h>
+#include <utmp.h>
+#ifndef UT_USER /* some systems have ut_name instead of ut_user */
+#define UT_USER ut_user
+#endif
+
+#include <grp.h>
+#include <pwd.h>
+#include <locale.h>
+
+#ifdef HAVE_LIBAUDIT
+#include <libaudit.h>
+#endif
+
+/* Module defines */
+#define LINE_LENGTH 1024
+
+#define LIMITS_DEF_USER 0 /* limit was set by a user entry */
+#define LIMITS_DEF_GROUP 1 /* limit was set by a group entry */
+#define LIMITS_DEF_ALLGROUP 2 /* limit was set by a group entry */
+#define LIMITS_DEF_ALL 3 /* limit was set by an all entry */
+#define LIMITS_DEF_DEFAULT 4 /* limit was set by a default entry */
+#define LIMITS_DEF_KERNEL 5 /* limit was set from /proc/1/limits */
+#define LIMITS_DEF_NONE 6 /* this limit was not set yet */
+
+#define LIMIT_RANGE_ERR -1 /* error in specified uid/gid range */
+#define LIMIT_RANGE_NONE 0 /* no range specified */
+#define LIMIT_RANGE_ONE 1 /* exact uid/gid specified (:max_uid)*/
+#define LIMIT_RANGE_MIN 2 /* only minimum uid/gid specified (min_uid:) */
+#define LIMIT_RANGE_MM 3 /* both min and max uid/gid specified (min_uid:max_uid) */
+
+static const char *limits_def_names[] = {
+ "USER",
+ "GROUP",
+ "ALLGROUP",
+ "ALL",
+ "DEFAULT",
+ "KERNEL",
+ "NONE",
+ NULL
+};
+
+struct user_limits_struct {
+ int supported;
+ int src_soft;
+ int src_hard;
+ struct rlimit limit;
+};
+
+/* internal data */
+struct pam_limit_s {
+ int login_limit; /* the max logins limit */
+ int login_limit_def; /* which entry set the login limit */
+ int flag_numsyslogins; /* whether to limit logins only for a
+ specific user or to count all logins */
+ int priority; /* the priority to run user process with */
+ int nonewprivs; /* whether to prctl(PR_SET_NO_NEW_PRIVS) */
+ struct user_limits_struct limits[RLIM_NLIMITS];
+ const char *conf_file;
+ int utmp_after_pam_call;
+ char login_group[LINE_LENGTH];
+};
+
+#define LIMIT_LOGIN RLIM_NLIMITS+1
+#define LIMIT_NUMSYSLOGINS RLIM_NLIMITS+2
+
+#define LIMIT_PRI RLIM_NLIMITS+3
+#define LIMIT_NONEWPRIVS RLIM_NLIMITS+4
+
+#define LIMIT_SOFT 1
+#define LIMIT_HARD 2
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+#include "pam_inline.h"
+
+/* argument parsing */
+
+#define PAM_DEBUG_ARG 0x0001
+#define PAM_UTMP_EARLY 0x0004
+#define PAM_NO_AUDIT 0x0008
+#define PAM_SET_ALL 0x0010
+
+/* Limits from globbed files. */
+#define LIMITS_CONF_GLOB LIMITS_FILE_DIR
+
+#define CONF_FILE (pl->conf_file != NULL)?pl->conf_file:LIMITS_FILE
+
+static int
+_pam_parse (const pam_handle_t *pamh, int argc, const char **argv,
+ struct pam_limit_s *pl)
+{
+ int ctrl=0;
+
+ /* step through arguments */
+ for (ctrl=0; argc-- > 0; ++argv) {
+ const char *str;
+
+ /* generic options */
+
+ if (!strcmp(*argv,"debug")) {
+ ctrl |= PAM_DEBUG_ARG;
+ } else if ((str = pam_str_skip_prefix(*argv, "conf=")) != NULL) {
+ pl->conf_file = str;
+ } else if (!strcmp(*argv,"utmp_early")) {
+ ctrl |= PAM_UTMP_EARLY;
+ } else if (!strcmp(*argv,"noaudit")) {
+ ctrl |= PAM_NO_AUDIT;
+ } else if (!strcmp(*argv,"set_all")) {
+ ctrl |= PAM_SET_ALL;
+ } else {
+ pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
+ }
+ }
+
+ return ctrl;
+}
+
+static const char *
+rlimit2str (int i)
+{
+ switch (i) {
+ case RLIMIT_CPU:
+ return "cpu";
+ break;
+ case RLIMIT_FSIZE:
+ return "fsize";
+ break;
+ case RLIMIT_DATA:
+ return "data";
+ break;
+ case RLIMIT_STACK:
+ return "stack";
+ break;
+ case RLIMIT_CORE:
+ return "core";
+ break;
+ case RLIMIT_RSS:
+ return "rss";
+ break;
+ case RLIMIT_NPROC:
+ return "nproc";
+ break;
+ case RLIMIT_NOFILE:
+ return "nofile";
+ break;
+ case RLIMIT_MEMLOCK:
+ return "memlock";
+ break;
+#ifdef RLIMIT_AS
+ case RLIMIT_AS:
+ return "as";
+ break;
+#endif
+#ifdef RLIMIT_LOCKS
+ case RLIMIT_LOCKS:
+ return "locks";
+ break;
+#endif
+#ifdef RLIMIT_SIGPENDING
+ case RLIMIT_SIGPENDING:
+ return "sigpending";
+ break;
+#endif
+#ifdef RLIMIT_MSGQUEUE
+ case RLIMIT_MSGQUEUE:
+ return "msgqueue";
+ break;
+#endif
+#ifdef RLIMIT_NICE
+ case RLIMIT_NICE:
+ return "nice";
+ break;
+#endif
+#ifdef RLIMIT_RTPRIO
+ case RLIMIT_RTPRIO:
+ return "rtprio";
+ break;
+#endif
+ default:
+ return "UNKNOWN";
+ break;
+ }
+}
+
+
+#define LIMITED_OK 0 /* limit setting appeared to work */
+#define LIMIT_ERR 1 /* error setting a limit */
+#define LOGIN_ERR 2 /* too many logins err */
+
+/* Counts the number of user logins and check against the limit*/
+static int
+check_logins (pam_handle_t *pamh, const char *name, int limit, int ctrl,
+ struct pam_limit_s *pl)
+{
+ struct utmp *ut;
+ int count;
+
+ if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "checking logins for '%s' (maximum of %d)", name, limit);
+ }
+
+ if (limit < 0)
+ return 0; /* no limits imposed */
+ if (limit == 0) /* maximum 0 logins ? */ {
+ pam_syslog(pamh, LOG_WARNING, "No logins allowed for '%s'", name);
+ return LOGIN_ERR;
+ }
+
+ setutent();
+
+ /* Because there is no definition about when an application
+ actually adds a utmp entry, some applications bizarrely do the
+ utmp call before the have PAM authenticate them to the system:
+ you're logged it, sort of...? Anyway, you can use the
+ "utmp_early" module argument in your PAM config file to make
+ allowances for this sort of problem. (There should be a PAM
+ standard for this, since if a module wants to actually map a
+ username then any early utmp entry will be for the unmapped
+ name = broken.) */
+
+ if (ctrl & PAM_UTMP_EARLY) {
+ count = 0;
+ } else {
+ count = 1;
+ }
+
+ while((ut = getutent())) {
+#ifdef USER_PROCESS
+ if (ut->ut_type != USER_PROCESS) {
+ continue;
+ }
+#endif
+ if (ut->UT_USER[0] == '\0') {
+ continue;
+ }
+ if (!pl->flag_numsyslogins) {
+ char user[sizeof(ut->UT_USER) + 1];
+ user[0] = '\0';
+ strncat(user, ut->UT_USER, sizeof(ut->UT_USER));
+
+ if (((pl->login_limit_def == LIMITS_DEF_USER)
+ || (pl->login_limit_def == LIMITS_DEF_GROUP)
+ || (pl->login_limit_def == LIMITS_DEF_DEFAULT))
+ && strcmp(name, user) != 0) {
+ continue;
+ }
+ if ((pl->login_limit_def == LIMITS_DEF_ALLGROUP)
+ && !pam_modutil_user_in_group_nam_nam(pamh, user, pl->login_group)) {
+ continue;
+ }
+ if (kill(ut->ut_pid, 0) == -1 && errno == ESRCH) {
+ /* process does not exist anymore */
+ pam_syslog(pamh, LOG_INFO,
+ "Stale utmp entry (pid %d) for '%s' ignored",
+ ut->ut_pid, user);
+ continue;
+ }
+ }
+ if (++count > limit) {
+ break;
+ }
+ }
+ endutent();
+ if (count > limit) {
+ if (name) {
+ pam_syslog(pamh, LOG_NOTICE,
+ "Too many logins (max %d) for %s", limit, name);
+ } else {
+ pam_syslog(pamh, LOG_NOTICE, "Too many system logins (max %d)", limit);
+ }
+ return LOGIN_ERR;
+ }
+ return 0;
+}
+
+static const char *lnames[RLIM_NLIMITS] = {
+ [RLIMIT_CPU] = "Max cpu time",
+ [RLIMIT_FSIZE] = "Max file size",
+ [RLIMIT_DATA] = "Max data size",
+ [RLIMIT_STACK] = "Max stack size",
+ [RLIMIT_CORE] = "Max core file size",
+ [RLIMIT_RSS] = "Max resident set",
+ [RLIMIT_NPROC] = "Max processes",
+ [RLIMIT_NOFILE] = "Max open files",
+ [RLIMIT_MEMLOCK] = "Max locked memory",
+#ifdef RLIMIT_AS
+ [RLIMIT_AS] = "Max address space",
+#endif
+#ifdef RLIMIT_LOCKS
+ [RLIMIT_LOCKS] = "Max file locks",
+#endif
+#ifdef RLIMIT_SIGPENDING
+ [RLIMIT_SIGPENDING] = "Max pending signals",
+#endif
+#ifdef RLIMIT_MSGQUEUE
+ [RLIMIT_MSGQUEUE] = "Max msgqueue size",
+#endif
+#ifdef RLIMIT_NICE
+ [RLIMIT_NICE] = "Max nice priority",
+#endif
+#ifdef RLIMIT_RTPRIO
+ [RLIMIT_RTPRIO] = "Max realtime priority",
+#endif
+#ifdef RLIMIT_RTTIME
+ [RLIMIT_RTTIME] = "Max realtime timeout",
+#endif
+};
+
+static int str2rlimit(char *name) {
+ int i;
+ if (!name || *name == '\0')
+ return -1;
+ for(i = 0; i < RLIM_NLIMITS; i++) {
+ if (strcmp(name, lnames[i]) == 0) return i;
+ }
+ return -1;
+}
+
+static rlim_t str2rlim_t(char *value) {
+ unsigned long long rlimit = 0;
+
+ if (!value) return (rlim_t)rlimit;
+ if (strcmp(value, "unlimited") == 0) {
+ return RLIM_INFINITY;
+ }
+ rlimit = strtoull(value, NULL, 10);
+ return (rlim_t)rlimit;
+}
+
+#define LIMITS_SKIP_WHITESPACE { \
+ /* step backwards over spaces */ \
+ pos--; \
+ while (pos && line[pos] == ' ') pos--; \
+ if (!pos) continue; \
+ line[pos+1] = '\0'; \
+}
+#define LIMITS_MARK_ITEM(item) { \
+ /* step backwards over non-spaces */ \
+ pos--; \
+ while (pos && line[pos] != ' ') pos--; \
+ if (!pos) continue; \
+ item = line + pos + 1; \
+}
+
+static void parse_kernel_limits(pam_handle_t *pamh, struct pam_limit_s *pl, int ctrl)
+{
+ int i, maxlen = 0;
+ FILE *limitsfile;
+ const char *proclimits = "/proc/1/limits";
+ char line[256];
+ char *hard, *soft, *name;
+
+ if (!(limitsfile = fopen(proclimits, "r"))) {
+ pam_syslog(pamh, LOG_WARNING, "Could not read %s (%s), using PAM defaults", proclimits, strerror(errno));
+ return;
+ }
+
+ while (fgets(line, 256, limitsfile)) {
+ int pos = strlen(line);
+ if (pos < 2) continue;
+
+ /* drop trailing newline */
+ if (line[pos-1] == '\n') {
+ pos--;
+ line[pos] = '\0';
+ }
+
+ /* determine formatting boundary of limits report */
+ if (!maxlen && pam_str_skip_prefix(line, "Limit") != NULL) {
+ maxlen = pos;
+ continue;
+ }
+
+ if (pos == maxlen) {
+ /* step backwards over "Units" name */
+ LIMITS_SKIP_WHITESPACE;
+ LIMITS_MARK_ITEM(hard); /* not a typo, units unused */
+ }
+
+ /* step backwards over "Hard Limit" value */
+ LIMITS_SKIP_WHITESPACE;
+ LIMITS_MARK_ITEM(hard);
+
+ /* step backwards over "Soft Limit" value */
+ LIMITS_SKIP_WHITESPACE;
+ LIMITS_MARK_ITEM(soft);
+
+ /* step backwards over name of limit */
+ LIMITS_SKIP_WHITESPACE;
+ name = line;
+
+ i = str2rlimit(name);
+ if (i < 0 || i >= RLIM_NLIMITS) {
+ if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh, LOG_DEBUG, "Unknown kernel rlimit '%s' ignored", name);
+ continue;
+ }
+ pl->limits[i].limit.rlim_cur = str2rlim_t(soft);
+ pl->limits[i].limit.rlim_max = str2rlim_t(hard);
+ pl->limits[i].src_soft = LIMITS_DEF_KERNEL;
+ pl->limits[i].src_hard = LIMITS_DEF_KERNEL;
+ }
+ fclose(limitsfile);
+}
+
+static int init_limits(pam_handle_t *pamh, struct pam_limit_s *pl, int ctrl)
+{
+ int i;
+ int retval = PAM_SUCCESS;
+
+ D(("called."));
+
+ for(i = 0; i < RLIM_NLIMITS; i++) {
+ int r = getrlimit(i, &pl->limits[i].limit);
+ if (r == -1) {
+ pl->limits[i].supported = 0;
+ if (errno != EINVAL) {
+ retval = !PAM_SUCCESS;
+ }
+ } else {
+ pl->limits[i].supported = 1;
+ pl->limits[i].src_soft = LIMITS_DEF_NONE;
+ pl->limits[i].src_hard = LIMITS_DEF_NONE;
+ }
+ }
+
+#ifdef __linux__
+ if (ctrl & PAM_SET_ALL) {
+ parse_kernel_limits(pamh, pl, ctrl);
+
+ for(i = 0; i < RLIM_NLIMITS; i++) {
+ if (pl->limits[i].supported &&
+ (pl->limits[i].src_soft == LIMITS_DEF_NONE ||
+ pl->limits[i].src_hard == LIMITS_DEF_NONE)) {
+ pam_syslog(pamh, LOG_WARNING, "Did not find kernel RLIMIT for %s, using PAM default", rlimit2str(i));
+ }
+ }
+ }
+#endif
+
+ errno = 0;
+ pl->priority = getpriority (PRIO_PROCESS, 0);
+ if (pl->priority == -1 && errno != 0)
+ retval = !PAM_SUCCESS;
+ pl->login_limit = -2;
+ pl->login_limit_def = LIMITS_DEF_NONE;
+
+ return retval;
+}
+
+/*
+ * Read the contents of <pathname> and return it in *valuep
+ * return 1 if conversion succeeds, result is in *valuep
+ * return 0 if conversion fails, *valuep is untouched.
+ */
+static int
+value_from_file(const char *pathname, rlim_t *valuep)
+{
+ char buf[128];
+ FILE *fp;
+ int retval;
+
+ retval = 0;
+
+ if ((fp = fopen(pathname, "r")) != NULL) {
+ if (fgets(buf, sizeof(buf), fp) != NULL) {
+ char *endptr;
+ unsigned long long value;
+
+ errno = 0;
+ value = strtoull(buf, &endptr, 10);
+ if (endptr != buf &&
+ (value != ULLONG_MAX || errno == 0) &&
+ (unsigned long long) (rlim_t) value == value) {
+ *valuep = (rlim_t) value;
+ retval = 1;
+ }
+ }
+
+ fclose(fp);
+ }
+
+ return retval;
+}
+
+static void
+process_limit (const pam_handle_t *pamh, int source, const char *lim_type,
+ const char *lim_item, const char *lim_value,
+ int ctrl, struct pam_limit_s *pl)
+{
+ int limit_item;
+ int limit_type = 0;
+ int int_value = 0;
+ rlim_t rlimit_value = 0;
+ char *endptr;
+ const char *value_orig = lim_value;
+
+ if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh, LOG_DEBUG, "%s: processing %s %s %s for %s",
+ __FUNCTION__, lim_type, lim_item, lim_value,
+ limits_def_names[source]);
+
+ if (strcmp(lim_item, "cpu") == 0)
+ limit_item = RLIMIT_CPU;
+ else if (strcmp(lim_item, "fsize") == 0)
+ limit_item = RLIMIT_FSIZE;
+ else if (strcmp(lim_item, "data") == 0)
+ limit_item = RLIMIT_DATA;
+ else if (strcmp(lim_item, "stack") == 0)
+ limit_item = RLIMIT_STACK;
+ else if (strcmp(lim_item, "core") == 0)
+ limit_item = RLIMIT_CORE;
+ else if (strcmp(lim_item, "rss") == 0)
+ limit_item = RLIMIT_RSS;
+ else if (strcmp(lim_item, "nproc") == 0)
+ limit_item = RLIMIT_NPROC;
+ else if (strcmp(lim_item, "nofile") == 0)
+ limit_item = RLIMIT_NOFILE;
+ else if (strcmp(lim_item, "memlock") == 0)
+ limit_item = RLIMIT_MEMLOCK;
+#ifdef RLIMIT_AS
+ else if (strcmp(lim_item, "as") == 0)
+ limit_item = RLIMIT_AS;
+#endif /*RLIMIT_AS*/
+#ifdef RLIMIT_LOCKS
+ else if (strcmp(lim_item, "locks") == 0)
+ limit_item = RLIMIT_LOCKS;
+#endif
+#ifdef RLIMIT_SIGPENDING
+ else if (strcmp(lim_item, "sigpending") == 0)
+ limit_item = RLIMIT_SIGPENDING;
+#endif
+#ifdef RLIMIT_MSGQUEUE
+ else if (strcmp(lim_item, "msgqueue") == 0)
+ limit_item = RLIMIT_MSGQUEUE;
+#endif
+#ifdef RLIMIT_NICE
+ else if (strcmp(lim_item, "nice") == 0)
+ limit_item = RLIMIT_NICE;
+#endif
+#ifdef RLIMIT_RTPRIO
+ else if (strcmp(lim_item, "rtprio") == 0)
+ limit_item = RLIMIT_RTPRIO;
+#endif
+ else if (strcmp(lim_item, "maxlogins") == 0) {
+ limit_item = LIMIT_LOGIN;
+ pl->flag_numsyslogins = 0;
+ } else if (strcmp(lim_item, "maxsyslogins") == 0) {
+ limit_item = LIMIT_NUMSYSLOGINS;
+ pl->flag_numsyslogins = 1;
+ } else if (strcmp(lim_item, "priority") == 0) {
+ limit_item = LIMIT_PRI;
+ } else if (strcmp(lim_item, "nonewprivs") == 0) {
+ limit_item = LIMIT_NONEWPRIVS;
+ } else {
+ pam_syslog(pamh, LOG_DEBUG, "unknown limit item '%s'", lim_item);
+ return;
+ }
+
+ if (strcmp(lim_type,"soft")==0)
+ limit_type=LIMIT_SOFT;
+ else if (strcmp(lim_type, "hard")==0)
+ limit_type=LIMIT_HARD;
+ else if (strcmp(lim_type,"-")==0)
+ limit_type=LIMIT_SOFT | LIMIT_HARD;
+ else if (limit_item != LIMIT_LOGIN && limit_item != LIMIT_NUMSYSLOGINS
+ && limit_item != LIMIT_NONEWPRIVS) {
+ pam_syslog(pamh, LOG_DEBUG, "unknown limit type '%s'", lim_type);
+ return;
+ }
+ if (limit_item == LIMIT_NONEWPRIVS) {
+ /* just require a bool-style 0 or 1 */
+ if (strcmp(lim_value, "0") == 0) {
+ int_value = 0;
+ } else if (strcmp(lim_value, "1") == 0) {
+ int_value = 1;
+ } else {
+ pam_syslog(pamh, LOG_DEBUG,
+ "wrong limit value '%s' for limit type '%s'",
+ lim_value, lim_type);
+ }
+ } else if (limit_item != LIMIT_PRI
+#ifdef RLIMIT_NICE
+ && limit_item != RLIMIT_NICE
+#endif
+ && (strcmp(lim_value, "-1") == 0
+ || strcmp(lim_value, "-") == 0 || strcmp(lim_value, "unlimited") == 0
+ || strcmp(lim_value, "infinity") == 0)) {
+ int_value = -1;
+ rlimit_value = RLIM_INFINITY;
+ } else if (limit_item == LIMIT_PRI || limit_item == LIMIT_LOGIN ||
+#ifdef RLIMIT_NICE
+ limit_item == RLIMIT_NICE ||
+#endif
+ limit_item == LIMIT_NUMSYSLOGINS) {
+ long temp;
+ temp = strtol (lim_value, &endptr, 10);
+ temp = temp < INT_MAX ? temp : INT_MAX;
+ int_value = temp > INT_MIN ? temp : INT_MIN;
+ if (int_value == 0 && value_orig == endptr) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "wrong limit value '%s' for limit type '%s'",
+ lim_value, lim_type);
+ return;
+ }
+ } else {
+#ifdef __USE_FILE_OFFSET64
+ rlimit_value = strtoull (lim_value, &endptr, 10);
+#else
+ rlimit_value = strtoul (lim_value, &endptr, 10);
+#endif
+ if (rlimit_value == 0 && value_orig == endptr) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "wrong limit value '%s' for limit type '%s'",
+ lim_value, lim_type);
+ return;
+ }
+ }
+
+ /* one more special case when limiting logins */
+ if ((source == LIMITS_DEF_ALL || source == LIMITS_DEF_ALLGROUP)
+ && (limit_item != LIMIT_LOGIN)) {
+ if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh, LOG_DEBUG,
+ "'%%' domain valid for maxlogins type only");
+ return;
+ }
+
+ switch(limit_item) {
+ case RLIMIT_CPU:
+ if (rlimit_value != RLIM_INFINITY)
+ {
+ if (rlimit_value >= RLIM_INFINITY/60)
+ rlimit_value = RLIM_INFINITY;
+ else
+ rlimit_value *= 60;
+ }
+ break;
+ case RLIMIT_FSIZE:
+ case RLIMIT_DATA:
+ case RLIMIT_STACK:
+ case RLIMIT_CORE:
+ case RLIMIT_RSS:
+ case RLIMIT_MEMLOCK:
+#ifdef RLIMIT_AS
+ case RLIMIT_AS:
+#endif
+ if (rlimit_value != RLIM_INFINITY)
+ {
+ if (rlimit_value >= RLIM_INFINITY/1024)
+ rlimit_value = RLIM_INFINITY;
+ else
+ rlimit_value *= 1024;
+ }
+ break;
+#ifdef RLIMIT_NICE
+ case RLIMIT_NICE:
+ if (int_value > 19)
+ int_value = 19;
+ if (int_value < -20)
+ int_value = -20;
+ rlimit_value = 20 - int_value;
+ break;
+#endif
+ case RLIMIT_NOFILE:
+ /*
+ * If nofile is to be set to "unlimited", try to set it to
+ * the value in /proc/sys/fs/nr_open instead.
+ */
+ if (rlimit_value == RLIM_INFINITY) {
+ if (!value_from_file("/proc/sys/fs/nr_open", &rlimit_value))
+ pam_syslog(pamh, LOG_WARNING,
+ "Cannot set \"nofile\" to a sensible value");
+ else if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh, LOG_DEBUG, "Setting \"nofile\" limit to %llu",
+ (unsigned long long) rlimit_value);
+ }
+ break;
+ }
+
+ if ( (limit_item != LIMIT_LOGIN)
+ && (limit_item != LIMIT_NUMSYSLOGINS)
+ && (limit_item != LIMIT_PRI)
+ && (limit_item != LIMIT_NONEWPRIVS) ) {
+ if (limit_type & LIMIT_SOFT) {
+ if (pl->limits[limit_item].src_soft < source) {
+ return;
+ } else {
+ pl->limits[limit_item].limit.rlim_cur = rlimit_value;
+ pl->limits[limit_item].src_soft = source;
+ }
+ }
+ if (limit_type & LIMIT_HARD) {
+ if (pl->limits[limit_item].src_hard < source) {
+ return;
+ } else {
+ pl->limits[limit_item].limit.rlim_max = rlimit_value;
+ pl->limits[limit_item].src_hard = source;
+ }
+ }
+ } else {
+ /* recent kernels support negative priority limits (=raise priority) */
+
+ if (limit_item == LIMIT_PRI) {
+ pl->priority = int_value;
+ } else if (limit_item == LIMIT_NONEWPRIVS) {
+ pl->nonewprivs = int_value;
+ } else {
+ if (pl->login_limit_def < source) {
+ return;
+ } else {
+ pl->login_limit = int_value;
+ pl->login_limit_def = source;
+ }
+ }
+ }
+ return;
+}
+
+static int
+parse_uid_range(pam_handle_t *pamh, const char *domain,
+ uid_t *min_uid, uid_t *max_uid)
+{
+ const char *range = domain;
+ char *pmax;
+ char *endptr;
+ int rv = LIMIT_RANGE_MM;
+
+ if ((pmax=strchr(range, ':')) == NULL)
+ return LIMIT_RANGE_NONE;
+ ++pmax;
+
+ if (range[0] == '@' || range[0] == '%')
+ ++range;
+
+ if (range[0] == ':')
+ rv = LIMIT_RANGE_ONE;
+ else {
+ errno = 0;
+ *min_uid = strtoul (range, &endptr, 10);
+ if (errno != 0 || (range == endptr) || *endptr != ':') {
+ pam_syslog(pamh, LOG_DEBUG,
+ "wrong min_uid/gid value in '%s'", domain);
+ return LIMIT_RANGE_ERR;
+ }
+ }
+
+ if (*pmax == '\0') {
+ if (rv == LIMIT_RANGE_ONE)
+ return LIMIT_RANGE_ERR;
+ else
+ return LIMIT_RANGE_MIN;
+ }
+
+ errno = 0;
+ *max_uid = strtoul (pmax, &endptr, 10);
+ if (errno != 0 || (pmax == endptr) || *endptr != '\0') {
+ pam_syslog(pamh, LOG_DEBUG,
+ "wrong max_uid/gid value in '%s'", domain);
+ return LIMIT_RANGE_ERR;
+ }
+
+ if (rv == LIMIT_RANGE_ONE)
+ *min_uid = *max_uid;
+ return rv;
+}
+
+static int
+parse_config_file(pam_handle_t *pamh, const char *uname, uid_t uid, gid_t gid,
+ int ctrl, struct pam_limit_s *pl)
+{
+ FILE *fil;
+ char buf[LINE_LENGTH];
+
+ /* check for the LIMITS_FILE */
+ if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh, LOG_DEBUG, "reading settings from '%s'", CONF_FILE);
+ fil = fopen(CONF_FILE, "r");
+ if (fil == NULL) {
+ pam_syslog (pamh, LOG_WARNING,
+ "cannot read settings from %s: %m", CONF_FILE);
+ return PAM_SERVICE_ERR;
+ }
+
+ /* start the show */
+ while (fgets(buf, LINE_LENGTH, fil) != NULL) {
+ char domain[LINE_LENGTH];
+ char ltype[LINE_LENGTH];
+ char item[LINE_LENGTH];
+ char value[LINE_LENGTH];
+ int i;
+ int rngtype;
+ size_t j;
+ char *tptr,*line;
+ uid_t min_uid = (uid_t)-1, max_uid = (uid_t)-1;
+
+ line = buf;
+ /* skip the leading white space */
+ while (*line && isspace(*line))
+ line++;
+
+ /* Rip off the comments */
+ tptr = strchr(line,'#');
+ if (tptr)
+ *tptr = '\0';
+ /* Rip off the newline char */
+ tptr = strchr(line,'\n');
+ if (tptr)
+ *tptr = '\0';
+ /* Anything left ? */
+ if (!strlen(line))
+ continue;
+
+ domain[0] = ltype[0] = item[0] = value[0] = '\0';
+
+ i = sscanf(line,"%s%s%s%s", domain, ltype, item, value);
+ D(("scanned line[%d]: domain[%s], ltype[%s], item[%s], value[%s]",
+ i, domain, ltype, item, value));
+
+ for(j=0; j < strlen(ltype); j++)
+ ltype[j]=tolower(ltype[j]);
+
+ if ((rngtype=parse_uid_range(pamh, domain, &min_uid, &max_uid)) < 0) {
+ pam_syslog(pamh, LOG_WARNING, "invalid uid range '%s' - skipped", domain);
+ continue;
+ }
+
+ if (i == 4) { /* a complete line */
+ for(j=0; j < strlen(item); j++)
+ item[j]=tolower(item[j]);
+ for(j=0; j < strlen(value); j++)
+ value[j]=tolower(value[j]);
+
+ if (strcmp(uname, domain) == 0) /* this user have a limit */
+ process_limit(pamh, LIMITS_DEF_USER, ltype, item, value, ctrl, pl);
+ else if (domain[0]=='@') {
+ if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "checking if %s is in group %s",
+ uname, domain + 1);
+ }
+ switch(rngtype) {
+ case LIMIT_RANGE_NONE:
+ if (pam_modutil_user_in_group_nam_nam(pamh, uname, domain+1))
+ process_limit(pamh, LIMITS_DEF_GROUP, ltype, item, value, ctrl,
+ pl);
+ break;
+ case LIMIT_RANGE_ONE:
+ if (pam_modutil_user_in_group_nam_gid(pamh, uname, (gid_t)max_uid))
+ process_limit(pamh, LIMITS_DEF_GROUP, ltype, item, value, ctrl,
+ pl);
+ break;
+ case LIMIT_RANGE_MM:
+ if (gid > (gid_t)max_uid)
+ break;
+ /* fallthrough */
+ case LIMIT_RANGE_MIN:
+ if (gid >= (gid_t)min_uid)
+ process_limit(pamh, LIMITS_DEF_GROUP, ltype, item, value, ctrl,
+ pl);
+ }
+ } else if (domain[0]=='%') {
+ if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "checking if %s is in group %s",
+ uname, domain + 1);
+ }
+ switch(rngtype) {
+ case LIMIT_RANGE_NONE:
+ if (strcmp(domain,"%") == 0)
+ process_limit(pamh, LIMITS_DEF_ALL, ltype, item, value, ctrl,
+ pl);
+ else if (pam_modutil_user_in_group_nam_nam(pamh, uname, domain+1)) {
+ strcpy(pl->login_group, domain+1);
+ process_limit(pamh, LIMITS_DEF_ALLGROUP, ltype, item, value, ctrl,
+ pl);
+ }
+ break;
+ case LIMIT_RANGE_ONE:
+ if (pam_modutil_user_in_group_nam_gid(pamh, uname, (gid_t)max_uid)) {
+ struct group *grp;
+ grp = pam_modutil_getgrgid(pamh, (gid_t)max_uid);
+ strncpy(pl->login_group, grp->gr_name, sizeof(pl->login_group));
+ pl->login_group[sizeof(pl->login_group)-1] = '\0';
+ process_limit(pamh, LIMITS_DEF_ALLGROUP, ltype, item, value, ctrl,
+ pl);
+ }
+ break;
+ case LIMIT_RANGE_MIN:
+ case LIMIT_RANGE_MM:
+ pam_syslog(pamh, LOG_WARNING, "range unsupported for %%group matching - ignored");
+ }
+ } else {
+ switch(rngtype) {
+ case LIMIT_RANGE_NONE:
+ if (strcmp(domain, "*") == 0)
+ process_limit(pamh, LIMITS_DEF_DEFAULT, ltype, item, value, ctrl,
+ pl);
+ break;
+ case LIMIT_RANGE_ONE:
+ if (uid != max_uid)
+ break;
+ /* fallthrough */
+ case LIMIT_RANGE_MM:
+ if (uid > max_uid)
+ break;
+ /* fallthrough */
+ case LIMIT_RANGE_MIN:
+ if (uid >= min_uid)
+ process_limit(pamh, LIMITS_DEF_USER, ltype, item, value, ctrl, pl);
+ }
+ }
+ } else if (i == 2 && ltype[0] == '-') { /* Probably a no-limit line */
+ if (strcmp(uname, domain) == 0) {
+ if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_DEBUG, "no limits for '%s'", uname);
+ }
+ } else if (domain[0] == '@') {
+ switch(rngtype) {
+ case LIMIT_RANGE_NONE:
+ if (!pam_modutil_user_in_group_nam_nam(pamh, uname, domain+1))
+ continue; /* next line */
+ break;
+ case LIMIT_RANGE_ONE:
+ if (!pam_modutil_user_in_group_nam_gid(pamh, uname, (gid_t)max_uid))
+ continue; /* next line */
+ break;
+ case LIMIT_RANGE_MM:
+ if (gid > (gid_t)max_uid)
+ continue; /* next line */
+ /* fallthrough */
+ case LIMIT_RANGE_MIN:
+ if (gid < (gid_t)min_uid)
+ continue; /* next line */
+ }
+ if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "no limits for '%s' in group '%s'",
+ uname, domain+1);
+ }
+ } else {
+ switch(rngtype) {
+ case LIMIT_RANGE_NONE:
+ continue; /* next line */
+ case LIMIT_RANGE_ONE:
+ if (uid != max_uid)
+ continue; /* next line */
+ break;
+ case LIMIT_RANGE_MM:
+ if (uid > max_uid)
+ continue; /* next line */
+ /* fallthrough */
+ case LIMIT_RANGE_MIN:
+ if (uid >= min_uid)
+ break;
+ continue; /* next line */
+ }
+ if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_DEBUG, "no limits for '%s'", uname);
+ }
+ }
+ fclose(fil);
+ return PAM_IGNORE;
+ } else {
+ pam_syslog(pamh, LOG_WARNING, "invalid line '%s' - skipped", line);
+ }
+ }
+ fclose(fil);
+ return PAM_SUCCESS;
+}
+
+static int setup_limits(pam_handle_t *pamh,
+ const char *uname, uid_t uid, int ctrl,
+ struct pam_limit_s *pl)
+{
+ int i;
+ int status;
+ int retval = LIMITED_OK;
+
+ for (i=0, status=LIMITED_OK; i<RLIM_NLIMITS; i++) {
+ int res;
+
+ if (!pl->limits[i].supported) {
+ /* skip it if its not known to the system */
+ continue;
+ }
+ if (pl->limits[i].src_soft == LIMITS_DEF_NONE &&
+ pl->limits[i].src_hard == LIMITS_DEF_NONE) {
+ /* skip it if its not initialized */
+ continue;
+ }
+ if (pl->limits[i].limit.rlim_cur > pl->limits[i].limit.rlim_max)
+ pl->limits[i].limit.rlim_cur = pl->limits[i].limit.rlim_max;
+ res = setrlimit(i, &pl->limits[i].limit);
+ if (res != 0)
+ pam_syslog(pamh, LOG_ERR, "Could not set limit for '%s': %m",
+ rlimit2str(i));
+ status |= res;
+ }
+
+ if (status) {
+ retval = LIMIT_ERR;
+ }
+
+ status = setpriority(PRIO_PROCESS, 0, pl->priority);
+ if (status != 0) {
+ pam_syslog(pamh, LOG_ERR, "Could not set limit for PRIO_PROCESS: %m");
+ retval = LIMIT_ERR;
+ }
+
+ if (uid == 0) {
+ D(("skip login limit check for uid=0"));
+ } else if (pl->login_limit > 0) {
+ if (check_logins(pamh, uname, pl->login_limit, ctrl, pl) == LOGIN_ERR) {
+#ifdef HAVE_LIBAUDIT
+ if (!(ctrl & PAM_NO_AUDIT)) {
+ pam_modutil_audit_write(pamh, AUDIT_ANOM_LOGIN_SESSIONS,
+ "pam_limits", PAM_PERM_DENIED);
+ /* ignore return value as we fail anyway */
+ }
+#endif
+ retval |= LOGIN_ERR;
+ }
+ } else if (pl->login_limit == 0) {
+ retval |= LOGIN_ERR;
+ }
+
+ if (pl->nonewprivs) {
+ if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
+ pam_syslog(pamh, LOG_ERR, "Could not set prctl(PR_SET_NO_NEW_PRIVS): %m");
+ retval |= LIMIT_ERR;
+ }
+ }
+
+ return retval;
+}
+
+/* now the session stuff */
+int
+pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ int retval;
+ int i;
+ int glob_rc;
+ char *user_name;
+ struct passwd *pwd;
+ int ctrl;
+ struct pam_limit_s plstruct;
+ struct pam_limit_s *pl = &plstruct;
+ glob_t globbuf;
+ const char *oldlocale;
+
+ D(("called."));
+
+ memset(pl, 0, sizeof(*pl));
+ memset(&globbuf, 0, sizeof(globbuf));
+
+ ctrl = _pam_parse(pamh, argc, argv, pl);
+ retval = pam_get_item( pamh, PAM_USER, (void*) &user_name );
+ if ( user_name == NULL || retval != PAM_SUCCESS ) {
+ pam_syslog(pamh, LOG_ERR, "open_session - error recovering username");
+ return PAM_SESSION_ERR;
+ }
+
+ pwd = pam_modutil_getpwnam(pamh, user_name);
+ if (!pwd) {
+ if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh, LOG_WARNING,
+ "open_session username '%s' does not exist", user_name);
+ return PAM_USER_UNKNOWN;
+ }
+
+ retval = init_limits(pamh, pl, ctrl);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR, "cannot initialize");
+ return PAM_ABORT;
+ }
+
+ retval = parse_config_file(pamh, pwd->pw_name, pwd->pw_uid, pwd->pw_gid, ctrl, pl);
+ if (retval == PAM_IGNORE) {
+ D(("the configuration file ('%s') has an applicable '<domain> -' entry", CONF_FILE));
+ return PAM_SUCCESS;
+ }
+ if (retval != PAM_SUCCESS || pl->conf_file != NULL)
+ /* skip reading limits.d if config file explicitly specified */
+ goto out;
+
+ /* Read subsequent *.conf files, if they exist. */
+
+ /* set the LC_COLLATE so the sorting order doesn't depend
+ on system locale */
+
+ oldlocale = setlocale(LC_COLLATE, "C");
+ glob_rc = glob(LIMITS_CONF_GLOB, GLOB_ERR, NULL, &globbuf);
+
+ if (oldlocale != NULL)
+ setlocale (LC_COLLATE, oldlocale);
+
+ if (!glob_rc) {
+ /* Parse the *.conf files. */
+ for (i = 0; globbuf.gl_pathv[i] != NULL; i++) {
+ pl->conf_file = globbuf.gl_pathv[i];
+ retval = parse_config_file(pamh, pwd->pw_name, pwd->pw_uid, pwd->pw_gid, ctrl, pl);
+ if (retval == PAM_IGNORE) {
+ D(("the configuration file ('%s') has an applicable '<domain> -' entry", pl->conf_file));
+ globfree(&globbuf);
+ return PAM_SUCCESS;
+ }
+ if (retval != PAM_SUCCESS)
+ goto out;
+ }
+ }
+
+out:
+ globfree(&globbuf);
+ if (retval != PAM_SUCCESS)
+ {
+ pam_syslog(pamh, LOG_ERR, "error parsing the configuration file: '%s' ",CONF_FILE);
+ return retval;
+ }
+
+ retval = setup_limits(pamh, pwd->pw_name, pwd->pw_uid, ctrl, pl);
+ if (retval & LOGIN_ERR)
+ pam_error(pamh, _("There were too many logins for '%s'."),
+ pwd->pw_name);
+ if (retval != LIMITED_OK) {
+ return PAM_PERM_DENIED;
+ }
+
+ return PAM_SUCCESS;
+}
+
+int
+pam_sm_close_session (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ /* nothing to do */
+ return PAM_SUCCESS;
+}
+
+/*
+ * Copyright (c) Cristian Gafton, 1996-1997, <gafton@redhat.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/modules/pam_limits/tst-pam_limits b/modules/pam_limits/tst-pam_limits
new file mode 100755
index 0000000..f563beb
--- /dev/null
+++ b/modules/pam_limits/tst-pam_limits
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_limits.so
diff --git a/modules/pam_listfile/Makefile.am b/modules/pam_listfile/Makefile.am
new file mode 100644
index 0000000..8b0fc28
--- /dev/null
+++ b/modules/pam_listfile/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_listfile.8
+endif
+XMLS = README.xml pam_listfile.8.xml
+dist_check_SCRIPTS = tst-pam_listfile
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_listfile.la
+pam_listfile_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_listfile/Makefile.in b/modules/pam_listfile/Makefile.in
new file mode 100644
index 0000000..86a9e91
--- /dev/null
+++ b/modules/pam_listfile/Makefile.in
@@ -0,0 +1,1150 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_listfile
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_listfile_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_listfile_la_SOURCES = pam_listfile.c
+pam_listfile_la_OBJECTS = pam_listfile.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_listfile.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_listfile.c
+DIST_SOURCES = pam_listfile.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_listfile.8
+XMLS = README.xml pam_listfile.8.xml
+dist_check_SCRIPTS = tst-pam_listfile
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_listfile.la
+pam_listfile_la_LIBADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_listfile/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_listfile/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_listfile.la: $(pam_listfile_la_OBJECTS) $(pam_listfile_la_DEPENDENCIES) $(EXTRA_pam_listfile_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_listfile_la_OBJECTS) $(pam_listfile_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_listfile.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_listfile.log: tst-pam_listfile
+ @p='tst-pam_listfile'; \
+ b='tst-pam_listfile'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_listfile.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_listfile.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_listfile/README b/modules/pam_listfile/README
new file mode 100644
index 0000000..5f926bd
--- /dev/null
+++ b/modules/pam_listfile/README
@@ -0,0 +1,101 @@
+pam_listfile — deny or allow services based on an arbitrary file
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+pam_listfile is a PAM module which provides a way to deny or allow services
+based on an arbitrary file.
+
+The module gets the item of the type specified -- user specifies the username,
+PAM_USER; tty specifies the name of the terminal over which the request has
+been made, PAM_TTY; rhost specifies the name of the remote host (if any) from
+which the request was made, PAM_RHOST; and ruser specifies the name of the
+remote user (if available) who made the request, PAM_RUSER -- and looks for an
+instance of that item in the file=filename. filename contains one line per item
+listed. If the item is found, then if sense=allow, PAM_SUCCESS is returned,
+causing the authorization request to succeed; else if sense=deny, PAM_AUTH_ERR
+is returned, causing the authorization request to fail.
+
+If an error is encountered (for instance, if filename does not exist, or a
+poorly-constructed argument is encountered), then if onerr=succeed, PAM_SUCCESS
+is returned, otherwise if onerr=fail, PAM_AUTH_ERR or PAM_SERVICE_ERR (as
+appropriate) will be returned.
+
+An additional argument, apply=, can be used to restrict the application of the
+above to a specific user (apply=username) or a given group (apply=@groupname).
+This added restriction is only meaningful when used with the tty, rhost and
+shell items.
+
+Besides this last one, all arguments should be specified; do not count on any
+default behavior.
+
+No credentials are awarded by this module.
+
+OPTIONS
+
+item=[tty|user|rhost|ruser|group|shell]
+
+ What is listed in the file and should be checked for.
+
+sense=[allow|deny]
+
+ Action to take if found in file, if the item is NOT found in the file, then
+ the opposite action is requested.
+
+file=/path/filename
+
+ File containing one item per line. The file needs to be a plain file and
+ not world writable.
+
+onerr=[succeed|fail]
+
+ What to do if something weird happens like being unable to open the file.
+
+apply=[user|@group]
+
+ Restrict the user class for which the restriction apply. Note that with
+ item=[user|ruser|group] this does not make sense, but for item=[tty|rhost|
+ shell] it have a meaning.
+
+quiet
+
+ Do not treat service refusals or missing list files as errors that need to
+ be logged.
+
+EXAMPLES
+
+Classic 'ftpusers' authentication can be implemented with this entry in /etc/
+pam.d/ftpd:
+
+#
+# deny ftp-access to users listed in the /etc/ftpusers file
+#
+auth required pam_listfile.so \
+ onerr=succeed item=user sense=deny file=/etc/ftpusers
+
+
+Note, users listed in /etc/ftpusers file are (counterintuitively) not allowed
+access to the ftp service.
+
+To allow login access only for certain users, you can use a /etc/pam.d/login
+entry like this:
+
+#
+# permit login to users listed in /etc/loginusers
+#
+auth required pam_listfile.so \
+ onerr=fail item=user sense=allow file=/etc/loginusers
+
+
+For this example to work, all users who are allowed to use the login service
+should be listed in the file /etc/loginusers. Unless you are explicitly trying
+to lock out root, make sure that when you do this, you leave a way for root to
+log in, either by listing root in /etc/loginusers, or by listing a user who is
+able to su to the root account.
+
+AUTHOR
+
+pam_listfile was written by Michael K. Johnson <johnsonm@redhat.com> and Elliot
+Lee <sopwith@cuc.edu>.
+
diff --git a/modules/pam_listfile/README.xml b/modules/pam_listfile/README.xml
new file mode 100644
index 0000000..d851aef
--- /dev/null
+++ b/modules/pam_listfile/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_listfile.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_listfile.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_listfile-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_listfile.8.xml" xpointer='xpointer(//refsect1[@id = "pam_listfile-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_listfile.8.xml" xpointer='xpointer(//refsect1[@id = "pam_listfile-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_listfile.8.xml" xpointer='xpointer(//refsect1[@id = "pam_listfile-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_listfile.8.xml" xpointer='xpointer(//refsect1[@id = "pam_listfile-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_listfile/pam_listfile.8 b/modules/pam_listfile/pam_listfile.8
new file mode 100644
index 0000000..35cc2e7
--- /dev/null
+++ b/modules/pam_listfile/pam_listfile.8
@@ -0,0 +1,211 @@
+'\" t
+.\" Title: pam_listfile
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_LISTFILE" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_listfile \- deny or allow services based on an arbitrary file
+.SH "SYNOPSIS"
+.HP \w'\fBpam_listfile\&.so\fR\ 'u
+\fBpam_listfile\&.so\fR item=[tty|user|rhost|ruser|group|shell] sense=[allow|deny] file=\fI/path/filename\fR onerr=[succeed|fail] [apply=[\fIuser\fR|\fI@group\fR]] [quiet]
+.SH "DESCRIPTION"
+.PP
+pam_listfile is a PAM module which provides a way to deny or allow services based on an arbitrary file\&.
+.PP
+The module gets the
+\fBitem\fR
+of the type specified \-\-
+\fIuser\fR
+specifies the username,
+\fIPAM_USER\fR; tty specifies the name of the terminal over which the request has been made,
+\fIPAM_TTY\fR; rhost specifies the name of the remote host (if any) from which the request was made,
+\fIPAM_RHOST\fR; and ruser specifies the name of the remote user (if available) who made the request,
+\fIPAM_RUSER\fR
+\-\- and looks for an instance of that item in the
+\fBfile=\fR\fB\fIfilename\fR\fR\&.
+filename
+contains one line per item listed\&. If the item is found, then if
+\fBsense=\fR\fB\fIallow\fR\fR,
+\fIPAM_SUCCESS\fR
+is returned, causing the authorization request to succeed; else if
+\fBsense=\fR\fB\fIdeny\fR\fR,
+\fIPAM_AUTH_ERR\fR
+is returned, causing the authorization request to fail\&.
+.PP
+If an error is encountered (for instance, if
+filename
+does not exist, or a poorly\-constructed argument is encountered), then if
+\fIonerr=succeed\fR,
+\fIPAM_SUCCESS\fR
+is returned, otherwise if
+\fIonerr=fail\fR,
+\fIPAM_AUTH_ERR\fR
+or
+\fIPAM_SERVICE_ERR\fR
+(as appropriate) will be returned\&.
+.PP
+An additional argument,
+\fBapply=\fR, can be used to restrict the application of the above to a specific user (\fBapply=\fR\fB\fIusername\fR\fR) or a given group (\fBapply=\fR\fB\fI@groupname\fR\fR)\&. This added restriction is only meaningful when used with the
+\fItty\fR,
+\fIrhost\fR
+and
+\fIshell\fR
+items\&.
+.PP
+Besides this last one, all arguments should be specified; do not count on any default behavior\&.
+.PP
+No credentials are awarded by this module\&.
+.SH "OPTIONS"
+.PP
+.PP
+\fBitem=[tty|user|rhost|ruser|group|shell]\fR
+.RS 4
+What is listed in the file and should be checked for\&.
+.RE
+.PP
+\fBsense=[allow|deny]\fR
+.RS 4
+Action to take if found in file, if the item is NOT found in the file, then the opposite action is requested\&.
+.RE
+.PP
+\fBfile=\fR\fB\fI/path/filename\fR\fR
+.RS 4
+File containing one item per line\&. The file needs to be a plain file and not world writable\&.
+.RE
+.PP
+\fBonerr=[succeed|fail]\fR
+.RS 4
+What to do if something weird happens like being unable to open the file\&.
+.RE
+.PP
+\fBapply=[\fR\fB\fIuser\fR\fR\fB|\fR\fB\fI@group\fR\fR\fB]\fR
+.RS 4
+Restrict the user class for which the restriction apply\&. Note that with
+\fBitem=[user|ruser|group]\fR
+this does not make sense, but for
+\fBitem=[tty|rhost|shell]\fR
+it have a meaning\&.
+.RE
+.PP
+\fBquiet\fR
+.RS 4
+Do not treat service refusals or missing list files as errors that need to be logged\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+All module types (\fBauth\fR,
+\fBaccount\fR,
+\fBpassword\fR
+and
+\fBsession\fR) are provided\&.
+.SH "RETURN VALUES"
+.PP
+.PP
+PAM_AUTH_ERR
+.RS 4
+Authentication failure\&.
+.RE
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_IGNORE
+.RS 4
+The rule does not apply to the
+\fBapply\fR
+option\&.
+.RE
+.PP
+PAM_SERVICE_ERR
+.RS 4
+Error in service module\&.
+.RE
+.PP
+PAM_SUCCESS
+.RS 4
+Success\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Classic \*(Aqftpusers\*(Aq authentication can be implemented with this entry in
+/etc/pam\&.d/ftpd:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+#
+# deny ftp\-access to users listed in the /etc/ftpusers file
+#
+auth required pam_listfile\&.so \e
+ onerr=succeed item=user sense=deny file=/etc/ftpusers
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Note, users listed in
+/etc/ftpusers
+file are (counterintuitively)
+\fInot\fR
+allowed access to the ftp service\&.
+.PP
+To allow login access only for certain users, you can use a
+/etc/pam\&.d/login
+entry like this:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+#
+# permit login to users listed in /etc/loginusers
+#
+auth required pam_listfile\&.so \e
+ onerr=fail item=user sense=allow file=/etc/loginusers
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+For this example to work, all users who are allowed to use the login service should be listed in the file
+/etc/loginusers\&. Unless you are explicitly trying to lock out root, make sure that when you do this, you leave a way for root to log in, either by listing root in
+/etc/loginusers, or by listing a user who is able to
+\fIsu\fR
+to the root account\&.
+.SH "SEE ALSO"
+.PP
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_listfile was written by Michael K\&. Johnson <johnsonm@redhat\&.com> and Elliot Lee <sopwith@cuc\&.edu>\&.
diff --git a/modules/pam_listfile/pam_listfile.8.xml b/modules/pam_listfile/pam_listfile.8.xml
new file mode 100644
index 0000000..15f047c
--- /dev/null
+++ b/modules/pam_listfile/pam_listfile.8.xml
@@ -0,0 +1,297 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_listfile">
+
+ <refmeta>
+ <refentrytitle>pam_listfile</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_listfile-name">
+ <refname>pam_listfile</refname>
+ <refpurpose>deny or allow services based on an arbitrary file</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_listfile-cmdsynopsis">
+ <command>pam_listfile.so</command>
+ <arg choice="plain">
+ item=[tty|user|rhost|ruser|group|shell]
+ </arg>
+ <arg choice="plain">
+ sense=[allow|deny]
+ </arg>
+ <arg choice="plain">
+ file=<replaceable>/path/filename</replaceable>
+ </arg>
+ <arg choice="plain">
+ onerr=[succeed|fail]
+ </arg>
+ <arg choice="opt">
+ apply=[<replaceable>user</replaceable>|<replaceable>@group</replaceable>]
+ </arg>
+ <arg choice="opt">
+ quiet
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_listfile-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ pam_listfile is a PAM module which provides a way to deny or
+ allow services based on an arbitrary file.
+ </para>
+ <para>
+ The module gets the <option>item</option> of the type specified --
+ <emphasis>user</emphasis> specifies the username,
+ <emphasis>PAM_USER</emphasis>; tty specifies the name of the terminal
+ over which the request has been made, <emphasis>PAM_TTY</emphasis>;
+ rhost specifies the name of the remote host (if any) from which the
+ request was made, <emphasis>PAM_RHOST</emphasis>; and ruser specifies
+ the name of the remote user (if available) who made the request,
+ <emphasis>PAM_RUSER</emphasis> -- and looks for an instance of that
+ item in the <option>file=<replaceable>filename</replaceable></option>.
+ <filename>filename</filename> contains one line per item listed. If
+ the item is found, then if
+ <option>sense=<replaceable>allow</replaceable></option>,
+ <emphasis>PAM_SUCCESS</emphasis> is returned, causing the authorization
+ request to succeed; else if
+ <option>sense=<replaceable>deny</replaceable></option>,
+ <emphasis>PAM_AUTH_ERR</emphasis> is returned, causing the authorization
+ request to fail.
+ </para>
+ <para>
+ If an error is encountered (for instance, if
+ <filename>filename</filename> does not exist, or a poorly-constructed
+ argument is encountered), then if <emphasis>onerr=succeed</emphasis>,
+ <emphasis>PAM_SUCCESS</emphasis> is returned, otherwise if
+ <emphasis>onerr=fail</emphasis>, <emphasis>PAM_AUTH_ERR</emphasis> or
+ <emphasis>PAM_SERVICE_ERR</emphasis> (as appropriate) will be returned.
+ </para>
+ <para>
+ An additional argument, <option>apply=</option>, can be used
+ to restrict the application of the above to a specific user
+ (<option>apply=<replaceable>username</replaceable></option>)
+ or a given group
+ (<option>apply=<replaceable>@groupname</replaceable></option>).
+ This added restriction is only meaningful when used with the
+ <emphasis>tty</emphasis>, <emphasis>rhost</emphasis> and
+ <emphasis>shell</emphasis> items.
+ </para>
+ <para>
+ Besides this last one, all arguments should be specified; do not
+ count on any default behavior.
+ </para>
+ <para>
+ No credentials are awarded by this module.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_listfile-options">
+
+ <title>OPTIONS</title>
+ <para>
+ <variablelist>
+
+ <varlistentry>
+ <term>
+ <option>item=[tty|user|rhost|ruser|group|shell]</option>
+ </term>
+ <listitem>
+ <para>
+ What is listed in the file and should be checked for.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>sense=[allow|deny]</option>
+ </term>
+ <listitem>
+ <para>
+ Action to take if found in file, if the item is NOT found in
+ the file, then the opposite action is requested.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>file=<replaceable>/path/filename</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ File containing one item per line. The file needs to be a plain
+ file and not world writable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>onerr=[succeed|fail]</option>
+ </term>
+ <listitem>
+ <para>
+ What to do if something weird happens like being unable to open
+ the file.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>apply=[<replaceable>user</replaceable>|<replaceable>@group</replaceable>]</option>
+ </term>
+ <listitem>
+ <para>
+ Restrict the user class for which the restriction apply. Note that
+ with <option>item=[user|ruser|group]</option> this does not make sense,
+ but for <option>item=[tty|rhost|shell]</option> it have a meaning.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>quiet</option>
+ </term>
+ <listitem>
+ <para>
+ Do not treat service refusals or missing list files as
+ errors that need to be logged.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_listfile-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ All module types (<option>auth</option>, <option>account</option>,
+ <option>password</option> and <option>session</option>) are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_listfile-return_values'>
+ <title>RETURN VALUES</title>
+ <para>
+ <variablelist>
+
+ <varlistentry>
+ <term>PAM_AUTH_ERR</term>
+ <listitem>
+ <para>Authentication failure.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory buffer error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ The rule does not apply to the <option>apply</option> option.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ Error in service module.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Success.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_listfile-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ Classic 'ftpusers' authentication can be implemented with this entry
+ in <filename>/etc/pam.d/ftpd</filename>:
+ <programlisting>
+#
+# deny ftp-access to users listed in the /etc/ftpusers file
+#
+auth required pam_listfile.so \
+ onerr=succeed item=user sense=deny file=/etc/ftpusers
+ </programlisting>
+ Note, users listed in <filename>/etc/ftpusers</filename> file are
+ (counterintuitively) <emphasis>not</emphasis> allowed access to
+ the ftp service.
+ </para>
+ <para>
+ To allow login access only for certain users, you can use a
+ <filename>/etc/pam.d/login</filename> entry like this:
+ <programlisting>
+#
+# permit login to users listed in /etc/loginusers
+#
+auth required pam_listfile.so \
+ onerr=fail item=user sense=allow file=/etc/loginusers
+ </programlisting>
+ For this example to work, all users who are allowed to use the
+ login service should be listed in the file
+ <filename>/etc/loginusers</filename>. Unless you are explicitly
+ trying to lock out root, make sure that when you do this, you leave
+ a way for root to log in, either by listing root in
+ <filename>/etc/loginusers</filename>, or by listing a user who is
+ able to <emphasis>su</emphasis> to the root account.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_listfile-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_listfile-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_listfile was written by Michael K. Johnson &lt;johnsonm@redhat.com&gt;
+ and Elliot Lee &lt;sopwith@cuc.edu&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_listfile/pam_listfile.c b/modules/pam_listfile/pam_listfile.c
new file mode 100644
index 0000000..28fd58f
--- /dev/null
+++ b/modules/pam_listfile/pam_listfile.c
@@ -0,0 +1,397 @@
+/*
+ * pam_listfile module
+ *
+ * by Elliot Lee <sopwith@redhat.com>, Red Hat Software. July 25, 1996.
+ * log refused access error christopher mccrory <chrismcc@netus.com> 1998/7/11
+ *
+ * This code began life as the pam_rootok module.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <string.h>
+#include <pwd.h>
+#include <grp.h>
+
+#ifdef PAM_DEBUG
+#include <assert.h>
+#endif
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+#include "pam_inline.h"
+
+/* --- authentication management functions (only) --- */
+
+/* Extended Items that are not directly available via pam_get_item() */
+#define EI_GROUP (1 << 0)
+#define EI_SHELL (1 << 1)
+
+/* Constants for apply= parameter */
+#define APPLY_TYPE_NULL 0
+#define APPLY_TYPE_NONE 1
+#define APPLY_TYPE_USER 2
+#define APPLY_TYPE_GROUP 3
+
+#define LESSER(a, b) ((a) < (b) ? (a) : (b))
+
+int
+pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ int retval, i, citem=0, extitem=0, onerr=PAM_SERVICE_ERR, sense=2, quiet=0;
+ const void *void_citemp;
+ const char *citemp;
+ char *ifname=NULL;
+ char aline[256];
+ char mybuf[256],myval[256];
+ struct stat fileinfo;
+ FILE *inf;
+ const char *apply_val;
+ int apply_type;
+
+ /* Stuff for "extended" items */
+ struct passwd *userinfo;
+
+ apply_type=APPLY_TYPE_NULL;
+ apply_val="";
+
+ for(i=0; i < argc; i++) {
+ {
+ const char *junk;
+
+ /* option quiet has no value */
+ if(!strcmp(argv[i],"quiet")) {
+ quiet = 1;
+ continue;
+ }
+
+ memset(mybuf,'\0',sizeof(mybuf));
+ memset(myval,'\0',sizeof(myval));
+ junk = strchr(argv[i], '=');
+ if((junk == NULL) || (junk - argv[i]) >= (int) sizeof(mybuf)) {
+ pam_syslog(pamh,LOG_ERR, "Bad option: \"%s\"",
+ argv[i]);
+ continue;
+ }
+ strncpy(mybuf, argv[i],
+ LESSER(junk - argv[i], (int)sizeof(mybuf) - 1));
+ strncpy(myval, junk + 1, sizeof(myval) - 1);
+ }
+ if(!strcmp(mybuf,"onerr"))
+ if(!strcmp(myval,"succeed"))
+ onerr = PAM_SUCCESS;
+ else if(!strcmp(myval,"fail"))
+ onerr = PAM_SERVICE_ERR;
+ else {
+ if (ifname) free (ifname);
+ return PAM_SERVICE_ERR;
+ }
+ else if(!strcmp(mybuf,"sense"))
+ if(!strcmp(myval,"allow"))
+ sense=0;
+ else if(!strcmp(myval,"deny"))
+ sense=1;
+ else {
+ if (ifname) free (ifname);
+ return onerr;
+ }
+ else if(!strcmp(mybuf,"file")) {
+ if (ifname) free (ifname);
+ ifname = (char *)malloc(strlen(myval)+1);
+ if (!ifname)
+ return PAM_BUF_ERR;
+ strcpy(ifname,myval);
+ } else if(!strcmp(mybuf,"item"))
+ if(!strcmp(myval,"user"))
+ citem = PAM_USER;
+ else if(!strcmp(myval,"tty"))
+ citem = PAM_TTY;
+ else if(!strcmp(myval,"rhost"))
+ citem = PAM_RHOST;
+ else if(!strcmp(myval,"ruser"))
+ citem = PAM_RUSER;
+ else { /* These items are related to the user, but are not
+ directly gettable with pam_get_item */
+ citem = PAM_USER;
+ if(!strcmp(myval,"group"))
+ extitem = EI_GROUP;
+ else if(!strcmp(myval,"shell"))
+ extitem = EI_SHELL;
+ else
+ citem = 0;
+ } else if(!strcmp(mybuf,"apply")) {
+ apply_type=APPLY_TYPE_NONE;
+ if (myval[0]=='@') {
+ apply_type=APPLY_TYPE_GROUP;
+ apply_val=myval+1;
+ } else {
+ apply_type=APPLY_TYPE_USER;
+ apply_val=myval;
+ }
+ } else {
+ free(ifname);
+ pam_syslog(pamh,LOG_ERR, "Unknown option: %s",mybuf);
+ return onerr;
+ }
+ }
+
+ if(!citem) {
+ pam_syslog(pamh,LOG_ERR,
+ "Unknown item or item not specified");
+ free(ifname);
+ return onerr;
+ } else if(!ifname) {
+ pam_syslog(pamh,LOG_ERR, "List filename not specified");
+ return onerr;
+ } else if(sense == 2) {
+ pam_syslog(pamh,LOG_ERR,
+ "Unknown sense or sense not specified");
+ free(ifname);
+ return onerr;
+ } else if(
+ (apply_type==APPLY_TYPE_NONE) ||
+ ((apply_type!=APPLY_TYPE_NULL) && (*apply_val=='\0'))
+ ) {
+ pam_syslog(pamh,LOG_ERR,
+ "Invalid usage for apply= parameter");
+ free (ifname);
+ return onerr;
+ }
+
+ /* Check if it makes sense to use the apply= parameter */
+ if (apply_type != APPLY_TYPE_NULL) {
+ if((citem==PAM_USER) || (citem==PAM_RUSER)) {
+ pam_syslog(pamh,LOG_WARNING,
+ "Non-sense use for apply= parameter");
+ apply_type=APPLY_TYPE_NULL;
+ }
+ if(extitem && (extitem==EI_GROUP)) {
+ pam_syslog(pamh,LOG_WARNING,
+ "Non-sense use for apply= parameter");
+ apply_type=APPLY_TYPE_NULL;
+ }
+ }
+
+ /* Short-circuit - test if this session apply for this user */
+ {
+ const char *user_name;
+ int rval;
+
+ rval=pam_get_user(pamh,&user_name,NULL);
+ if(rval==PAM_SUCCESS && user_name[0]) {
+ /* Got it ? Valid ? */
+ if(apply_type==APPLY_TYPE_USER) {
+ if(strcmp(user_name, apply_val)) {
+ /* Does not apply to this user */
+#ifdef PAM_DEBUG
+ pam_syslog(pamh,LOG_DEBUG,
+ "don't apply: apply=%s, user=%s",
+ apply_val,user_name);
+#endif /* PAM_DEBUG */
+ free(ifname);
+ return PAM_IGNORE;
+ }
+ } else if(apply_type==APPLY_TYPE_GROUP) {
+ if(!pam_modutil_user_in_group_nam_nam(pamh,user_name,apply_val)) {
+ /* Not a member of apply= group */
+#ifdef PAM_DEBUG
+ pam_syslog(pamh,LOG_DEBUG,
+
+ "don't apply: %s not a member of group %s",
+ user_name,apply_val);
+#endif /* PAM_DEBUG */
+ free(ifname);
+ return PAM_IGNORE;
+ }
+ }
+ }
+ }
+
+ retval = pam_get_item(pamh,citem,&void_citemp);
+ citemp = void_citemp;
+ if(retval != PAM_SUCCESS) {
+ free(ifname);
+ return onerr;
+ }
+ if((citem == PAM_USER) && !citemp) {
+ retval = pam_get_user(pamh,&citemp,NULL);
+ if (retval != PAM_SUCCESS) {
+ free(ifname);
+ return PAM_SERVICE_ERR;
+ }
+ }
+ if((citem == PAM_TTY) && citemp) {
+ /* Normalize the TTY name. */
+ const char *str = pam_str_skip_prefix(citemp, "/dev/");
+ if (str != NULL)
+ citemp = str;
+ }
+
+ if(!citemp || (strlen(citemp) == 0)) {
+ free(ifname);
+ /* The item was NULL - we are sure not to match */
+ return sense?PAM_SUCCESS:PAM_AUTH_ERR;
+ }
+
+ if(extitem) {
+ switch(extitem) {
+ case EI_GROUP:
+ /* Just ignore, call pam_modutil_in_group... later */
+ break;
+ case EI_SHELL:
+ /* Assume that we have already gotten PAM_USER in
+ pam_get_item() - a valid assumption since citem
+ gets set to PAM_USER in the extitem switch */
+ userinfo = pam_modutil_getpwnam(pamh, citemp);
+ if (userinfo == NULL) {
+ pam_syslog(pamh, LOG_NOTICE, "getpwnam(%s) failed",
+ citemp);
+ free(ifname);
+ return onerr;
+ }
+ citemp = userinfo->pw_shell;
+ break;
+ default:
+ pam_syslog(pamh,LOG_ERR,
+
+ "Internal weirdness, unknown extended item %d",
+ extitem);
+ free(ifname);
+ return onerr;
+ }
+ }
+#ifdef PAM_DEBUG
+ pam_syslog(pamh,LOG_INFO,
+
+ "Got file = %s, item = %d, value = %s, sense = %d",
+ ifname, citem, citemp, sense);
+#endif
+ if(lstat(ifname,&fileinfo)) {
+ if(!quiet)
+ pam_syslog(pamh,LOG_ERR, "Couldn't open %s",ifname);
+ free(ifname);
+ return onerr;
+ }
+
+ if((fileinfo.st_mode & S_IWOTH)
+ || !S_ISREG(fileinfo.st_mode)) {
+ /* If the file is world writable or is not a
+ normal file, return error */
+ pam_syslog(pamh,LOG_ERR,
+ "%s is either world writable or not a normal file",
+ ifname);
+ free(ifname);
+ return PAM_AUTH_ERR;
+ }
+
+ inf = fopen(ifname,"r");
+ if(inf == NULL) { /* Check that we opened it successfully */
+ if (onerr == PAM_SERVICE_ERR) {
+ /* Only report if it's an error... */
+ pam_syslog(pamh,LOG_ERR, "Error opening %s", ifname);
+ }
+ free(ifname);
+ return onerr;
+ }
+ /* There should be no more errors from here on */
+ retval=PAM_AUTH_ERR;
+ /* This loop assumes that PAM_SUCCESS == 0
+ and PAM_AUTH_ERR != 0 */
+#ifdef PAM_DEBUG
+ assert(PAM_SUCCESS == 0);
+ assert(PAM_AUTH_ERR != 0);
+#endif
+ while((fgets(aline,sizeof(aline),inf) != NULL)
+ && retval) {
+ const char *a = aline;
+
+ if(strlen(aline) == 0)
+ continue;
+ if(aline[strlen(aline) - 1] == '\n')
+ aline[strlen(aline) - 1] = '\0';
+ if(strlen(aline) == 0)
+ continue;
+ if(aline[strlen(aline) - 1] == '\r')
+ aline[strlen(aline) - 1] = '\0';
+ if(citem == PAM_TTY) {
+ const char *str = pam_str_skip_prefix(a, "/dev/");
+ if (str != NULL)
+ a = str;
+ }
+ if (extitem == EI_GROUP) {
+ retval = !pam_modutil_user_in_group_nam_nam(pamh,
+ citemp, aline);
+ } else {
+ retval = strcmp(a, citemp);
+ }
+ }
+
+ fclose(inf);
+ free(ifname);
+ if ((sense && retval) || (!sense && !retval)) {
+#ifdef PAM_DEBUG
+ pam_syslog(pamh,LOG_INFO,
+ "Returning PAM_SUCCESS, retval = %d", retval);
+#endif
+ return PAM_SUCCESS;
+ }
+ else {
+ const void *service;
+ const char *user_name;
+#ifdef PAM_DEBUG
+ pam_syslog(pamh,LOG_INFO,
+ "Returning PAM_AUTH_ERR, retval = %d", retval);
+#endif
+ (void) pam_get_item(pamh, PAM_SERVICE, &service);
+ (void) pam_get_user(pamh, &user_name, NULL);
+ if (!quiet)
+ pam_syslog (pamh, LOG_NOTICE, "Refused user %s for service %s",
+ user_name, (const char *)service);
+ return PAM_AUTH_ERR;
+ }
+}
+
+int
+pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
+
+int
+pam_sm_acct_mgmt (pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+int
+pam_sm_open_session (pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+int
+pam_sm_close_session (pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+int
+pam_sm_chauthtok (pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
diff --git a/modules/pam_listfile/tst-pam_listfile b/modules/pam_listfile/tst-pam_listfile
new file mode 100755
index 0000000..f555a9f
--- /dev/null
+++ b/modules/pam_listfile/tst-pam_listfile
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_listfile.so
diff --git a/modules/pam_localuser/Makefile.am b/modules/pam_localuser/Makefile.am
new file mode 100644
index 0000000..46f87a8
--- /dev/null
+++ b/modules/pam_localuser/Makefile.am
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_localuser.8
+endif
+XMLS = README.xml pam_localuser.8.xml
+dist_check_SCRIPTS = tst-pam_localuser
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_localuser.la
+pam_localuser_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+check_PROGRAMS = tst-pam_localuser-retval
+tst_pam_localuser_retval_LDADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_localuser/Makefile.in b/modules/pam_localuser/Makefile.in
new file mode 100644
index 0000000..9f1526f
--- /dev/null
+++ b/modules/pam_localuser/Makefile.in
@@ -0,0 +1,1181 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+check_PROGRAMS = tst-pam_localuser-retval$(EXEEXT)
+subdir = modules/pam_localuser
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_localuser_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_localuser_la_SOURCES = pam_localuser.c
+pam_localuser_la_OBJECTS = pam_localuser.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+tst_pam_localuser_retval_SOURCES = tst-pam_localuser-retval.c
+tst_pam_localuser_retval_OBJECTS = tst-pam_localuser-retval.$(OBJEXT)
+tst_pam_localuser_retval_DEPENDENCIES = \
+ $(top_builddir)/libpam/libpam.la
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_localuser.Plo \
+ ./$(DEPDIR)/tst-pam_localuser-retval.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_localuser.c tst-pam_localuser-retval.c
+DIST_SOURCES = pam_localuser.c tst-pam_localuser-retval.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_localuser.8
+XMLS = README.xml pam_localuser.8.xml
+dist_check_SCRIPTS = tst-pam_localuser
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_localuser.la
+pam_localuser_la_LIBADD = $(top_builddir)/libpam/libpam.la
+tst_pam_localuser_retval_LDADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_localuser/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_localuser/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_localuser.la: $(pam_localuser_la_OBJECTS) $(pam_localuser_la_DEPENDENCIES) $(EXTRA_pam_localuser_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_localuser_la_OBJECTS) $(pam_localuser_la_LIBADD) $(LIBS)
+
+tst-pam_localuser-retval$(EXEEXT): $(tst_pam_localuser_retval_OBJECTS) $(tst_pam_localuser_retval_DEPENDENCIES) $(EXTRA_tst_pam_localuser_retval_DEPENDENCIES)
+ @rm -f tst-pam_localuser-retval$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tst_pam_localuser_retval_OBJECTS) $(tst_pam_localuser_retval_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_localuser.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-pam_localuser-retval.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_localuser.log: tst-pam_localuser
+ @p='tst-pam_localuser'; \
+ b='tst-pam_localuser'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+tst-pam_localuser-retval.log: tst-pam_localuser-retval$(EXEEXT)
+ @p='tst-pam_localuser-retval$(EXEEXT)'; \
+ b='tst-pam_localuser-retval'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) \
+ $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_localuser.Plo
+ -rm -f ./$(DEPDIR)/tst-pam_localuser-retval.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_localuser.Plo
+ -rm -f ./$(DEPDIR)/tst-pam_localuser-retval.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_localuser/README b/modules/pam_localuser/README
new file mode 100644
index 0000000..e4c932c
--- /dev/null
+++ b/modules/pam_localuser/README
@@ -0,0 +1,38 @@
+pam_localuser — require users to be listed in /etc/passwd
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+pam_localuser is a PAM module to help implementing site-wide login policies,
+where they typically include a subset of the network's users and a few accounts
+that are local to a particular workstation. Using pam_localuser and pam_wheel
+or pam_listfile is an effective way to restrict access to either local users
+and/or a subset of the network's users.
+
+This could also be implemented using pam_listfile.so and a very short awk
+script invoked by cron, but it's common enough to have been separated out.
+
+OPTIONS
+
+debug
+
+ Print debug information.
+
+file=/path/passwd
+
+ Use a file other than /etc/passwd.
+
+EXAMPLES
+
+Add the following lines to /etc/pam.d/su to allow only local users or group
+wheel to use su.
+
+account sufficient pam_localuser.so
+account required pam_wheel.so
+
+
+AUTHOR
+
+pam_localuser was written by Nalin Dahyabhai <nalin@redhat.com>.
+
diff --git a/modules/pam_localuser/README.xml b/modules/pam_localuser/README.xml
new file mode 100644
index 0000000..4ab56d9
--- /dev/null
+++ b/modules/pam_localuser/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_localuser.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_localuser.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_localuser-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_localuser.8.xml" xpointer='xpointer(//refsect1[@id = "pam_localuser-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_localuser.8.xml" xpointer='xpointer(//refsect1[@id = "pam_localuser-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_localuser.8.xml" xpointer='xpointer(//refsect1[@id = "pam_localuser-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_localuser.8.xml" xpointer='xpointer(//refsect1[@id = "pam_localuser-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_localuser/pam_localuser.8 b/modules/pam_localuser/pam_localuser.8
new file mode 100644
index 0000000..724ab54
--- /dev/null
+++ b/modules/pam_localuser/pam_localuser.8
@@ -0,0 +1,123 @@
+'\" t
+.\" Title: pam_localuser
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_LOCALUSER" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_localuser \- require users to be listed in /etc/passwd
+.SH "SYNOPSIS"
+.HP \w'\fBpam_localuser\&.so\fR\ 'u
+\fBpam_localuser\&.so\fR [debug] [file=\fI/path/passwd\fR]
+.SH "DESCRIPTION"
+.PP
+pam_localuser is a PAM module to help implementing site\-wide login policies, where they typically include a subset of the network\*(Aqs users and a few accounts that are local to a particular workstation\&. Using pam_localuser and pam_wheel or pam_listfile is an effective way to restrict access to either local users and/or a subset of the network\*(Aqs users\&.
+.PP
+This could also be implemented using pam_listfile\&.so and a very short awk script invoked by cron, but it\*(Aqs common enough to have been separated out\&.
+.SH "OPTIONS"
+.PP
+.PP
+\fBdebug\fR
+.RS 4
+Print debug information\&.
+.RE
+.PP
+\fBfile=\fR\fB\fI/path/passwd\fR\fR
+.RS 4
+Use a file other than
+/etc/passwd\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+All module types (\fBaccount\fR,
+\fBauth\fR,
+\fBpassword\fR
+and
+\fBsession\fR) are provided\&.
+.SH "RETURN VALUES"
+.PP
+.PP
+PAM_SUCCESS
+.RS 4
+The new localuser was set successfully\&.
+.RE
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_CONV_ERR
+.RS 4
+The conversation method supplied by the application failed to obtain the username\&.
+.RE
+.PP
+PAM_INCOMPLETE
+.RS 4
+The conversation method supplied by the application returned PAM_CONV_AGAIN\&.
+.RE
+.PP
+PAM_SERVICE_ERR
+.RS 4
+The user name is not valid or the passwd file is unavailable\&.
+.RE
+.PP
+PAM_PERM_DENIED
+.RS 4
+The user is not listed in the passwd file\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Add the following lines to
+/etc/pam\&.d/su
+to allow only local users or group wheel to use su\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+account sufficient pam_localuser\&.so
+account required pam_wheel\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "FILES"
+.PP
+/etc/passwd
+.RS 4
+Local user account information\&.
+.RE
+.SH "SEE ALSO"
+.PP
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_localuser was written by Nalin Dahyabhai <nalin@redhat\&.com>\&.
diff --git a/modules/pam_localuser/pam_localuser.8.xml b/modules/pam_localuser/pam_localuser.8.xml
new file mode 100644
index 0000000..b3c1886
--- /dev/null
+++ b/modules/pam_localuser/pam_localuser.8.xml
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_localuser">
+
+ <refmeta>
+ <refentrytitle>pam_localuser</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_localuser-name">
+ <refname>pam_localuser</refname>
+ <refpurpose>require users to be listed in /etc/passwd</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_localuser-cmdsynopsis">
+ <command>pam_localuser.so</command>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ file=<replaceable>/path/passwd</replaceable>
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_localuser-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ pam_localuser is a PAM module to help implementing site-wide login
+ policies, where they typically include a subset of the network's
+ users and a few accounts that are local to a particular workstation.
+ Using pam_localuser and pam_wheel or pam_listfile is an effective
+ way to restrict access to either local users and/or a subset of the
+ network's users.
+ </para>
+ <para>
+ This could also be implemented using pam_listfile.so and a very
+ short awk script invoked by cron, but it's common enough to have
+ been separated out.
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="pam_localuser-options">
+
+ <title>OPTIONS</title>
+ <para>
+ <variablelist>
+
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Print debug information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>file=<replaceable>/path/passwd</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Use a file other than <filename>/etc/passwd</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_localuser-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ All module types (<option>account</option>, <option>auth</option>,
+ <option>password</option> and <option>session</option>) are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_localuser-return_values'>
+ <title>RETURN VALUES</title>
+ <para>
+ <variablelist>
+
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ The new localuser was set successfully.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory buffer error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_CONV_ERR</term>
+ <listitem>
+ <para>
+ The conversation method supplied by the application
+ failed to obtain the username.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_INCOMPLETE</term>
+ <listitem>
+ <para>
+ The conversation method supplied by the application
+ returned PAM_CONV_AGAIN.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ The user name is not valid or the passwd file is unavailable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_PERM_DENIED</term>
+ <listitem>
+ <para>
+ The user is not listed in the passwd file.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_localuser-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ Add the following lines to <filename>/etc/pam.d/su</filename> to
+ allow only local users or group wheel to use su.
+ <programlisting>
+account sufficient pam_localuser.so
+account required pam_wheel.so
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_localuser-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/passwd</filename></term>
+ <listitem>
+ <para>Local user account information.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_localuser-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_localuser-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_localuser was written by Nalin Dahyabhai &lt;nalin@redhat.com&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_localuser/pam_localuser.c b/modules/pam_localuser/pam_localuser.c
new file mode 100644
index 0000000..a9f2233
--- /dev/null
+++ b/modules/pam_localuser/pam_localuser.c
@@ -0,0 +1,126 @@
+/*
+ * pam_localuser module
+ *
+ * Copyright 2001, 2004 Red Hat, Inc.
+ * Copyright (c) 2020 Dmitry V. Levin <ldv@altlinux.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+#include "pam_inline.h"
+
+int
+pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ int i;
+ int rc;
+ int debug = 0;
+ const char *file_name = NULL;
+ const char *user_name = NULL;
+
+ /* Process arguments. */
+ for (i = 0; i < argc; ++i) {
+ if (strcmp("debug", argv[i]) == 0) {
+ debug = 1;
+ }
+ }
+ for (i = 0; i < argc; ++i) {
+ const char *str;
+
+ if (strcmp("debug", argv[i]) == 0) {
+ /* Already processed. */
+ continue;
+ }
+ if ((str = pam_str_skip_prefix(argv[i], "file=")) != NULL) {
+ file_name = str;
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "set filename to %s", file_name);
+ }
+ } else {
+ pam_syslog(pamh, LOG_ERR, "unrecognized option: %s",
+ argv[i]);
+ }
+ }
+
+ /* Obtain the user name. */
+ if ((rc = pam_get_user(pamh, &user_name, NULL)) != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE, "cannot determine user name: %s",
+ pam_strerror(pamh, rc));
+ return rc == PAM_CONV_AGAIN ? PAM_INCOMPLETE : rc;
+ }
+
+ return pam_modutil_check_user_in_passwd(pamh, user_name, file_name);
+}
+
+int
+pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
+
+int
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+int
+pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+int
+pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+int
+pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
diff --git a/modules/pam_localuser/tst-pam_localuser b/modules/pam_localuser/tst-pam_localuser
new file mode 100755
index 0000000..2bcdf6b
--- /dev/null
+++ b/modules/pam_localuser/tst-pam_localuser
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_localuser.so
diff --git a/modules/pam_localuser/tst-pam_localuser-retval.c b/modules/pam_localuser/tst-pam_localuser-retval.c
new file mode 100644
index 0000000..5581cec
--- /dev/null
+++ b/modules/pam_localuser/tst-pam_localuser-retval.c
@@ -0,0 +1,144 @@
+/*
+ * Check pam_localuser return values.
+ *
+ * Copyright (c) 2020 Dmitry V. Levin <ldv@altlinux.org>
+ */
+
+#include "test_assert.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <security/pam_appl.h>
+
+#define MODULE_NAME "pam_localuser"
+#define TEST_NAME "tst-" MODULE_NAME "-retval"
+
+static const char service_file[] = TEST_NAME ".service";
+static const char passwd_file[] = TEST_NAME ".passwd";
+static const char missing_file[] = TEST_NAME ".missing";
+
+static const char alice_line[] = "alice:x:1001:1001:Alice:/home/alice:";
+static const char bob_line[] = "bob:x:1002:1002:Bob:/home/bob:";
+static const char craig_prefix[] = ":x:1003:1003:";
+static const char craig_suffix[] = "craig:/home/craig:";
+
+int
+main(void)
+{
+ static struct pam_conv conv;
+ pam_handle_t *pamh = NULL;
+ FILE *fp;
+ char cwd[PATH_MAX];
+ char name[BUFSIZ];
+
+ ASSERT_NE(NULL, getcwd(cwd, sizeof(cwd)));
+
+ /* default passwd */
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so\n",
+ cwd, MODULE_NAME));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, "", &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_SERVICE_ERR, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ memset(name, 'x', sizeof(name) - 1);
+ name[sizeof(name) - 1] = '\0';
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, name, &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_SERVICE_ERR, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, "root:x", &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_PERM_DENIED, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ /* missing passwd file */
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so file=%s\n",
+ cwd, MODULE_NAME, missing_file));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, "root", &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_SERVICE_ERR, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ /* custom passwd file */
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so file=%s\n",
+ cwd, MODULE_NAME, passwd_file));
+ ASSERT_EQ(0, fclose(fp));
+
+ memcpy(name + (sizeof(name) - sizeof(craig_prefix)),
+ craig_prefix, sizeof(craig_prefix));
+ ASSERT_NE(NULL, fp = fopen(passwd_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "%s\n%s\n%s%s\n",
+ alice_line, bob_line, name, craig_suffix));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, "", &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_SERVICE_ERR, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ memset(name, 'x', sizeof(name) - 1);
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, name, &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_SERVICE_ERR, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, "alice", &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, "bob", &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, "alice:x", &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_PERM_DENIED, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, "craig", &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_PERM_DENIED, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ ASSERT_EQ(0, unlink(service_file));
+ ASSERT_EQ(0, unlink(passwd_file));
+
+ return 0;
+}
diff --git a/modules/pam_loginuid/Makefile.am b/modules/pam_loginuid/Makefile.am
new file mode 100644
index 0000000..071b2ae
--- /dev/null
+++ b/modules/pam_loginuid/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2006, 2009 Thorsten Kukuk <kukuk@thkukuk.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_loginuid.8
+endif
+XMLS = README.xml pam_loginuid.8.xml
+dist_check_SCRIPTS = tst-pam_loginuid
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_loginuid.la
+pam_loginuid_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBAUDIT@
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_loginuid/Makefile.in b/modules/pam_loginuid/Makefile.in
new file mode 100644
index 0000000..bcfe714
--- /dev/null
+++ b/modules/pam_loginuid/Makefile.in
@@ -0,0 +1,1150 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2006, 2009 Thorsten Kukuk <kukuk@thkukuk.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_loginuid
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_loginuid_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_loginuid_la_SOURCES = pam_loginuid.c
+pam_loginuid_la_OBJECTS = pam_loginuid.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_loginuid.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_loginuid.c
+DIST_SOURCES = pam_loginuid.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_loginuid.8
+XMLS = README.xml pam_loginuid.8.xml
+dist_check_SCRIPTS = tst-pam_loginuid
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_loginuid.la
+pam_loginuid_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBAUDIT@
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_loginuid/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_loginuid/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_loginuid.la: $(pam_loginuid_la_OBJECTS) $(pam_loginuid_la_DEPENDENCIES) $(EXTRA_pam_loginuid_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_loginuid_la_OBJECTS) $(pam_loginuid_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_loginuid.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_loginuid.log: tst-pam_loginuid
+ @p='tst-pam_loginuid'; \
+ b='tst-pam_loginuid'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_loginuid.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_loginuid.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_loginuid/README b/modules/pam_loginuid/README
new file mode 100644
index 0000000..f07cffe
--- /dev/null
+++ b/modules/pam_loginuid/README
@@ -0,0 +1,29 @@
+pam_loginuid — Record user's login uid to the process attribute
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+The pam_loginuid module sets the loginuid process attribute for the process
+that was authenticated. This is necessary for applications to be correctly
+audited. This PAM module should only be used for entry point applications like:
+login, sshd, gdm, vsftpd, crond and atd. There are probably other entry point
+applications besides these. You should not use it for applications like sudo or
+su as that defeats the purpose by changing the loginuid to the account they
+just switched to.
+
+EXAMPLES
+
+#%PAM-1.0
+auth required pam_unix.so
+auth required pam_nologin.so
+account required pam_unix.so
+password required pam_unix.so
+session required pam_unix.so
+session required pam_loginuid.so
+
+
+AUTHOR
+
+pam_loginuid was written by Steve Grubb <sgrubb@redhat.com>
+
diff --git a/modules/pam_loginuid/README.xml b/modules/pam_loginuid/README.xml
new file mode 100644
index 0000000..3bcd38a
--- /dev/null
+++ b/modules/pam_loginuid/README.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_loginuid.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_loginuid.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_loginuid-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_loginuid.8.xml" xpointer='xpointer(//refsect1[@id = "pam_loginuid-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_loginuid.8.xml" xpointer='xpointer(//refsect1[@id = "pam_loginuid-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_loginuid.8.xml" xpointer='xpointer(//refsect1[@id = "pam_loginuid-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_loginuid/pam_loginuid.8 b/modules/pam_loginuid/pam_loginuid.8
new file mode 100644
index 0000000..3bb3fda
--- /dev/null
+++ b/modules/pam_loginuid/pam_loginuid.8
@@ -0,0 +1,93 @@
+'\" t
+.\" Title: pam_loginuid
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_LOGINUID" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_loginuid \- Record user\*(Aqs login uid to the process attribute
+.SH "SYNOPSIS"
+.HP \w'\fBpam_loginuid\&.so\fR\ 'u
+\fBpam_loginuid\&.so\fR [require_auditd]
+.SH "DESCRIPTION"
+.PP
+The pam_loginuid module sets the loginuid process attribute for the process that was authenticated\&. This is necessary for applications to be correctly audited\&. This PAM module should only be used for entry point applications like: login, sshd, gdm, vsftpd, crond and atd\&. There are probably other entry point applications besides these\&. You should not use it for applications like sudo or su as that defeats the purpose by changing the loginuid to the account they just switched to\&.
+.SH "OPTIONS"
+.PP
+\fBrequire_auditd\fR
+.RS 4
+This option, when given, will cause this module to query the audit daemon status and deny logins if it is not running\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+Only the
+\fBsession\fR
+module type is provided\&.
+.SH "RETURN VALUES"
+.PP
+.PP
+PAM_SUCCESS
+.RS 4
+The loginuid value is set and auditd is running if check requested\&.
+.RE
+.PP
+PAM_IGNORE
+.RS 4
+The /proc/self/loginuid file is not present on the system or the login process runs inside uid namespace and kernel does not support overwriting loginuid\&.
+.RE
+.PP
+PAM_SESSION_ERR
+.RS 4
+Any other error prevented setting loginuid or auditd is not running\&.
+.RE
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+#%PAM\-1\&.0
+auth required pam_unix\&.so
+auth required pam_nologin\&.so
+account required pam_unix\&.so
+password required pam_unix\&.so
+session required pam_unix\&.so
+session required pam_loginuid\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+.PP
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8),
+\fBauditctl\fR(8),
+\fBauditd\fR(8)
+.SH "AUTHOR"
+.PP
+pam_loginuid was written by Steve Grubb <sgrubb@redhat\&.com>
diff --git a/modules/pam_loginuid/pam_loginuid.8.xml b/modules/pam_loginuid/pam_loginuid.8.xml
new file mode 100644
index 0000000..9513b0e
--- /dev/null
+++ b/modules/pam_loginuid/pam_loginuid.8.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_loginuid">
+
+ <refmeta>
+ <refentrytitle>pam_loginuid</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_loginuid-name">
+ <refname>pam_loginuid</refname>
+ <refpurpose>Record user's login uid to the process attribute</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_loginuid-cmdsynopsis">
+ <command>pam_loginuid.so</command>
+ <arg choice="opt">
+ require_auditd
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_loginuid-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ The pam_loginuid module sets the loginuid process attribute for the
+ process that was authenticated. This is necessary for applications
+ to be correctly audited. This PAM module should only be used for entry
+ point applications like: login, sshd, gdm, vsftpd, crond and atd.
+ There are probably other entry point applications besides these.
+ You should not use it for applications like sudo or su as that
+ defeats the purpose by changing the loginuid to the account they just
+ switched to.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_loginuid-options">
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>require_auditd</option>
+ </term>
+ <listitem>
+ <para>
+ This option, when given, will cause this module to query
+ the audit daemon status and deny logins if it is not running.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_loginuid-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ Only the <option>session</option> module type is provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_loginuid-return_values'>
+ <title>RETURN VALUES</title>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ The loginuid value is set and auditd is running if check requested.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ The /proc/self/loginuid file is not present on the system or the
+ login process runs inside uid namespace and kernel does not support
+ overwriting loginuid.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SESSION_ERR</term>
+ <listitem>
+ <para>
+ Any other error prevented setting loginuid or auditd is not running.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_loginuid-examples'>
+ <title>EXAMPLES</title>
+ <programlisting>
+#%PAM-1.0
+auth required pam_unix.so
+auth required pam_nologin.so
+account required pam_unix.so
+password required pam_unix.so
+session required pam_unix.so
+session required pam_loginuid.so
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id='pam_loginuid-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>auditctl</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>auditd</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_loginuid-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_loginuid was written by Steve Grubb &lt;sgrubb@redhat.com&gt;
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_loginuid/pam_loginuid.c b/modules/pam_loginuid/pam_loginuid.c
new file mode 100644
index 0000000..6f5a638
--- /dev/null
+++ b/modules/pam_loginuid/pam_loginuid.c
@@ -0,0 +1,267 @@
+/*
+ * pam_loginuid module
+ *
+ * Copyright 2005 Red Hat Inc., Durham, North Carolina.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Suite 500
+ * Boston, MA 02110-1335 USA
+ *
+ * Authors:
+ * Steve Grubb <sgrubb@redhat.com>
+ *
+ * PAM module that sets the login uid introduced in kernel 2.6.11
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <stdarg.h>
+#include <syslog.h>
+#include <string.h>
+#include <pwd.h>
+#include <unistd.h>
+#include <limits.h>
+#include <errno.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_ext.h>
+#include <security/pam_modutil.h>
+
+#include <fcntl.h>
+
+#ifdef HAVE_LIBAUDIT
+#include <libaudit.h>
+#include <sys/select.h>
+#endif
+
+/*
+ * This function writes the loginuid to the /proc system. It returns
+ * PAM_SUCCESS on success,
+ * PAM_IGNORE when /proc/self/loginuid does not exist,
+ * PAM_SESSION_ERR in case of any other error.
+ */
+static int set_loginuid(pam_handle_t *pamh, uid_t uid)
+{
+ int fd, count, rc = PAM_SESSION_ERR;
+ char loginuid[24], buf[24];
+ static const char host_uid_map[] = " 0 0 4294967295\n";
+ char uid_map[sizeof(host_uid_map)];
+
+ /* loginuid in user namespaces currently isn't writable and in some
+ case, not even readable, so consider any failure as ignorable (but try
+ anyway, in case we hit a kernel which supports it). */
+ fd = open("/proc/self/uid_map", O_RDONLY);
+ if (fd >= 0) {
+ count = pam_modutil_read(fd, uid_map, sizeof(uid_map));
+ if (count <= 0 || strncmp(uid_map, host_uid_map, count) != 0)
+ rc = PAM_IGNORE;
+ close(fd);
+ }
+
+ fd = open("/proc/self/loginuid", O_NOFOLLOW|O_RDWR);
+ if (fd < 0) {
+ if (errno == ENOENT) {
+ rc = PAM_IGNORE;
+ }
+ if (rc != PAM_IGNORE) {
+ pam_syslog(pamh, LOG_ERR, "Cannot open %s: %m",
+ "/proc/self/loginuid");
+ }
+ return rc;
+ }
+
+ count = snprintf(loginuid, sizeof(loginuid), "%lu", (unsigned long)uid);
+ if (pam_modutil_read(fd, buf, sizeof(buf)) == count &&
+ memcmp(buf, loginuid, count) == 0) {
+ rc = PAM_SUCCESS;
+ goto done; /* already correct */
+ }
+ if (lseek(fd, 0, SEEK_SET) == 0 && ftruncate(fd, 0) == 0 &&
+ pam_modutil_write(fd, loginuid, count) == count) {
+ rc = PAM_SUCCESS;
+ } else {
+ if (rc != PAM_IGNORE) {
+ pam_syslog(pamh, LOG_ERR, "Error writing %s: %m",
+ "/proc/self/loginuid");
+ }
+ }
+ done:
+ close(fd);
+ return rc;
+}
+
+#ifdef HAVE_LIBAUDIT
+/*
+ * This function is called only if "require_auditd" option is passed. It is
+ * called after loginuid has been set. The purpose is to disallow logins
+ * should the audit daemon not be running or crashed. It returns PAM_SUCCESS
+ * if the audit daemon is running and PAM_SESSION_ERR otherwise.
+ */
+static int check_auditd(void)
+{
+ int fd, retval;
+
+ fd = audit_open();
+ if (fd < 0) {
+ /* This is here to let people that build their own kernel
+ and disable the audit system get in. You get these error
+ codes only when the kernel doesn't have audit
+ compiled in. */
+ if (errno == EINVAL || errno == EPROTONOSUPPORT ||
+ errno == EAFNOSUPPORT)
+ return PAM_SUCCESS;
+ return PAM_SESSION_ERR;
+ }
+ retval = audit_request_status(fd);
+ if (retval > 0) {
+ struct audit_reply rep;
+ int i;
+ int timeout = 30; /* tenths of seconds */
+ fd_set read_mask;
+
+ FD_ZERO(&read_mask);
+ FD_SET(fd, &read_mask);
+
+ for (i = 0; i < timeout; i++) {
+ struct timeval t;
+ int rc;
+
+ t.tv_sec = 0;
+ t.tv_usec = 100000;
+ do {
+ rc = select(fd+1, &read_mask, NULL, NULL, &t);
+ } while (rc < 0 && errno == EINTR);
+
+ rc = audit_get_reply(fd, &rep, GET_REPLY_NONBLOCKING,0);
+ if (rc > 0) {
+ /* If we get done or error, break out */
+ if (rep.type == NLMSG_DONE ||
+ rep.type == NLMSG_ERROR)
+ break;
+
+ /* If its not status, keep looping */
+ if (rep.type != AUDIT_GET)
+ continue;
+
+ /* Found it... */
+ close(fd);
+ if (rep.status->pid == 0)
+ return PAM_SESSION_ERR;
+ else
+ return PAM_SUCCESS;
+ }
+ }
+ }
+ close(fd);
+ if (retval == -ECONNREFUSED) {
+ /* This is here to let people that build their own kernel
+ and disable the audit system get in. ECONNREFUSED is
+ issued by the kernel when there is "no on listening". */
+ return PAM_SUCCESS;
+ } else if (retval == -EPERM && getuid() != 0) {
+ /* If we get this, then the kernel supports auditing
+ * but we don't have enough privilege to write to the
+ * socket. Therefore, we have already been authenticated
+ * and we are a common user. Just act as though auditing
+ * is not enabled. Any other error we take seriously. */
+ return PAM_SUCCESS;
+ }
+
+ return PAM_SESSION_ERR;
+}
+#endif
+
+/*
+ * Initialize audit session for user
+ */
+static int
+_pam_loginuid(pam_handle_t *pamh, int flags UNUSED,
+#ifdef HAVE_LIBAUDIT
+ int argc, const char **argv
+#else
+ int argc UNUSED, const char **argv UNUSED
+#endif
+)
+{
+ const char *user = NULL;
+ struct passwd *pwd;
+ int ret;
+#ifdef HAVE_LIBAUDIT
+ int require_auditd = 0;
+#endif
+
+ /* get user name */
+ if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE, "cannot determine user name");
+ return PAM_SESSION_ERR;
+ }
+
+ /* get user info */
+ if ((pwd = pam_modutil_getpwnam(pamh, user)) == NULL) {
+ pam_syslog(pamh, LOG_NOTICE,
+ "error: login user-name '%s' does not exist", user);
+ return PAM_SESSION_ERR;
+ }
+
+ ret = set_loginuid(pamh, pwd->pw_uid);
+ switch (ret) {
+ case PAM_SUCCESS:
+ case PAM_IGNORE:
+ break;
+ default:
+ pam_syslog(pamh, LOG_ERR, "set_loginuid failed");
+ return ret;
+ }
+
+#ifdef HAVE_LIBAUDIT
+ while (argc-- > 0) {
+ if (strcmp(*argv, "require_auditd") == 0)
+ require_auditd = 1;
+ argv++;
+ }
+
+ if (require_auditd) {
+ int rc = check_auditd();
+ if (rc != PAM_SUCCESS)
+ pam_syslog(pamh, LOG_ERR, "required running auditd not detected");
+ return rc != PAM_SUCCESS ? rc : ret;
+ } else
+#endif
+ return ret;
+}
+
+/*
+ * PAM routines
+ *
+ * This is here for vsftpd which doesn't seem to run the session stack
+ */
+int
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return _pam_loginuid(pamh, flags, argc, argv);
+}
+
+int
+pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return _pam_loginuid(pamh, flags, argc, argv);
+}
+
+int
+pam_sm_close_session(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
diff --git a/modules/pam_loginuid/tst-pam_loginuid b/modules/pam_loginuid/tst-pam_loginuid
new file mode 100755
index 0000000..bd1e83b
--- /dev/null
+++ b/modules/pam_loginuid/tst-pam_loginuid
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_loginuid.so
diff --git a/modules/pam_mail/Makefile.am b/modules/pam_mail/Makefile.am
new file mode 100644
index 0000000..6756f40
--- /dev/null
+++ b/modules/pam_mail/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_mail.8
+endif
+XMLS = README.xml pam_mail.8.xml
+dist_check_SCRIPTS = tst-pam_mail
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_mail.la
+pam_mail_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_mail/Makefile.in b/modules/pam_mail/Makefile.in
new file mode 100644
index 0000000..fbbffa7
--- /dev/null
+++ b/modules/pam_mail/Makefile.in
@@ -0,0 +1,1150 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_mail
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_mail_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_mail_la_SOURCES = pam_mail.c
+pam_mail_la_OBJECTS = pam_mail.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_mail.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_mail.c
+DIST_SOURCES = pam_mail.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_mail.8
+XMLS = README.xml pam_mail.8.xml
+dist_check_SCRIPTS = tst-pam_mail
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_mail.la
+pam_mail_la_LIBADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_mail/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_mail/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_mail.la: $(pam_mail_la_OBJECTS) $(pam_mail_la_DEPENDENCIES) $(EXTRA_pam_mail_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_mail_la_OBJECTS) $(pam_mail_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_mail.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_mail.log: tst-pam_mail
+ @p='tst-pam_mail'; \
+ b='tst-pam_mail'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_mail.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_mail.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_mail/README b/modules/pam_mail/README
new file mode 100644
index 0000000..3da9276
--- /dev/null
+++ b/modules/pam_mail/README
@@ -0,0 +1,71 @@
+pam_mail — Inform about available mail
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+The pam_mail PAM module provides the "you have new mail" service to the user.
+It can be plugged into any application that has credential or session hooks. It
+gives a single message indicating the newness of any mail it finds in the
+user's mail folder. This module also sets the PAM environment variable, MAIL,
+to the user's mail directory.
+
+If the mail spool file (be it /var/mail/$USER or a pathname given with the dir=
+parameter) is a directory then pam_mail assumes it is in the Maildir format.
+
+OPTIONS
+
+close
+
+ Indicate if the user has any mail also on logout.
+
+debug
+
+ Print debug information.
+
+dir=maildir
+
+ Look for the user's mail in an alternative location defined by maildir/
+ <login>. The default location for mail is /var/mail/<login>. Note, if the
+ supplied maildir is prefixed by a '~', the directory is interpreted as
+ indicating a file in the user's home directory.
+
+empty
+
+ Also print message if user has no mail.
+
+hash=count
+
+ Mail directory hash depth. For example, a hashcount of 2 would make the
+ mail file be /var/spool/mail/u/s/user.
+
+noenv
+
+ Do not set the MAIL environment variable.
+
+nopen
+
+ Don't print any mail information on login. This flag is useful to get the
+ MAIL environment variable set, but to not display any information about it.
+
+quiet
+
+ Only report when there is new mail.
+
+standard
+
+ Old style "You have..." format which doesn't show the mail spool being
+ used. This also implies "empty".
+
+EXAMPLES
+
+Add the following line to /etc/pam.d/login to indicate that the user has new
+mail when they login to the system.
+
+session optional pam_mail.so standard
+
+
+AUTHOR
+
+pam_mail was written by Andrew G. Morgan <morgan@kernel.org>.
+
diff --git a/modules/pam_mail/README.xml b/modules/pam_mail/README.xml
new file mode 100644
index 0000000..4165d85
--- /dev/null
+++ b/modules/pam_mail/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_mail.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_mail.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_mail-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_mail.8.xml" xpointer='xpointer(//refsect1[@id = "pam_mail-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_mail.8.xml" xpointer='xpointer(//refsect1[@id = "pam_mail-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_mail.8.xml" xpointer='xpointer(//refsect1[@id = "pam_mail-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_mail.8.xml" xpointer='xpointer(//refsect1[@id = "pam_mail-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_mail/pam_mail.8 b/modules/pam_mail/pam_mail.8
new file mode 100644
index 0000000..a6f7766
--- /dev/null
+++ b/modules/pam_mail/pam_mail.8
@@ -0,0 +1,159 @@
+'\" t
+.\" Title: pam_mail
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_MAIL" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_mail \- Inform about available mail
+.SH "SYNOPSIS"
+.HP \w'\fBpam_mail\&.so\fR\ 'u
+\fBpam_mail\&.so\fR [close] [debug] [dir=\fImaildir\fR] [empty] [hash=\fIcount\fR] [noenv] [nopen] [quiet] [standard]
+.SH "DESCRIPTION"
+.PP
+The pam_mail PAM module provides the "you have new mail" service to the user\&. It can be plugged into any application that has credential or session hooks\&. It gives a single message indicating the
+\fInewness\fR
+of any mail it finds in the user\*(Aqs mail folder\&. This module also sets the PAM environment variable,
+\fBMAIL\fR, to the user\*(Aqs mail directory\&.
+.PP
+If the mail spool file (be it
+/var/mail/$USER
+or a pathname given with the
+\fBdir=\fR
+parameter) is a directory then pam_mail assumes it is in the
+\fIMaildir\fR
+format\&.
+.SH "OPTIONS"
+.PP
+.PP
+\fBclose\fR
+.RS 4
+Indicate if the user has any mail also on logout\&.
+.RE
+.PP
+\fBdebug\fR
+.RS 4
+Print debug information\&.
+.RE
+.PP
+\fBdir=\fR\fB\fImaildir\fR\fR
+.RS 4
+Look for the user\*(Aqs mail in an alternative location defined by
+maildir/<login>\&. The default location for mail is
+/var/mail/<login>\&. Note, if the supplied
+maildir
+is prefixed by a \*(Aq~\*(Aq, the directory is interpreted as indicating a file in the user\*(Aqs home directory\&.
+.RE
+.PP
+\fBempty\fR
+.RS 4
+Also print message if user has no mail\&.
+.RE
+.PP
+\fBhash=\fR\fB\fIcount\fR\fR
+.RS 4
+Mail directory hash depth\&. For example, a
+\fIhashcount\fR
+of 2 would make the mail file be
+/var/spool/mail/u/s/user\&.
+.RE
+.PP
+\fBnoenv\fR
+.RS 4
+Do not set the
+\fBMAIL\fR
+environment variable\&.
+.RE
+.PP
+\fBnopen\fR
+.RS 4
+Don\*(Aqt print any mail information on login\&. This flag is useful to get the
+\fBMAIL\fR
+environment variable set, but to not display any information about it\&.
+.RE
+.PP
+\fBquiet\fR
+.RS 4
+Only report when there is new mail\&.
+.RE
+.PP
+\fBstandard\fR
+.RS 4
+Old style "You have\&.\&.\&." format which doesn\*(Aqt show the mail spool being used\&. This also implies "empty"\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+The
+\fBsession\fR
+and
+\fBauth\fR
+(on establishment and deletion of credentials) module types are provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_SERVICE_ERR
+.RS 4
+Badly formed arguments\&.
+.RE
+.PP
+PAM_SUCCESS
+.RS 4
+Success\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+User not known\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Add the following line to
+/etc/pam\&.d/login
+to indicate that the user has new mail when they login to the system\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+session optional pam_mail\&.so standard
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.PP
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_mail was written by Andrew G\&. Morgan <morgan@kernel\&.org>\&.
diff --git a/modules/pam_mail/pam_mail.8.xml b/modules/pam_mail/pam_mail.8.xml
new file mode 100644
index 0000000..95216b6
--- /dev/null
+++ b/modules/pam_mail/pam_mail.8.xml
@@ -0,0 +1,280 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_mail">
+
+ <refmeta>
+ <refentrytitle>pam_mail</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_mail-name">
+ <refname>pam_mail</refname>
+ <refpurpose>Inform about available mail</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_mail-cmdsynopsis">
+ <command>pam_mail.so</command>
+ <arg choice="opt">
+ close
+ </arg>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ dir=<replaceable>maildir</replaceable>
+ </arg>
+ <arg choice="opt">
+ empty
+ </arg>
+ <arg choice="opt">
+ hash=<replaceable>count</replaceable>
+ </arg>
+ <arg choice="opt">
+ noenv
+ </arg>
+ <arg choice="opt">
+ nopen
+ </arg>
+ <arg choice="opt">
+ quiet
+ </arg>
+ <arg choice="opt">
+ standard
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_mail-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ The pam_mail PAM module provides the "you have new mail"
+ service to the user. It can be plugged into any application
+ that has credential or session hooks. It gives a single message
+ indicating the <emphasis>newness</emphasis> of any mail it finds
+ in the user's mail folder. This module also sets the PAM
+ environment variable, <emphasis remap='B'>MAIL</emphasis>, to the
+ user's mail directory.
+ </para>
+ <para>
+ If the mail spool file (be it <filename>/var/mail/$USER</filename>
+ or a pathname given with the <option>dir=</option> parameter) is
+ a directory then pam_mail assumes it is in the
+ <emphasis remap='I'>Maildir</emphasis> format.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_mail-options">
+
+ <title>OPTIONS</title>
+ <para>
+ <variablelist>
+
+ <varlistentry>
+ <term>
+ <option>close</option>
+ </term>
+ <listitem>
+ <para>
+ Indicate if the user has any mail also on logout.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Print debug information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>dir=<replaceable>maildir</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Look for the user's mail in an alternative location defined by
+ <filename>maildir/&lt;login&gt;</filename>. The default
+ location for mail is <filename>/var/mail/&lt;login&gt;</filename>.
+ Note, if the supplied
+ <filename>maildir</filename> is prefixed by a '~', the
+ directory is interpreted as indicating a file in the user's
+ home directory.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>empty</option>
+ </term>
+ <listitem>
+ <para>
+ Also print message if user has no mail.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>hash=<replaceable>count</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Mail directory hash depth. For example, a
+ <emphasis>hashcount</emphasis> of 2 would
+ make the mail file be
+ <filename>/var/spool/mail/u/s/user</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>noenv</option>
+ </term>
+ <listitem>
+ <para>
+ Do not set the <emphasis remap='B'>MAIL</emphasis>
+ environment variable.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>nopen</option>
+ </term>
+ <listitem>
+ <para>
+ Don't print any mail information on login. This flag is
+ useful to get the <emphasis remap='B'>MAIL</emphasis>
+ environment variable set, but to not display any information
+ about it.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>quiet</option>
+ </term>
+ <listitem>
+ <para>
+ Only report when there is new mail.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>standard</option>
+ </term>
+ <listitem>
+ <para>
+ Old style "You have..." format which doesn't show the
+ mail spool being used. This also implies "empty".
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_mail-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ The <option>session</option> and
+ <option>auth</option> (on establishment and
+ deletion of credentials) module types are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_mail-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory buffer error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ Badly formed arguments.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Success.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ User not known.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_mail-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ Add the following line to <filename>/etc/pam.d/login</filename> to
+ indicate that the user has new mail when they login to the system.
+ <programlisting>
+session optional pam_mail.so standard
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_mail-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_mail-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_mail was written by Andrew G. Morgan &lt;morgan@kernel.org&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_mail/pam_mail.c b/modules/pam_mail/pam_mail.c
new file mode 100644
index 0000000..17383c7
--- /dev/null
+++ b/modules/pam_mail/pam_mail.c
@@ -0,0 +1,468 @@
+/*
+ * pam_mail module
+ *
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
+ * $HOME additions by David Kinchlea <kinch@kinch.ark.com> 1997/1/7
+ * mailhash additions by Chris Adams <cadams@ro.com> 1998/7/11
+ */
+
+#include "config.h"
+
+#include <ctype.h>
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <errno.h>
+
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+
+#define DEFAULT_MAIL_DIRECTORY PAM_PATH_MAILDIR
+#define MAIL_FILE_FORMAT "%s%s/%s"
+#define MAIL_ENV_NAME "MAIL"
+#define MAIL_ENV_FORMAT MAIL_ENV_NAME "=%s"
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+#include "pam_inline.h"
+
+/* argument parsing */
+
+#define PAM_DEBUG_ARG 0x0001
+#define PAM_NO_LOGIN 0x0002
+#define PAM_LOGOUT_TOO 0x0004
+#define PAM_NEW_MAIL_DIR 0x0010
+#define PAM_MAIL_SILENT 0x0020
+#define PAM_NO_ENV 0x0040
+#define PAM_HOME_MAIL 0x0100
+#define PAM_EMPTY_TOO 0x0200
+#define PAM_STANDARD_MAIL 0x0400
+#define PAM_QUIET_MAIL 0x1000
+
+#define HAVE_NEW_MAIL 0x1
+#define HAVE_OLD_MAIL 0x2
+#define HAVE_NO_MAIL 0x3
+#define HAVE_MAIL 0x4
+
+static int
+_pam_parse (const pam_handle_t *pamh, int flags, int argc,
+ const char **argv, const char **maildir, size_t *hashcount)
+{
+ int ctrl=0;
+
+ if (flags & PAM_SILENT) {
+ ctrl |= PAM_MAIL_SILENT;
+ }
+
+ *hashcount = 0;
+
+ /* step through arguments */
+ for (; argc-- > 0; ++argv) {
+ const char *str;
+
+ /* generic options */
+
+ if (!strcmp(*argv,"debug"))
+ ctrl |= PAM_DEBUG_ARG;
+ else if (!strcmp(*argv,"quiet"))
+ ctrl |= PAM_QUIET_MAIL;
+ else if (!strcmp(*argv,"standard"))
+ ctrl |= PAM_STANDARD_MAIL | PAM_EMPTY_TOO;
+ else if ((str = pam_str_skip_prefix(*argv, "dir=")) != NULL) {
+ *maildir = str;
+ if (**maildir != '\0') {
+ D(("new mail directory: %s", *maildir));
+ ctrl |= PAM_NEW_MAIL_DIR;
+ } else {
+ pam_syslog(pamh, LOG_ERR,
+ "dir= specification missing argument - ignored");
+ }
+ } else if ((str = pam_str_skip_prefix(*argv, "hash=")) != NULL) {
+ char *ep = NULL;
+ *hashcount = strtoul(str,&ep,10);
+ if (!ep) {
+ *hashcount = 0;
+ }
+ } else if (!strcmp(*argv,"close")) {
+ ctrl |= PAM_LOGOUT_TOO;
+ } else if (!strcmp(*argv,"nopen")) {
+ ctrl |= PAM_NO_LOGIN;
+ } else if (!strcmp(*argv,"noenv")) {
+ ctrl |= PAM_NO_ENV;
+ } else if (!strcmp(*argv,"empty")) {
+ ctrl |= PAM_EMPTY_TOO;
+ } else {
+ pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
+ }
+ }
+
+ if ((*hashcount != 0) && !(ctrl & PAM_NEW_MAIL_DIR)) {
+ *maildir = DEFAULT_MAIL_DIRECTORY;
+ ctrl |= PAM_NEW_MAIL_DIR;
+ }
+
+ return ctrl;
+}
+
+static int
+get_folder(pam_handle_t *pamh, int ctrl,
+ const char *path_mail, char **folder_p, size_t hashcount,
+ const struct passwd *pwd)
+{
+ int retval;
+ const char *path;
+ char *folder = NULL;
+
+ if (ctrl & PAM_NEW_MAIL_DIR) {
+ path = path_mail;
+ if (*path == '~') { /* support for $HOME delivery */
+ /*
+ * "~/xxx" and "~xxx" are treated as same
+ */
+ if (!*++path || (*path == '/' && !*++path)) {
+ pam_syslog(pamh, LOG_ERR,
+ "badly formed mail path [%s]", path_mail);
+ retval = PAM_SERVICE_ERR;
+ goto get_folder_cleanup;
+ }
+ ctrl |= PAM_HOME_MAIL;
+ if (hashcount != 0) {
+ pam_syslog(pamh, LOG_ERR,
+ "cannot do hash= and home directory mail");
+ }
+ }
+ } else {
+ path = DEFAULT_MAIL_DIRECTORY;
+ }
+
+ /* put folder together */
+
+ hashcount = hashcount < strlen(pwd->pw_name) ?
+ hashcount : strlen(pwd->pw_name);
+
+ retval = PAM_BUF_ERR;
+ if (ctrl & PAM_HOME_MAIL) {
+ if (asprintf(&folder, MAIL_FILE_FORMAT, pwd->pw_dir, "", path) < 0)
+ goto get_folder_cleanup;
+ } else {
+ int rc;
+ size_t i;
+ char *hash;
+
+ if ((hash = malloc(2 * hashcount + 1)) == NULL)
+ goto get_folder_cleanup;
+
+ for (i = 0; i < hashcount; i++) {
+ hash[2 * i] = '/';
+ hash[2 * i + 1] = pwd->pw_name[i];
+ }
+ hash[2 * i] = '\0';
+
+ rc = asprintf(&folder, MAIL_FILE_FORMAT, path, hash, pwd->pw_name);
+ _pam_overwrite(hash);
+ _pam_drop(hash);
+ if (rc < 0)
+ goto get_folder_cleanup;
+ }
+ D(("folder=[%s]", folder));
+ retval = PAM_SUCCESS;
+
+ /* tidy up */
+
+ get_folder_cleanup:
+ path = NULL;
+
+ *folder_p = folder;
+ folder = NULL;
+
+ if (retval == PAM_BUF_ERR)
+ pam_syslog(pamh, LOG_CRIT, "out of memory for mail folder");
+
+ return retval;
+}
+
+static int
+get_mail_status(pam_handle_t *pamh, int ctrl, const char *folder)
+{
+ int type = 0;
+ struct stat mail_st;
+
+ if (stat(folder, &mail_st) < 0)
+ return 0;
+
+ if (S_ISDIR(mail_st.st_mode)) { /* Assume Maildir format */
+ int i, save_errno;
+ char *dir;
+ struct dirent **namelist;
+
+ if (asprintf(&dir, "%s/new", folder) < 0) {
+ pam_syslog(pamh, LOG_CRIT, "out of memory");
+ goto get_mail_status_cleanup;
+ }
+ i = scandir(dir, &namelist, 0, alphasort);
+ save_errno = errno;
+ _pam_overwrite(dir);
+ _pam_drop(dir);
+ if (i < 0) {
+ type = 0;
+ namelist = NULL;
+ if (save_errno == ENOMEM) {
+ pam_syslog(pamh, LOG_CRIT, "out of memory");
+ goto get_mail_status_cleanup;
+ }
+ }
+ type = (i > 2) ? HAVE_NEW_MAIL : 0;
+ while (--i >= 0)
+ _pam_drop(namelist[i]);
+ _pam_drop(namelist);
+ if (type == 0) {
+ if (asprintf(&dir, "%s/cur", folder) < 0) {
+ pam_syslog(pamh, LOG_CRIT, "out of memory");
+ goto get_mail_status_cleanup;
+ }
+ i = scandir(dir, &namelist, 0, alphasort);
+ save_errno = errno;
+ _pam_overwrite(dir);
+ _pam_drop(dir);
+ if (i < 0) {
+ type = 0;
+ namelist = NULL;
+ if (save_errno == ENOMEM) {
+ pam_syslog(pamh, LOG_CRIT, "out of memory");
+ goto get_mail_status_cleanup;
+ }
+ }
+ if (i > 2)
+ type = HAVE_OLD_MAIL;
+ else
+ type = (ctrl & PAM_EMPTY_TOO) ? HAVE_NO_MAIL : 0;
+ while (--i >= 0)
+ _pam_drop(namelist[i]);
+ _pam_drop(namelist);
+ }
+ } else {
+ if (mail_st.st_size > 0) {
+ if (mail_st.st_atime < mail_st.st_mtime) /* new */
+ type = HAVE_NEW_MAIL;
+ else /* old */
+ type = (ctrl & PAM_STANDARD_MAIL) ? HAVE_MAIL : HAVE_OLD_MAIL;
+ } else if (ctrl & PAM_EMPTY_TOO) {
+ type = HAVE_NO_MAIL;
+ } else {
+ type = 0;
+ }
+ }
+
+ get_mail_status_cleanup:
+ memset(&mail_st, 0, sizeof(mail_st));
+ D(("user has %d mail in %s folder", type, folder));
+ return type;
+}
+
+static int
+report_mail(pam_handle_t *pamh, int ctrl, int type, const char *folder)
+{
+ int retval;
+
+ if ((ctrl & PAM_MAIL_SILENT) ||
+ ((ctrl & PAM_QUIET_MAIL) && type != HAVE_NEW_MAIL))
+ {
+ D(("keeping quiet"));
+ retval = PAM_SUCCESS;
+ }
+ else
+ {
+ if (ctrl & PAM_STANDARD_MAIL)
+ switch (type)
+ {
+ case HAVE_NO_MAIL:
+ retval = pam_info (pamh, "%s", _("You have no mail."));
+ break;
+ case HAVE_NEW_MAIL:
+ retval = pam_info (pamh, "%s", _("You have new mail."));
+ break;
+ case HAVE_OLD_MAIL:
+ retval = pam_info (pamh, "%s", _("You have old mail."));
+ break;
+ case HAVE_MAIL:
+ default:
+ retval = pam_info (pamh, "%s", _("You have mail."));
+ break;
+ }
+ else
+ switch (type)
+ {
+ case HAVE_NO_MAIL:
+ retval = pam_info (pamh, _("You have no mail in folder %s."),
+ folder);
+ break;
+ case HAVE_NEW_MAIL:
+ retval = pam_info (pamh, _("You have new mail in folder %s."),
+ folder);
+ break;
+ case HAVE_OLD_MAIL:
+ retval = pam_info (pamh, _("You have old mail in folder %s."),
+ folder);
+ break;
+ case HAVE_MAIL:
+ default:
+ retval = pam_info (pamh, _("You have mail in folder %s."),
+ folder);
+ break;
+ }
+ }
+
+ D(("returning %s", pam_strerror(pamh, retval)));
+ return retval;
+}
+
+static int _do_mail(pam_handle_t *, int, int, const char **, int);
+
+/* --- authentication functions --- */
+
+int
+pam_sm_authenticate (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_IGNORE;
+}
+
+/* Checking mail as part of authentication */
+int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ if (!(flags & (PAM_ESTABLISH_CRED|PAM_DELETE_CRED)))
+ return PAM_IGNORE;
+ return _do_mail(pamh,flags,argc,argv,(flags & PAM_ESTABLISH_CRED));
+}
+
+/* --- session management functions --- */
+
+int pam_sm_close_session(pam_handle_t *pamh,int flags,int argc
+ ,const char **argv)
+{
+ return _do_mail(pamh,flags,argc,argv,0);
+}
+
+/* Checking mail as part of the session management */
+int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ return _do_mail(pamh,flags,argc,argv,1);
+}
+
+
+/* --- The Beaf (Tm) --- */
+
+static int _do_mail(pam_handle_t *pamh, int flags, int argc,
+ const char **argv, int est)
+{
+ int retval, ctrl, type;
+ size_t hashcount;
+ char *folder = NULL;
+ const char *user;
+ const char *path_mail = NULL;
+ const struct passwd *pwd = NULL;
+
+ /*
+ * this module (un)sets the MAIL environment variable, and checks if
+ * the user has any new mail.
+ */
+
+ ctrl = _pam_parse(pamh, flags, argc, argv, &path_mail, &hashcount);
+
+ retval = pam_get_user(pamh, &user, NULL);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE, "cannot determine user name: %s",
+ pam_strerror(pamh, retval));
+ return PAM_USER_UNKNOWN;
+ }
+
+ pwd = pam_modutil_getpwnam (pamh, user);
+ if (pwd == NULL) {
+ pam_syslog(pamh, LOG_NOTICE, "user unknown");
+ return PAM_USER_UNKNOWN;
+ }
+
+ /* which folder? */
+
+ retval = get_folder(pamh, ctrl, path_mail, &folder, hashcount, pwd);
+ if (retval != PAM_SUCCESS) {
+ D(("failed to find folder"));
+ return retval;
+ }
+
+ /* set the MAIL variable? */
+
+ if (!(ctrl & PAM_NO_ENV) && est) {
+ char *tmp;
+
+ if (asprintf(&tmp, MAIL_ENV_FORMAT, folder) < 0) {
+ pam_syslog(pamh, LOG_CRIT,
+ "no memory for " MAIL_ENV_NAME " variable");
+ retval = PAM_BUF_ERR;
+ goto do_mail_cleanup;
+ }
+ D(("setting env: %s", tmp));
+ retval = pam_putenv(pamh, tmp);
+ _pam_overwrite(tmp);
+ _pam_drop(tmp);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_CRIT,
+ "unable to set " MAIL_ENV_NAME " variable");
+ retval = PAM_BUF_ERR;
+ goto do_mail_cleanup;
+ }
+ } else {
+ D(("not setting " MAIL_ENV_NAME " variable"));
+ }
+
+ /*
+ * OK. we've got the mail folder... what about its status?
+ */
+
+ if ((est && !(ctrl & PAM_NO_LOGIN))
+ || (!est && (ctrl & PAM_LOGOUT_TOO))) {
+ PAM_MODUTIL_DEF_PRIVS(privs);
+
+ if (pam_modutil_drop_priv(pamh, &privs, pwd)) {
+ retval = PAM_SESSION_ERR;
+ goto do_mail_cleanup;
+ } else {
+ type = get_mail_status(pamh, ctrl, folder);
+ if (pam_modutil_regain_priv(pamh, &privs)) {
+ retval = PAM_SESSION_ERR;
+ goto do_mail_cleanup;
+ }
+ }
+
+ if (type != 0) {
+ retval = report_mail(pamh, ctrl, type, folder);
+ type = 0;
+ }
+ }
+
+ /* Delete environment variable? */
+ if ( ! est && ! (ctrl & PAM_NO_ENV) )
+ (void) pam_putenv(pamh, MAIL_ENV_NAME);
+
+ do_mail_cleanup:
+ _pam_overwrite(folder);
+ _pam_drop(folder);
+
+ /* indicate success or failure */
+
+ return retval;
+}
+
+/* end of module definition */
diff --git a/modules/pam_mail/tst-pam_mail b/modules/pam_mail/tst-pam_mail
new file mode 100755
index 0000000..99fb7ed
--- /dev/null
+++ b/modules/pam_mail/tst-pam_mail
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_mail.so
diff --git a/modules/pam_mkhomedir/Makefile.am b/modules/pam_mkhomedir/Makefile.am
new file mode 100644
index 0000000..04da1dc
--- /dev/null
+++ b/modules/pam_mkhomedir/Makefile.am
@@ -0,0 +1,44 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+# Copyright (c) 2008 Red Hat, Inc.
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_mkhomedir.8 mkhomedir_helper.8
+endif
+XMLS = README.xml pam_mkhomedir.8.xml mkhomedir_helper.8.xml
+dist_check_SCRIPTS = tst-pam_mkhomedir
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DMKHOMEDIR_HELPER=\"$(sbindir)/mkhomedir_helper\" $(WARN_CFLAGS)
+
+securelib_LTLIBRARIES = pam_mkhomedir.la
+pam_mkhomedir_la_SOURCES = pam_mkhomedir.c
+pam_mkhomedir_la_LIBADD = $(top_builddir)/libpam/libpam.la
+pam_mkhomedir_la_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ pam_mkhomedir_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+sbin_PROGRAMS = mkhomedir_helper
+mkhomedir_helper_SOURCES = mkhomedir_helper.c
+mkhomedir_helper_CFLAGS = $(AM_CFLAGS) @EXE_CFLAGS@
+mkhomedir_helper_LDFLAGS = @EXE_LDFLAGS@
+mkhomedir_helper_LDADD = $(top_builddir)/libpam/libpam.la
+
+check_PROGRAMS = tst-pam_mkhomedir-retval
+tst_pam_mkhomedir_retval_LDADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_mkhomedir/Makefile.in b/modules/pam_mkhomedir/Makefile.in
new file mode 100644
index 0000000..163531e
--- /dev/null
+++ b/modules/pam_mkhomedir/Makefile.in
@@ -0,0 +1,1280 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+# Copyright (c) 2008 Red Hat, Inc.
+#
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+sbin_PROGRAMS = mkhomedir_helper$(EXEEXT)
+check_PROGRAMS = tst-pam_mkhomedir-retval$(EXEEXT)
+subdir = modules/pam_mkhomedir
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(securelibdir)" \
+ "$(DESTDIR)$(man8dir)"
+PROGRAMS = $(sbin_PROGRAMS)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_mkhomedir_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+am_pam_mkhomedir_la_OBJECTS = pam_mkhomedir.lo
+pam_mkhomedir_la_OBJECTS = $(am_pam_mkhomedir_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+pam_mkhomedir_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(pam_mkhomedir_la_LDFLAGS) $(LDFLAGS) \
+ -o $@
+am_mkhomedir_helper_OBJECTS = \
+ mkhomedir_helper-mkhomedir_helper.$(OBJEXT)
+mkhomedir_helper_OBJECTS = $(am_mkhomedir_helper_OBJECTS)
+mkhomedir_helper_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+mkhomedir_helper_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(mkhomedir_helper_CFLAGS) $(CFLAGS) \
+ $(mkhomedir_helper_LDFLAGS) $(LDFLAGS) -o $@
+tst_pam_mkhomedir_retval_SOURCES = tst-pam_mkhomedir-retval.c
+tst_pam_mkhomedir_retval_OBJECTS = tst-pam_mkhomedir-retval.$(OBJEXT)
+tst_pam_mkhomedir_retval_DEPENDENCIES = \
+ $(top_builddir)/libpam/libpam.la
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = \
+ ./$(DEPDIR)/mkhomedir_helper-mkhomedir_helper.Po \
+ ./$(DEPDIR)/pam_mkhomedir.Plo \
+ ./$(DEPDIR)/tst-pam_mkhomedir-retval.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(pam_mkhomedir_la_SOURCES) $(mkhomedir_helper_SOURCES) \
+ tst-pam_mkhomedir-retval.c
+DIST_SOURCES = $(pam_mkhomedir_la_SOURCES) $(mkhomedir_helper_SOURCES) \
+ tst-pam_mkhomedir-retval.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_mkhomedir.8 mkhomedir_helper.8
+XMLS = README.xml pam_mkhomedir.8.xml mkhomedir_helper.8.xml
+dist_check_SCRIPTS = tst-pam_mkhomedir
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DMKHOMEDIR_HELPER=\"$(sbindir)/mkhomedir_helper\" $(WARN_CFLAGS)
+
+securelib_LTLIBRARIES = pam_mkhomedir.la
+pam_mkhomedir_la_SOURCES = pam_mkhomedir.c
+pam_mkhomedir_la_LIBADD = $(top_builddir)/libpam/libpam.la
+pam_mkhomedir_la_LDFLAGS = -no-undefined -avoid-version -module \
+ $(am__append_1)
+mkhomedir_helper_SOURCES = mkhomedir_helper.c
+mkhomedir_helper_CFLAGS = $(AM_CFLAGS) @EXE_CFLAGS@
+mkhomedir_helper_LDFLAGS = @EXE_LDFLAGS@
+mkhomedir_helper_LDADD = $(top_builddir)/libpam/libpam.la
+tst_pam_mkhomedir_retval_LDADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_mkhomedir/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_mkhomedir/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(sbindir)" && rm -f $$files
+
+clean-sbinPROGRAMS:
+ @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_mkhomedir.la: $(pam_mkhomedir_la_OBJECTS) $(pam_mkhomedir_la_DEPENDENCIES) $(EXTRA_pam_mkhomedir_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(pam_mkhomedir_la_LINK) -rpath $(securelibdir) $(pam_mkhomedir_la_OBJECTS) $(pam_mkhomedir_la_LIBADD) $(LIBS)
+
+mkhomedir_helper$(EXEEXT): $(mkhomedir_helper_OBJECTS) $(mkhomedir_helper_DEPENDENCIES) $(EXTRA_mkhomedir_helper_DEPENDENCIES)
+ @rm -f mkhomedir_helper$(EXEEXT)
+ $(AM_V_CCLD)$(mkhomedir_helper_LINK) $(mkhomedir_helper_OBJECTS) $(mkhomedir_helper_LDADD) $(LIBS)
+
+tst-pam_mkhomedir-retval$(EXEEXT): $(tst_pam_mkhomedir_retval_OBJECTS) $(tst_pam_mkhomedir_retval_DEPENDENCIES) $(EXTRA_tst_pam_mkhomedir_retval_DEPENDENCIES)
+ @rm -f tst-pam_mkhomedir-retval$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tst_pam_mkhomedir_retval_OBJECTS) $(tst_pam_mkhomedir_retval_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mkhomedir_helper-mkhomedir_helper.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_mkhomedir.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-pam_mkhomedir-retval.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mkhomedir_helper-mkhomedir_helper.o: mkhomedir_helper.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mkhomedir_helper_CFLAGS) $(CFLAGS) -MT mkhomedir_helper-mkhomedir_helper.o -MD -MP -MF $(DEPDIR)/mkhomedir_helper-mkhomedir_helper.Tpo -c -o mkhomedir_helper-mkhomedir_helper.o `test -f 'mkhomedir_helper.c' || echo '$(srcdir)/'`mkhomedir_helper.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mkhomedir_helper-mkhomedir_helper.Tpo $(DEPDIR)/mkhomedir_helper-mkhomedir_helper.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mkhomedir_helper.c' object='mkhomedir_helper-mkhomedir_helper.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mkhomedir_helper_CFLAGS) $(CFLAGS) -c -o mkhomedir_helper-mkhomedir_helper.o `test -f 'mkhomedir_helper.c' || echo '$(srcdir)/'`mkhomedir_helper.c
+
+mkhomedir_helper-mkhomedir_helper.obj: mkhomedir_helper.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mkhomedir_helper_CFLAGS) $(CFLAGS) -MT mkhomedir_helper-mkhomedir_helper.obj -MD -MP -MF $(DEPDIR)/mkhomedir_helper-mkhomedir_helper.Tpo -c -o mkhomedir_helper-mkhomedir_helper.obj `if test -f 'mkhomedir_helper.c'; then $(CYGPATH_W) 'mkhomedir_helper.c'; else $(CYGPATH_W) '$(srcdir)/mkhomedir_helper.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mkhomedir_helper-mkhomedir_helper.Tpo $(DEPDIR)/mkhomedir_helper-mkhomedir_helper.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='mkhomedir_helper.c' object='mkhomedir_helper-mkhomedir_helper.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mkhomedir_helper_CFLAGS) $(CFLAGS) -c -o mkhomedir_helper-mkhomedir_helper.obj `if test -f 'mkhomedir_helper.c'; then $(CYGPATH_W) 'mkhomedir_helper.c'; else $(CYGPATH_W) '$(srcdir)/mkhomedir_helper.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_mkhomedir.log: tst-pam_mkhomedir
+ @p='tst-pam_mkhomedir'; \
+ b='tst-pam_mkhomedir'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+tst-pam_mkhomedir-retval.log: tst-pam_mkhomedir-retval$(EXEEXT)
+ @p='tst-pam_mkhomedir-retval$(EXEEXT)'; \
+ b='tst-pam_mkhomedir-retval'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) \
+ $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-sbinPROGRAMS clean-securelibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/mkhomedir_helper-mkhomedir_helper.Po
+ -rm -f ./$(DEPDIR)/pam_mkhomedir.Plo
+ -rm -f ./$(DEPDIR)/tst-pam_mkhomedir-retval.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-sbinPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/mkhomedir_helper-mkhomedir_helper.Po
+ -rm -f ./$(DEPDIR)/pam_mkhomedir.Plo
+ -rm -f ./$(DEPDIR)/tst-pam_mkhomedir-retval.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-sbinPROGRAMS \
+ uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-sbinPROGRAMS clean-securelibLTLIBRARIES cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-sbinPROGRAMS \
+ uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_mkhomedir/README b/modules/pam_mkhomedir/README
new file mode 100644
index 0000000..cfc7bc4
--- /dev/null
+++ b/modules/pam_mkhomedir/README
@@ -0,0 +1,36 @@
+pam_mkhomedir — PAM module to create users home directory
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+The pam_mkhomedir PAM module will create a users home directory if it does not
+exist when the session begins. This allows users to be present in central
+database (such as NIS, kerberos or LDAP) without using a distributed file
+system or pre-creating a large number of directories. The skeleton directory
+(usually /etc/skel/) is used to copy default files and also sets a umask for
+the creation.
+
+The new users home directory will not be removed after logout of the user.
+
+EXAMPLES
+
+A sample /etc/pam.d/login file:
+
+ auth requisite pam_securetty.so
+ auth sufficient pam_ldap.so
+ auth required pam_unix.so
+ auth required pam_nologin.so
+ account sufficient pam_ldap.so
+ account required pam_unix.so
+ password required pam_unix.so
+ session required pam_mkhomedir.so skel=/etc/skel/ umask=0022
+ session required pam_unix.so
+ session optional pam_lastlog.so
+ session optional pam_mail.so standard
+
+
+AUTHOR
+
+pam_mkhomedir was written by Jason Gunthorpe <jgg@debian.org>.
+
diff --git a/modules/pam_mkhomedir/README.xml b/modules/pam_mkhomedir/README.xml
new file mode 100644
index 0000000..978cbe7
--- /dev/null
+++ b/modules/pam_mkhomedir/README.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_mkhomedir.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_mkhomedir.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_mkhomedir-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_mkhomedir.8.xml" xpointer='xpointer(//refsect1[@id = "pam_mkhomedir-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_mkhomedir.8.xml" xpointer='xpointer(//refsect1[@id = "pam_mkhomedir-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_mkhomedir.8.xml" xpointer='xpointer(//refsect1[@id = "pam_mkhomedir-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_mkhomedir/mkhomedir_helper.8 b/modules/pam_mkhomedir/mkhomedir_helper.8
new file mode 100644
index 0000000..a9e68a0
--- /dev/null
+++ b/modules/pam_mkhomedir/mkhomedir_helper.8
@@ -0,0 +1,63 @@
+'\" t
+.\" Title: mkhomedir_helper
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "MKHOMEDIR_HELPER" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+mkhomedir_helper \- Helper binary that creates home directories
+.SH "SYNOPSIS"
+.HP \w'\fBmkhomedir_helper\fR\ 'u
+\fBmkhomedir_helper\fR {\fIuser\fR} [\fIumask\fR\ [\ \fIpath\-to\-skel\fR\ [\ \fIhome_mode\fR\ ]\ ]]
+.SH "DESCRIPTION"
+.PP
+\fImkhomedir_helper\fR
+is a helper program for the
+\fIpam_mkhomedir\fR
+module that creates home directories and populates them with contents of the specified skel directory\&.
+.PP
+The default value of
+\fIumask\fR
+is 0022 and the default value of
+\fIpath\-to\-skel\fR
+is
+\fI/etc/skel\fR\&. The default value of
+\fIhome_mode\fR
+is computed from the value of
+\fIumask\fR\&.
+.PP
+The helper is separated from the module to not require direct access from login SELinux domains to the contents of user home directories\&. The SELinux domain transition happens when the module is executing the
+\fImkhomedir_helper\fR\&.
+.PP
+The helper never touches home directories if they already exist\&.
+.SH "SEE ALSO"
+.PP
+\fBpam_mkhomedir\fR(8)
+.SH "AUTHOR"
+.PP
+Written by Tomas Mraz based on the code originally in
+\fIpam_mkhomedir\fR
+module\&.
diff --git a/modules/pam_mkhomedir/mkhomedir_helper.8.xml b/modules/pam_mkhomedir/mkhomedir_helper.8.xml
new file mode 100644
index 0000000..8a76f2d
--- /dev/null
+++ b/modules/pam_mkhomedir/mkhomedir_helper.8.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="mkhomedir_helper">
+
+ <refmeta>
+ <refentrytitle>mkhomedir_helper</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="mkhomedir_helper-name">
+ <refname>mkhomedir_helper</refname>
+ <refpurpose>Helper binary that creates home directories</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="mkhomedir_helper-cmdsynopsis">
+ <command>mkhomedir_helper</command>
+ <arg choice="req">
+ <replaceable>user</replaceable>
+ </arg>
+ <arg choice="opt">
+ <replaceable>umask</replaceable>
+ <arg choice="opt">
+ <replaceable>path-to-skel</replaceable>
+ <arg choice="opt">
+ <replaceable>home_mode</replaceable>
+ </arg>
+ </arg>
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="mkhomedir_helper-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ <emphasis>mkhomedir_helper</emphasis> is a helper program for the
+ <emphasis>pam_mkhomedir</emphasis> module that creates home directories
+ and populates them with contents of the specified skel directory.
+ </para>
+
+ <para>
+ The default value of <replaceable>umask</replaceable> is 0022 and the
+ default value of <replaceable>path-to-skel</replaceable> is
+ <emphasis>/etc/skel</emphasis>. The default value of
+ <replaceable>home_mode</replaceable> is computed from the value of
+ <replaceable>umask</replaceable>.
+ </para>
+
+ <para>
+ The helper is separated from the module to not require direct access from
+ login SELinux domains to the contents of user home directories. The
+ SELinux domain transition happens when the module is executing the
+ <emphasis>mkhomedir_helper</emphasis>.
+ </para>
+
+ <para>
+ The helper never touches home directories if they already exist.
+ </para>
+ </refsect1>
+
+ <refsect1 id='mkhomedir_helper-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam_mkhomedir</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='mkhomedir_helper-author'>
+ <title>AUTHOR</title>
+ <para>
+ Written by Tomas Mraz based on the code originally in
+ <emphasis>pam_mkhomedir</emphasis> module.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_mkhomedir/mkhomedir_helper.c b/modules/pam_mkhomedir/mkhomedir_helper.c
new file mode 100644
index 0000000..582fecc
--- /dev/null
+++ b/modules/pam_mkhomedir/mkhomedir_helper.c
@@ -0,0 +1,439 @@
+/* mkhomedir_helper - helper for pam_mkhomedir module
+
+ Released under the GNU LGPL version 2 or later
+
+ Copyright (c) Red Hat, Inc., 2009
+ Originally written by Jason Gunthorpe <jgg@debian.org> Feb 1999
+ Structure taken from pam_lastlogin by Andrew Morgan
+ <morgan@parc.power.net> 1996
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <dirent.h>
+#include <syslog.h>
+
+#include <security/pam_ext.h>
+#include <security/pam_modutil.h>
+
+static unsigned long u_mask = 0022;
+static unsigned long home_mode = 0;
+static char skeldir[BUFSIZ] = "/etc/skel";
+
+/* Do the actual work of creating a home dir */
+static int
+create_homedir(const struct passwd *pwd,
+ const char *source, const char *dest)
+{
+ char remark[BUFSIZ];
+ DIR *d;
+ struct dirent *dent;
+ int retval = PAM_SESSION_ERR;
+
+ /* Create the new directory */
+ if (mkdir(dest, 0700) && errno != EEXIST)
+ {
+ pam_syslog(NULL, LOG_ERR, "unable to create directory %s: %m", dest);
+ return PAM_PERM_DENIED;
+ }
+
+ /* See if we need to copy the skel dir over. */
+ if ((source == NULL) || (strlen(source) == 0))
+ {
+ retval = PAM_SUCCESS;
+ goto go_out;
+ }
+
+ /* Scan the directory */
+ d = opendir(source);
+ if (d == NULL)
+ {
+ pam_syslog(NULL, LOG_DEBUG, "unable to read directory %s: %m", source);
+ retval = PAM_PERM_DENIED;
+ goto go_out;
+ }
+
+ for (dent = readdir(d); dent != NULL; dent = readdir(d))
+ {
+ int srcfd;
+ int destfd;
+ int res;
+ struct stat st;
+#ifndef PATH_MAX
+ char *newsource = NULL, *newdest = NULL;
+ /* track length of buffers */
+ int nslen = 0, ndlen = 0;
+ int slen = strlen(source), dlen = strlen(dest);
+#else
+ char newsource[PATH_MAX], newdest[PATH_MAX];
+#endif
+
+ /* Skip some files.. */
+ if (strcmp(dent->d_name,".") == 0 ||
+ strcmp(dent->d_name,"..") == 0)
+ continue;
+
+ /* Determine what kind of file it is. */
+#ifndef PATH_MAX
+ nslen = slen + strlen(dent->d_name) + 2;
+
+ if (nslen <= 0)
+ {
+ retval = PAM_BUF_ERR;
+ goto go_out;
+ }
+
+ if ((newsource = malloc(nslen)) == NULL)
+ {
+ retval = PAM_BUF_ERR;
+ goto go_out;
+ }
+
+ sprintf(newsource, "%s/%s", source, dent->d_name);
+#else
+ snprintf(newsource, sizeof(newsource), "%s/%s", source, dent->d_name);
+#endif
+
+ if (lstat(newsource, &st) != 0)
+#ifndef PATH_MAX
+ {
+ free(newsource);
+ newsource = NULL;
+ continue;
+ }
+#else
+ continue;
+#endif
+
+
+ /* We'll need the new file's name. */
+#ifndef PATH_MAX
+ ndlen = dlen + strlen(dent->d_name)+2;
+
+ if (ndlen <= 0)
+ {
+ retval = PAM_BUF_ERR;
+ goto go_out;
+ }
+
+ if ((newdest = malloc(ndlen)) == NULL)
+ {
+ free (newsource);
+ retval = PAM_BUF_ERR;
+ goto go_out;
+ }
+
+ sprintf (newdest, "%s/%s", dest, dent->d_name);
+#else
+ snprintf (newdest, sizeof (newdest), "%s/%s", dest, dent->d_name);
+#endif
+
+ /* If it's a directory, recurse. */
+ if (S_ISDIR(st.st_mode))
+ {
+ retval = create_homedir(pwd, newsource, newdest);
+
+#ifndef PATH_MAX
+ free(newsource); newsource = NULL;
+ free(newdest); newdest = NULL;
+#endif
+
+ if (retval != PAM_SUCCESS)
+ {
+ closedir(d);
+ goto go_out;
+ }
+ continue;
+ }
+
+ /* If it's a symlink, create a new link. */
+ if (S_ISLNK(st.st_mode))
+ {
+ int pointedlen = 0;
+#ifndef PATH_MAX
+ char *pointed = NULL;
+ {
+ int size = 100;
+
+ while (1) {
+ pointed = malloc(size);
+ if (pointed == NULL) {
+ free(newsource);
+ free(newdest);
+ return PAM_BUF_ERR;
+ }
+ pointedlen = readlink(newsource, pointed, size);
+ if (pointedlen < 0) break;
+ if (pointedlen < size) break;
+ free(pointed);
+ size *= 2;
+ }
+ }
+ if (pointedlen < 0)
+ free(pointed);
+ else
+ pointed[pointedlen] = 0;
+#else
+ char pointed[PATH_MAX];
+ memset(pointed, 0, sizeof(pointed));
+
+ pointedlen = readlink(newsource, pointed, sizeof(pointed) - 1);
+#endif
+
+ if (pointedlen >= 0) {
+ if(symlink(pointed, newdest) == 0)
+ {
+ if (lchown(newdest, pwd->pw_uid, pwd->pw_gid) != 0)
+ {
+ pam_syslog(NULL, LOG_DEBUG,
+ "unable to change perms on link %s: %m", newdest);
+ closedir(d);
+#ifndef PATH_MAX
+ free(pointed);
+ free(newsource);
+ free(newdest);
+#endif
+ return PAM_PERM_DENIED;
+ }
+ }
+#ifndef PATH_MAX
+ free(pointed);
+#endif
+ }
+#ifndef PATH_MAX
+ free(newsource); newsource = NULL;
+ free(newdest); newdest = NULL;
+#endif
+ continue;
+ }
+
+ /* If it's not a regular file, it's probably not a good idea to create
+ * the new device node, FIFO, or whatever it is. */
+ if (!S_ISREG(st.st_mode))
+ {
+#ifndef PATH_MAX
+ free(newsource); newsource = NULL;
+ free(newdest); newdest = NULL;
+#endif
+ continue;
+ }
+
+ /* Open the source file */
+ if ((srcfd = open(newsource, O_RDONLY)) < 0 || fstat(srcfd, &st) != 0)
+ {
+ pam_syslog(NULL, LOG_DEBUG,
+ "unable to open or stat src file %s: %m", newsource);
+ if (srcfd >= 0)
+ close(srcfd);
+ closedir(d);
+
+#ifndef PATH_MAX
+ free(newsource); newsource = NULL;
+ free(newdest); newdest = NULL;
+#endif
+
+ return PAM_PERM_DENIED;
+ }
+
+ /* Open the dest file */
+ if ((destfd = open(newdest, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0)
+ {
+ pam_syslog(NULL, LOG_DEBUG,
+ "unable to open dest file %s: %m", newdest);
+ close(srcfd);
+ closedir(d);
+
+#ifndef PATH_MAX
+ free(newsource); newsource = NULL;
+ free(newdest); newdest = NULL;
+#endif
+ return PAM_PERM_DENIED;
+ }
+
+ /* Set the proper ownership and permissions for the module. We make
+ the file a+w and then mask it with the set mask. This preserves
+ execute bits */
+ if (fchmod(destfd, (st.st_mode | 0222) & (~u_mask)) != 0 ||
+ fchown(destfd, pwd->pw_uid, pwd->pw_gid) != 0)
+ {
+ pam_syslog(NULL, LOG_DEBUG,
+ "unable to change perms on copy %s: %m", newdest);
+ close(srcfd);
+ close(destfd);
+ closedir(d);
+
+#ifndef PATH_MAX
+ free(newsource); newsource = NULL;
+ free(newdest); newdest = NULL;
+#endif
+
+ return PAM_PERM_DENIED;
+ }
+
+ /* Copy the file */
+ do
+ {
+ res = pam_modutil_read(srcfd, remark, sizeof(remark));
+
+ if (res == 0)
+ continue;
+
+ if (res > 0) {
+ if (pam_modutil_write(destfd, remark, res) == res)
+ continue;
+ }
+
+ /* If we get here, pam_modutil_read returned a -1 or
+ pam_modutil_write returned something unexpected. */
+ pam_syslog(NULL, LOG_DEBUG, "unable to perform IO: %m");
+ close(srcfd);
+ close(destfd);
+ closedir(d);
+
+#ifndef PATH_MAX
+ free(newsource); newsource = NULL;
+ free(newdest); newdest = NULL;
+#endif
+
+ return PAM_PERM_DENIED;
+ }
+ while (res != 0);
+ close(srcfd);
+ close(destfd);
+
+#ifndef PATH_MAX
+ free(newsource); newsource = NULL;
+ free(newdest); newdest = NULL;
+#endif
+
+ }
+ closedir(d);
+
+ retval = PAM_SUCCESS;
+
+ go_out:
+
+ if (chmod(dest, 0777 & (~u_mask)) != 0 ||
+ chown(dest, pwd->pw_uid, pwd->pw_gid) != 0)
+ {
+ pam_syslog(NULL, LOG_DEBUG,
+ "unable to change perms on directory %s: %m", dest);
+ return PAM_PERM_DENIED;
+ }
+
+ return retval;
+}
+
+static int
+create_homedir_helper(const struct passwd *_pwd,
+ const char *_skeldir, const char *_homedir)
+{
+ int retval = PAM_SESSION_ERR;
+
+ retval = create_homedir(_pwd, _skeldir, _homedir);
+
+ if (chmod(_homedir, home_mode) != 0)
+ {
+ pam_syslog(NULL, LOG_DEBUG,
+ "unable to change perms on home directory %s: %m", _homedir);
+ return PAM_PERM_DENIED;
+ }
+
+ return retval;
+}
+
+static int
+make_parent_dirs(char *dir, int make)
+{
+ int rc = PAM_SUCCESS;
+ char *cp = strrchr(dir, '/');
+ struct stat st;
+
+ if (!cp)
+ return rc;
+
+ if (cp != dir) {
+ *cp = '\0';
+ if (stat(dir, &st) && errno == ENOENT)
+ rc = make_parent_dirs(dir, 1);
+ *cp = '/';
+
+ if (rc != PAM_SUCCESS)
+ return rc;
+ }
+
+ if (make && mkdir(dir, 0755) && errno != EEXIST) {
+ pam_syslog(NULL, LOG_ERR, "unable to create directory %s: %m", dir);
+ return PAM_PERM_DENIED;
+ }
+
+ return rc;
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct passwd *pwd;
+ struct stat st;
+ char *eptr;
+
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s <username> [<umask> [<skeldir> [<home_mode>]]]\n", argv[0]);
+ return PAM_SESSION_ERR;
+ }
+
+ pwd = getpwnam(argv[1]);
+ if (pwd == NULL) {
+ pam_syslog(NULL, LOG_ERR, "User unknown.");
+ return PAM_USER_UNKNOWN;
+ }
+
+ if (argc >= 3) {
+ errno = 0;
+ u_mask = strtoul(argv[2], &eptr, 0);
+ if (errno != 0 || *eptr != '\0') {
+ pam_syslog(NULL, LOG_ERR, "Bogus umask value %s", argv[2]);
+ return PAM_SESSION_ERR;
+ }
+ }
+
+ if (argc >= 4) {
+ if (strlen(argv[3]) >= sizeof(skeldir)) {
+ pam_syslog(NULL, LOG_ERR, "Too long skeldir path.");
+ return PAM_SESSION_ERR;
+ }
+ strcpy(skeldir, argv[3]);
+ }
+
+ if (argc >= 5) {
+ errno = 0;
+ home_mode = strtoul(argv[4], &eptr, 0);
+ if (errno != 0 || *eptr != '\0') {
+ pam_syslog(NULL, LOG_ERR, "Bogus home_mode value %s", argv[4]);
+ return PAM_SESSION_ERR;
+ }
+ }
+
+ if (home_mode == 0)
+ home_mode = 0777 & ~u_mask;
+
+ /* Stat the home directory, if something exists then we assume it is
+ correct and return a success */
+ if (stat(pwd->pw_dir, &st) == 0)
+ return PAM_SUCCESS;
+
+ if (make_parent_dirs(pwd->pw_dir, 0) != PAM_SUCCESS)
+ return PAM_PERM_DENIED;
+
+ return create_homedir_helper(pwd, skeldir, pwd->pw_dir);
+}
diff --git a/modules/pam_mkhomedir/pam_mkhomedir.8 b/modules/pam_mkhomedir/pam_mkhomedir.8
new file mode 100644
index 0000000..b8a4754
--- /dev/null
+++ b/modules/pam_mkhomedir/pam_mkhomedir.8
@@ -0,0 +1,135 @@
+'\" t
+.\" Title: pam_mkhomedir
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_MKHOMEDIR" "8" "09/03/2021" "Linux-PAM Manual" "Linux-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_mkhomedir \- PAM module to create users home directory
+.SH "SYNOPSIS"
+.HP \w'\fBpam_mkhomedir\&.so\fR\ 'u
+\fBpam_mkhomedir\&.so\fR [silent] [debug] [umask=\fImode\fR] [skel=\fIskeldir\fR]
+.SH "DESCRIPTION"
+.PP
+The pam_mkhomedir PAM module will create a users home directory if it does not exist when the session begins\&. This allows users to be present in central database (such as NIS, kerberos or LDAP) without using a distributed file system or pre\-creating a large number of directories\&. The skeleton directory (usually
+/etc/skel/) is used to copy default files and also sets a umask for the creation\&.
+.PP
+The new users home directory will not be removed after logout of the user\&.
+.SH "OPTIONS"
+.PP
+\fBsilent\fR
+.RS 4
+Don\*(Aqt print informative messages\&.
+.RE
+.PP
+\fBdebug\fR
+.RS 4
+Turns on debugging via
+\fBsyslog\fR(3)\&.
+.RE
+.PP
+\fBumask=\fR\fB\fImask\fR\fR
+.RS 4
+The file mode creation mask is set to
+\fImask\fR\&. The default value of mask is 0022\&. If this option is not specified, then the permissions of created user home directory is set to the value of
+\fBHOME_MODE\fR
+configuration item from
+/etc/login\&.defs\&. If there is no such configuration item then the value is computed from the value of
+\fBUMASK\fR
+in the same file\&. If there is no such configuration option either the default value of 0755 is used for the mode\&.
+.RE
+.PP
+\fBskel=\fR\fB\fI/path/to/skel/directory\fR\fR
+.RS 4
+Indicate an alternative
+skel
+directory to override the default
+/etc/skel\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+Only the
+\fBsession\fR
+module type is provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_PERM_DENIED
+.RS 4
+Not enough permissions to create the new directory or read the skel directory\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+User not known to the underlying authentication module\&.
+.RE
+.PP
+PAM_SUCCESS
+.RS 4
+Environment variables were set\&.
+.RE
+.SH "FILES"
+.PP
+/etc/skel
+.RS 4
+Default skel directory
+.RE
+.SH "EXAMPLES"
+.PP
+A sample /etc/pam\&.d/login file:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ auth requisite pam_securetty\&.so
+ auth sufficient pam_ldap\&.so
+ auth required pam_unix\&.so
+ auth required pam_nologin\&.so
+ account sufficient pam_ldap\&.so
+ account required pam_unix\&.so
+ password required pam_unix\&.so
+ session required pam_mkhomedir\&.so skel=/etc/skel/ umask=0022
+ session required pam_unix\&.so
+ session optional pam_lastlog\&.so
+ session optional pam_mail\&.so standard
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.PP
+\fBpam.d\fR(5),
+\fBpam\fR(8)\&.
+.SH "AUTHOR"
+.PP
+pam_mkhomedir was written by Jason Gunthorpe <jgg@debian\&.org>\&.
diff --git a/modules/pam_mkhomedir/pam_mkhomedir.8.xml b/modules/pam_mkhomedir/pam_mkhomedir.8.xml
new file mode 100644
index 0000000..1010906
--- /dev/null
+++ b/modules/pam_mkhomedir/pam_mkhomedir.8.xml
@@ -0,0 +1,219 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+
+<refentry id='pam_mkhomedir'>
+
+ <refmeta>
+ <refentrytitle>pam_mkhomedir</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id='pam_mkhomedir-name'>
+ <refname>pam_mkhomedir</refname>
+ <refpurpose>
+ PAM module to create users home directory
+ </refpurpose>
+ </refnamediv>
+
+<!-- body begins here -->
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_mkhomedir-cmdsynopsis">
+ <command>pam_mkhomedir.so</command>
+ <arg choice="opt">
+ silent
+ </arg>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ umask=<replaceable>mode</replaceable>
+ </arg>
+ <arg choice="opt">
+ skel=<replaceable>skeldir</replaceable>
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1 id="pam_mkhomedir-description">
+ <title>DESCRIPTION</title>
+ <para>
+ The pam_mkhomedir PAM module will create a users home directory
+ if it does not exist when the session begins. This allows users
+ to be present in central database (such as NIS, kerberos or LDAP)
+ without using a distributed file system or pre-creating a large
+ number of directories. The skeleton directory (usually
+ <filename>/etc/skel/</filename>) is used to copy default files
+ and also sets a umask for the creation.
+ </para>
+ <para>
+ The new users home directory will not be removed after logout
+ of the user.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_mkhomedir-options">
+ <title>OPTIONS</title>
+ <variablelist>
+
+ <varlistentry>
+ <term>
+ <option>silent</option>
+ </term>
+ <listitem>
+ <para>
+ Don't print informative messages.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Turns on debugging via
+ <citerefentry>
+ <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>umask=<replaceable>mask</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The file mode creation mask is set to
+ <replaceable>mask</replaceable>. The default value of mask
+ is 0022. If this option is not specified, then the permissions
+ of created user home directory is set to the value of
+ <option>HOME_MODE</option> configuration item from
+ <filename>/etc/login.defs</filename>. If there is no such
+ configuration item then the value is computed from the
+ value of <option>UMASK</option> in the same file. If
+ there is no such configuration option either the default
+ value of 0755 is used for the mode.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>skel=<replaceable>/path/to/skel/directory</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Indicate an alternative <filename>skel</filename> directory
+ to override the default <filename>/etc/skel</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_mkhomedir-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ Only the <option>session</option> module type is provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_mkhomedir-return_values">
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory buffer error.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_PERM_DENIED</term>
+ <listitem>
+ <para>
+ Not enough permissions to create the new directory
+ or read the skel directory.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ User not known to the underlying authentication module.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Environment variables were set.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_mkhomedir-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/skel</filename></term>
+ <listitem>
+ <para>Default skel directory</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_mkhomedir-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ A sample /etc/pam.d/login file:
+ <programlisting>
+ auth requisite pam_securetty.so
+ auth sufficient pam_ldap.so
+ auth required pam_unix.so
+ auth required pam_nologin.so
+ account sufficient pam_ldap.so
+ account required pam_unix.so
+ password required pam_unix.so
+ session required pam_mkhomedir.so skel=/etc/skel/ umask=0022
+ session required pam_unix.so
+ session optional pam_lastlog.so
+ session optional pam_mail.so standard
+ </programlisting>
+ </para>
+ </refsect1>
+
+
+ <refsect1 id="pam_mkhomedir-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_mkhomedir-author">
+ <title>AUTHOR</title>
+ <para>
+ pam_mkhomedir was written by Jason Gunthorpe &lt;jgg@debian.org&gt;.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_mkhomedir/pam_mkhomedir.c b/modules/pam_mkhomedir/pam_mkhomedir.c
new file mode 100644
index 0000000..48e578f
--- /dev/null
+++ b/modules/pam_mkhomedir/pam_mkhomedir.c
@@ -0,0 +1,267 @@
+/* PAM Make Home Dir module
+
+ This module will create a users home directory if it does not exist
+ when the session begins. This allows users to be present in central
+ database (such as nis, kerb or ldap) without using a distributed
+ file system or pre-creating a large number of directories.
+
+ Here is a sample /etc/pam.d/login file for Debian GNU/Linux
+ 2.1:
+
+ auth requisite pam_securetty.so
+ auth sufficient pam_ldap.so
+ auth required pam_unix.so
+ auth optional pam_group.so
+ auth optional pam_mail.so
+ account requisite pam_time.so
+ account sufficient pam_ldap.so
+ account required pam_unix.so
+ session required pam_mkhomedir.so skel=/etc/skel/ umask=0022
+ session required pam_unix.so
+ session optional pam_lastlog.so
+ password required pam_unix.so
+
+ Released under the GNU LGPL version 2 or later
+ Copyright (c) Red Hat, Inc. 2009
+ Originally written by Jason Gunthorpe <jgg@debian.org> Feb 1999
+ Structure taken from pam_lastlogin by Andrew Morgan
+ <morgan@parc.power.net> 1996
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#include <signal.h>
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+
+#include "pam_cc_compat.h"
+#include "pam_inline.h"
+
+/* argument parsing */
+#define MKHOMEDIR_DEBUG 020 /* be verbose about things */
+#define MKHOMEDIR_QUIET 040 /* keep quiet about things */
+
+#define LOGIN_DEFS "/etc/login.defs"
+#define UMASK_DEFAULT "0022"
+
+struct options_t {
+ int ctrl;
+ const char *umask;
+ const char *skeldir;
+};
+typedef struct options_t options_t;
+
+static void
+_pam_parse (const pam_handle_t *pamh, int flags, int argc, const char **argv,
+ options_t *opt)
+{
+ opt->ctrl = 0;
+ opt->umask = NULL;
+ opt->skeldir = "/etc/skel";
+
+ /* does the application require quiet? */
+ if ((flags & PAM_SILENT) == PAM_SILENT)
+ opt->ctrl |= MKHOMEDIR_QUIET;
+
+ /* step through arguments */
+ for (; argc-- > 0; ++argv)
+ {
+ const char *str;
+
+ if (!strcmp(*argv, "silent")) {
+ opt->ctrl |= MKHOMEDIR_QUIET;
+ } else if (!strcmp(*argv, "debug")) {
+ opt->ctrl |= MKHOMEDIR_DEBUG;
+ } else if ((str = pam_str_skip_prefix(*argv, "umask=")) != NULL) {
+ opt->umask = str;
+ } else if ((str = pam_str_skip_prefix(*argv, "skel=")) != NULL) {
+ opt->skeldir = str;
+ } else {
+ pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
+ }
+ }
+}
+
+static char*
+_pam_conv_str_umask_to_homemode(const char *umask)
+{
+ unsigned int m = 0;
+ char tmp[5];
+
+ m = 0777 & ~strtoul(umask, NULL, 8);
+ (void) snprintf(tmp, sizeof(tmp), "0%o", m);
+ return strdup(tmp);
+}
+
+/* Do the actual work of creating a home dir */
+static int
+create_homedir (pam_handle_t *pamh, options_t *opt,
+ const char *user, const char *dir)
+{
+ int retval, child;
+ struct sigaction newsa, oldsa;
+ char *login_umask = NULL;
+ char *login_homemode = NULL;
+
+ /* Mention what is happening, if the notification fails that is OK */
+ if (!(opt->ctrl & MKHOMEDIR_QUIET))
+ pam_info(pamh, _("Creating directory '%s'."), dir);
+
+
+ D(("called."));
+
+ /*
+ * This code arranges that the demise of the child does not cause
+ * the application to receive a signal it is not expecting - which
+ * may kill the application or worse.
+ */
+ memset(&newsa, '\0', sizeof(newsa));
+ newsa.sa_handler = SIG_DFL;
+ sigaction(SIGCHLD, &newsa, &oldsa);
+
+ if (opt->ctrl & MKHOMEDIR_DEBUG) {
+ pam_syslog(pamh, LOG_DEBUG, "Executing mkhomedir_helper.");
+ }
+
+ /* fetch UMASK from /etc/login.defs if not in argv */
+ if (opt->umask == NULL) {
+ login_umask = pam_modutil_search_key(pamh, LOGIN_DEFS, "UMASK");
+ login_homemode = pam_modutil_search_key(pamh, LOGIN_DEFS, "HOME_MODE");
+ if (login_homemode == NULL) {
+ if (login_umask != NULL) {
+ login_homemode = _pam_conv_str_umask_to_homemode(login_umask);
+ } else {
+ login_homemode = _pam_conv_str_umask_to_homemode(UMASK_DEFAULT);
+ }
+ }
+ } else {
+ login_homemode = _pam_conv_str_umask_to_homemode(opt->umask);
+ }
+
+ /* fork */
+ child = fork();
+ if (child == 0) {
+ static char *envp[] = { NULL };
+ const char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL };
+
+ if (pam_modutil_sanitize_helper_fds(pamh, PAM_MODUTIL_PIPE_FD,
+ PAM_MODUTIL_PIPE_FD,
+ PAM_MODUTIL_PIPE_FD) < 0)
+ _exit(PAM_SYSTEM_ERR);
+
+ /* exec the mkhomedir helper */
+ args[0] = MKHOMEDIR_HELPER;
+ args[1] = user;
+ args[2] = opt->umask ? opt->umask : UMASK_DEFAULT;
+ args[3] = opt->skeldir;
+ args[4] = login_homemode;
+
+ DIAG_PUSH_IGNORE_CAST_QUAL;
+ execve(MKHOMEDIR_HELPER, (char **)args, envp);
+ DIAG_POP_IGNORE_CAST_QUAL;
+
+ /* should not get here: exit with error */
+ D(("helper binary is not available"));
+ _exit(PAM_SYSTEM_ERR);
+ } else if (child > 0) {
+ int rc;
+ while ((rc=waitpid(child, &retval, 0)) < 0 && errno == EINTR);
+ if (rc < 0) {
+ pam_syslog(pamh, LOG_ERR, "waitpid failed: %m");
+ retval = PAM_SYSTEM_ERR;
+ } else if (!WIFEXITED(retval)) {
+ pam_syslog(pamh, LOG_ERR, "mkhomedir_helper abnormal exit: %d", retval);
+ retval = PAM_SYSTEM_ERR;
+ } else {
+ retval = WEXITSTATUS(retval);
+ }
+ } else {
+ D(("fork failed"));
+ pam_syslog(pamh, LOG_ERR, "fork failed: %m");
+ retval = PAM_SYSTEM_ERR;
+ }
+
+ sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */
+
+ if (opt->ctrl & MKHOMEDIR_DEBUG) {
+ pam_syslog(pamh, LOG_DEBUG, "mkhomedir_helper returned %d", retval);
+ }
+
+ if (retval != PAM_SUCCESS && !(opt->ctrl & MKHOMEDIR_QUIET)) {
+ pam_error(pamh, _("Unable to create and initialize directory '%s'."),
+ dir);
+ }
+
+ free(login_umask);
+ free(login_homemode);
+
+ D(("returning %d", retval));
+ return retval;
+}
+
+/* --- authentication management functions (only) --- */
+
+int
+pam_sm_open_session (pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ int retval;
+ options_t opt;
+ const void *user;
+ const struct passwd *pwd;
+ struct stat St;
+
+ /* Parse the flag values */
+ _pam_parse(pamh, flags, argc, argv, &opt);
+
+ /* Determine the user name so we can get the home directory */
+ retval = pam_get_item(pamh, PAM_USER, &user);
+ if (retval != PAM_SUCCESS || user == NULL || *(const char *)user == '\0')
+ {
+ pam_syslog(pamh, LOG_NOTICE, "Cannot obtain the user name.");
+ return PAM_USER_UNKNOWN;
+ }
+
+ /* Get the password entry */
+ pwd = pam_modutil_getpwnam (pamh, user);
+ if (pwd == NULL)
+ {
+ pam_syslog(pamh, LOG_NOTICE, "User unknown.");
+ D(("couldn't identify user %s", user));
+ return PAM_USER_UNKNOWN;
+ }
+
+ /* Stat the home directory, if something exists then we assume it is
+ correct and return a success*/
+ if (stat(pwd->pw_dir, &St) == 0) {
+ if (opt.ctrl & MKHOMEDIR_DEBUG) {
+ pam_syslog(pamh, LOG_DEBUG, "Home directory %s already exists.",
+ pwd->pw_dir);
+ }
+ return PAM_SUCCESS;
+ }
+
+ return create_homedir(pamh, &opt, user, pwd->pw_dir);
+}
+
+/* Ignore */
+int pam_sm_close_session (pam_handle_t * pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
diff --git a/modules/pam_mkhomedir/tst-pam_mkhomedir b/modules/pam_mkhomedir/tst-pam_mkhomedir
new file mode 100755
index 0000000..5447883
--- /dev/null
+++ b/modules/pam_mkhomedir/tst-pam_mkhomedir
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_mkhomedir.so
diff --git a/modules/pam_mkhomedir/tst-pam_mkhomedir-retval.c b/modules/pam_mkhomedir/tst-pam_mkhomedir-retval.c
new file mode 100644
index 0000000..451d2e5
--- /dev/null
+++ b/modules/pam_mkhomedir/tst-pam_mkhomedir-retval.c
@@ -0,0 +1,110 @@
+/*
+ * Check pam_mkhomedir return values.
+ *
+ * Copyright (c) 2020 Dmitry V. Levin <ldv@altlinux.org>
+ */
+
+#include "test_assert.h"
+
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <sys/stat.h>
+#include <security/pam_appl.h>
+
+#define MODULE_NAME "pam_mkhomedir"
+#define TEST_NAME "tst-" MODULE_NAME "-retval"
+
+static const char service_file[] = TEST_NAME ".service";
+static const char user_empty[] = "";
+static const char user_missing[] = ":";
+static struct pam_conv conv;
+
+int
+main(void)
+{
+ pam_handle_t *pamh = NULL;
+ FILE *fp;
+ struct passwd *pw;
+ struct stat st;
+ char cwd[PATH_MAX];
+
+ ASSERT_NE(NULL, getcwd(cwd, sizeof(cwd)));
+
+ /* PAM_USER_UNKNOWN */
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so\n"
+ "account required %s/.libs/%s.so\n"
+ "password required %s/.libs/%s.so\n"
+ "session required %s/.libs/%s.so\n",
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, user_empty,
+ &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
+ ASSERT_EQ(PAM_USER_UNKNOWN, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, user_missing,
+ &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
+ ASSERT_EQ(PAM_USER_UNKNOWN, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ /* PAM_SUCCESS */
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so debug\n"
+ "account required %s/.libs/%s.so debug\n"
+ "password required %s/.libs/%s.so debug\n"
+ "session required %s/.libs/%s.so debug\n",
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME));
+ ASSERT_EQ(0, fclose(fp));
+
+ if ((pw = getpwuid(geteuid())) != NULL &&
+ pw->pw_dir != NULL &&
+ stat(pw->pw_dir, &st) == 0 &&
+ (st.st_mode & S_IFMT) == S_IFDIR) {
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, pw->pw_name,
+ &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+ }
+
+ ASSERT_EQ(0, unlink(service_file));
+
+ return 0;
+}
diff --git a/modules/pam_motd/Makefile.am b/modules/pam_motd/Makefile.am
new file mode 100644
index 0000000..956dad2
--- /dev/null
+++ b/modules/pam_motd/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_motd.8
+endif
+XMLS = README.xml pam_motd.8.xml
+dist_check_SCRIPTS = tst-pam_motd
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_motd.la
+pam_motd_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_motd/Makefile.in b/modules/pam_motd/Makefile.in
new file mode 100644
index 0000000..14ab6bb
--- /dev/null
+++ b/modules/pam_motd/Makefile.in
@@ -0,0 +1,1150 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_motd
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_motd_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_motd_la_SOURCES = pam_motd.c
+pam_motd_la_OBJECTS = pam_motd.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_motd.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_motd.c
+DIST_SOURCES = pam_motd.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_motd.8
+XMLS = README.xml pam_motd.8.xml
+dist_check_SCRIPTS = tst-pam_motd
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_motd.la
+pam_motd_la_LIBADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_motd/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_motd/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_motd.la: $(pam_motd_la_OBJECTS) $(pam_motd_la_DEPENDENCIES) $(EXTRA_pam_motd_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_motd_la_OBJECTS) $(pam_motd_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_motd.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_motd.log: tst-pam_motd
+ @p='tst-pam_motd'; \
+ b='tst-pam_motd'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_motd.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_motd.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_motd/README b/modules/pam_motd/README
new file mode 100644
index 0000000..01bc64e
--- /dev/null
+++ b/modules/pam_motd/README
@@ -0,0 +1,82 @@
+pam_motd — Display the motd file
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+pam_motd is a PAM module that can be used to display arbitrary motd (message of
+the day) files after a successful login. By default, pam_motd shows files in
+the following locations:
+
+/etc/motd
+/run/motd
+/usr/lib/motd
+/etc/motd.d/
+/run/motd.d/
+/usr/lib/motd.d/
+
+Each message size is limited to 64KB.
+
+If /etc/motd does not exist, then /run/motd is shown. If /run/motd does not
+exist, then /usr/lib/motd is shown.
+
+Similar overriding behavior applies to the directories. Files in /etc/motd.d/
+override files with the same name in /run/motd.d/ and /usr/lib/motd.d/. Files
+in /run/motd.d/ override files with the same name in /usr/lib/motd.d/.
+
+Files in the directories listed above are displayed in lexicographic order by
+name. Moreover, the files are filtered by reading them with the credentials of
+the target user authenticating on the system.
+
+To silence a message, a symbolic link with target /dev/null may be placed in /
+etc/motd.d with the same filename as the message to be silenced. Example:
+Creating a symbolic link as follows silences /usr/lib/motd.d/my_motd.
+
+ln -s /dev/null /etc/motd.d/my_motd
+
+The MOTD_SHOWN=pam environment variable is set after showing the motd files,
+even when all of them were silenced using symbolic links.
+
+OPTIONS
+
+motd=/path/filename
+
+ The /path/filename file is displayed as message of the day. Multiple paths
+ to try can be specified as a colon-separated list. By default this option
+ is set to /etc/motd:/run/motd:/usr/lib/motd.
+
+motd_dir=/path/dirname.d
+
+ The /path/dirname.d directory is scanned and each file contained inside of
+ it is displayed. Multiple directories to scan can be specified as a
+ colon-separated list. By default this option is set to /etc/motd.d:/run/
+ motd.d:/usr/lib/motd.d.
+
+When no options are given, the default behavior applies for both options.
+Specifying either option (or both) will disable the default behavior for both
+options.
+
+EXAMPLES
+
+The suggested usage for /etc/pam.d/login is:
+
+session optional pam_motd.so
+
+
+To use a motd file from a different location:
+
+session optional pam_motd.so motd=/elsewhere/motd
+
+
+To use a motd file from elsewhere, along with a corresponding .d directory:
+
+session optional pam_motd.so motd=/elsewhere/motd motd_dir=/elsewhere/motd.d
+
+
+AUTHOR
+
+pam_motd was written by Ben Collins <bcollins@debian.org>.
+
+The motd_dir= option was added by Allison Karlitskaya
+<allison.karlitskaya@redhat.com>.
+
diff --git a/modules/pam_motd/README.xml b/modules/pam_motd/README.xml
new file mode 100644
index 0000000..779e4d1
--- /dev/null
+++ b/modules/pam_motd/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_motd.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_motd.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_motd-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_motd.8.xml" xpointer='xpointer(//refsect1[@id = "pam_motd-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_motd.8.xml" xpointer='xpointer(//refsect1[@id = "pam_motd-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_motd.8.xml" xpointer='xpointer(//refsect1[@id = "pam_motd-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_motd.8.xml" xpointer='xpointer(//refsect1[@id = "pam_motd-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_motd/pam_motd.8 b/modules/pam_motd/pam_motd.8
new file mode 100644
index 0000000..a211d6e
--- /dev/null
+++ b/modules/pam_motd/pam_motd.8
@@ -0,0 +1,195 @@
+'\" t
+.\" Title: pam_motd
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_MOTD" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_motd \- Display the motd file
+.SH "SYNOPSIS"
+.HP \w'\fBpam_motd\&.so\fR\ 'u
+\fBpam_motd\&.so\fR [motd=\fI/path/filename\fR] [motd_dir=\fI/path/dirname\&.d\fR]
+.SH "DESCRIPTION"
+.PP
+pam_motd is a PAM module that can be used to display arbitrary motd (message of the day) files after a successful login\&. By default, pam_motd shows files in the following locations:
+.PP
+.RS 4
+/etc/motd
+.RE
+.RS 4
+/run/motd
+.RE
+.RS 4
+/usr/lib/motd
+.RE
+.RS 4
+/etc/motd\&.d/
+.RE
+.RS 4
+/run/motd\&.d/
+.RE
+.RS 4
+/usr/lib/motd\&.d/
+.RE
+.PP
+Each message size is limited to 64KB\&.
+.PP
+If
+/etc/motd
+does not exist, then
+/run/motd
+is shown\&. If
+/run/motd
+does not exist, then
+/usr/lib/motd
+is shown\&.
+.PP
+Similar overriding behavior applies to the directories\&. Files in
+/etc/motd\&.d/
+override files with the same name in
+/run/motd\&.d/
+and
+/usr/lib/motd\&.d/\&. Files in
+/run/motd\&.d/
+override files with the same name in
+/usr/lib/motd\&.d/\&.
+.PP
+Files in the directories listed above are displayed in lexicographic order by name\&. Moreover, the files are filtered by reading them with the credentials of the target user authenticating on the system\&.
+.PP
+To silence a message, a symbolic link with target
+/dev/null
+may be placed in
+/etc/motd\&.d
+with the same filename as the message to be silenced\&. Example: Creating a symbolic link as follows silences
+/usr/lib/motd\&.d/my_motd\&.
+.PP
+\fBln \-s /dev/null /etc/motd\&.d/my_motd\fR
+.PP
+The
+\fBMOTD_SHOWN=pam\fR
+environment variable is set after showing the motd files, even when all of them were silenced using symbolic links\&.
+.SH "OPTIONS"
+.PP
+\fBmotd=\fR\fB\fI/path/filename\fR\fR
+.RS 4
+The
+/path/filename
+file is displayed as message of the day\&. Multiple paths to try can be specified as a colon\-separated list\&. By default this option is set to
+/etc/motd:/run/motd:/usr/lib/motd\&.
+.RE
+.PP
+\fBmotd_dir=\fR\fB\fI/path/dirname\&.d\fR\fR
+.RS 4
+The
+/path/dirname\&.d
+directory is scanned and each file contained inside of it is displayed\&. Multiple directories to scan can be specified as a colon\-separated list\&. By default this option is set to
+/etc/motd\&.d:/run/motd\&.d:/usr/lib/motd\&.d\&.
+.RE
+.PP
+When no options are given, the default behavior applies for both options\&. Specifying either option (or both) will disable the default behavior for both options\&.
+.SH "MODULE TYPES PROVIDED"
+.PP
+Only the
+\fBsession\fR
+module type is provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_ABORT
+.RS 4
+Not all relevant data or options could be obtained\&.
+.RE
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_IGNORE
+.RS 4
+This is the default return value of this module\&.
+.RE
+.SH "EXAMPLES"
+.PP
+The suggested usage for
+/etc/pam\&.d/login
+is:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+session optional pam_motd\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To use a
+motd
+file from a different location:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+session optional pam_motd\&.so motd=/elsewhere/motd
+
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+To use a
+motd
+file from elsewhere, along with a corresponding
+\&.d
+directory:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+session optional pam_motd\&.so motd=/elsewhere/motd motd_dir=/elsewhere/motd\&.d
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.PP
+\fBmotd\fR(5),
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_motd was written by Ben Collins <bcollins@debian\&.org>\&.
+.PP
+The
+\fBmotd_dir=\fR
+option was added by Allison Karlitskaya <allison\&.karlitskaya@redhat\&.com>\&.
diff --git a/modules/pam_motd/pam_motd.8.xml b/modules/pam_motd/pam_motd.8.xml
new file mode 100644
index 0000000..0afd4c9
--- /dev/null
+++ b/modules/pam_motd/pam_motd.8.xml
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_motd">
+
+ <refmeta>
+ <refentrytitle>pam_motd</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_motd-name">
+ <refname>pam_motd</refname>
+ <refpurpose>Display the motd file</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_motd-cmdsynopsis">
+ <command>pam_motd.so</command>
+ <arg choice="opt">
+ motd=<replaceable>/path/filename</replaceable>
+ </arg>
+ <arg choice="opt">
+ motd_dir=<replaceable>/path/dirname.d</replaceable>
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_motd-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ pam_motd is a PAM module that can be used to display
+ arbitrary motd (message of the day) files after a successful
+ login. By default, pam_motd shows files in the
+ following locations:
+ </para>
+ <para>
+ <simplelist type='vert'>
+ <member><filename>/etc/motd</filename></member>
+ <member><filename>/run/motd</filename></member>
+ <member><filename>/usr/lib/motd</filename></member>
+ <member><filename>/etc/motd.d/</filename></member>
+ <member><filename>/run/motd.d/</filename></member>
+ <member><filename>/usr/lib/motd.d/</filename></member>
+ </simplelist>
+ </para>
+ <para>
+ Each message size is limited to 64KB.
+ </para>
+ <para>
+ If <filename>/etc/motd</filename> does not exist,
+ then <filename>/run/motd</filename> is shown. If
+ <filename>/run/motd</filename> does not exist, then
+ <filename>/usr/lib/motd</filename> is shown.
+ </para>
+ <para>
+ Similar overriding behavior applies to the directories.
+ Files in <filename>/etc/motd.d/</filename> override files
+ with the same name in <filename>/run/motd.d/</filename> and
+ <filename>/usr/lib/motd.d/</filename>. Files in <filename>/run/motd.d/</filename>
+ override files with the same name in <filename>/usr/lib/motd.d/</filename>.
+ </para>
+ <para>
+ Files in the directories listed above are displayed in lexicographic
+ order by name. Moreover, the files are filtered by reading them with the
+ credentials of the target user authenticating on the system.
+ </para>
+ <para>
+ To silence a message,
+ a symbolic link with target <filename>/dev/null</filename>
+ may be placed in <filename>/etc/motd.d</filename> with
+ the same filename as the message to be silenced. Example:
+ Creating a symbolic link as follows silences <filename>/usr/lib/motd.d/my_motd</filename>.
+ </para>
+ <para>
+ <command>ln -s /dev/null /etc/motd.d/my_motd</command>
+ </para>
+ <para>
+ The <emphasis remap='B'>MOTD_SHOWN=pam</emphasis> environment variable
+ is set after showing the motd files, even when all of them were silenced
+ using symbolic links.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_motd-options">
+
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>motd=<replaceable>/path/filename</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The <filename>/path/filename</filename> file is displayed
+ as message of the day. Multiple paths to try can be
+ specified as a colon-separated list. By default this option
+ is set to <filename>/etc/motd:/run/motd:/usr/lib/motd</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>motd_dir=<replaceable>/path/dirname.d</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The <filename>/path/dirname.d</filename> directory is scanned
+ and each file contained inside of it is displayed. Multiple
+ directories to scan can be specified as a colon-separated list.
+ By default this option is set to <filename>/etc/motd.d:/run/motd.d:/usr/lib/motd.d</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+ When no options are given, the default behavior applies for both
+ options. Specifying either option (or both) will disable the
+ default behavior for both options.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_motd-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ Only the <option>session</option> module type is provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_motd-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_ABORT</term>
+ <listitem>
+ <para>
+ Not all relevant data or options could be obtained.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory buffer error.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ This is the default return value of this module.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_motd-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ The suggested usage for <filename>/etc/pam.d/login</filename> is:
+ <programlisting>
+session optional pam_motd.so
+ </programlisting>
+ </para>
+ <para>
+ To use a <filename>motd</filename> file from a different location:
+ <programlisting>
+session optional pam_motd.so motd=/elsewhere/motd
+ </programlisting>
+ </para>
+ <para>
+ To use a <filename>motd</filename> file from elsewhere, along with a
+ corresponding <filename>.d</filename> directory:
+ <programlisting>
+session optional pam_motd.so motd=/elsewhere/motd motd_dir=/elsewhere/motd.d
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_motd-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>motd</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_motd-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_motd was written by Ben Collins &lt;bcollins@debian.org&gt;.
+ </para>
+ <para>
+ The <option>motd_dir=</option> option was added by
+ Allison Karlitskaya &lt;allison.karlitskaya@redhat.com&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_motd/pam_motd.c b/modules/pam_motd/pam_motd.c
new file mode 100644
index 0000000..6ac8cba
--- /dev/null
+++ b/modules/pam_motd/pam_motd.c
@@ -0,0 +1,445 @@
+/*
+ * pam_motd module
+ *
+ * Modified for pam_motd by Ben Collins <bcollins@debian.org>
+ * Written by Michael K. Johnson <johnsonm@redhat.com> 1996/10/24
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <pwd.h>
+#include <syslog.h>
+#include <errno.h>
+
+#include <security/_pam_macros.h>
+#include <security/pam_ext.h>
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+#include "pam_inline.h"
+
+#define DEFAULT_MOTD "/etc/motd:/run/motd:/usr/lib/motd"
+#define DEFAULT_MOTD_D "/etc/motd.d:/run/motd.d:/usr/lib/motd.d"
+
+/* --- session management functions (only) --- */
+
+int
+pam_sm_close_session (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_IGNORE;
+}
+
+static const char default_motd[] = DEFAULT_MOTD;
+static const char default_motd_dir[] = DEFAULT_MOTD_D;
+
+static void try_to_display_fd(pam_handle_t *pamh, int fd)
+{
+ struct stat st;
+ char *mtmp = NULL;
+
+ /* fill in message buffer with contents of motd */
+ if ((fstat(fd, &st) < 0) || !st.st_size || st.st_size > 0x10000)
+ return;
+
+ if (!(mtmp = malloc(st.st_size+1)))
+ return;
+
+ if (pam_modutil_read(fd, mtmp, st.st_size) == st.st_size) {
+ if (mtmp[st.st_size-1] == '\n')
+ mtmp[st.st_size-1] = '\0';
+ else
+ mtmp[st.st_size] = '\0';
+
+ pam_info (pamh, "%s", mtmp);
+ }
+
+ _pam_drop(mtmp);
+}
+
+/*
+ * Split a DELIM-separated string ARG into an array.
+ * Outputs a newly allocated array of strings OUT_ARG_SPLIT
+ * and the number of strings OUT_NUM_STRS.
+ * Returns 0 in case of error, 1 in case of success.
+ */
+static int pam_split_string(const pam_handle_t *pamh, char *arg, char delim,
+ char ***out_arg_split, unsigned int *out_num_strs)
+{
+ char *arg_extracted = NULL;
+ const char *arg_ptr = arg;
+ char **arg_split = NULL;
+ char delim_str[2];
+ unsigned int i = 0;
+ unsigned int num_strs = 0;
+ int retval = 0;
+
+ delim_str[0] = delim;
+ delim_str[1] = '\0';
+
+ if (arg == NULL) {
+ goto out;
+ }
+
+ while (arg_ptr != NULL) {
+ num_strs++;
+ arg_ptr = strchr(arg_ptr + sizeof(const char), delim);
+ }
+
+ arg_split = calloc(num_strs, sizeof(*arg_split));
+ if (arg_split == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "failed to allocate string array");
+ goto out;
+ }
+
+ arg_extracted = strtok_r(arg, delim_str, &arg);
+ while (arg_extracted != NULL && i < num_strs) {
+ arg_split[i++] = arg_extracted;
+ arg_extracted = strtok_r(NULL, delim_str, &arg);
+ }
+
+ retval = 1;
+
+ out:
+ *out_num_strs = num_strs;
+ *out_arg_split = arg_split;
+
+ return retval;
+}
+
+/* Join A_STR and B_STR, inserting a "/" between them if one is not already trailing
+ * in A_STR or beginning B_STR. A pointer to a newly allocated string holding the
+ * joined string is returned in STRP_OUT.
+ * Returns -1 in case of error, or the number of bytes in the joined string in
+ * case of success. */
+static int join_dir_strings(char **strp_out, const char *a_str, const char *b_str)
+{
+ int has_sep = 0;
+ int retval = -1;
+ char *join_strp = NULL;
+
+ if (strp_out == NULL || a_str == NULL || b_str == NULL) {
+ goto out;
+ }
+ if (strlen(a_str) == 0) {
+ goto out;
+ }
+
+ has_sep = (a_str[strlen(a_str) - 1] == '/') || (b_str[0] == '/');
+
+ retval = asprintf(&join_strp, "%s%s%s", a_str,
+ (has_sep == 1) ? "" : "/", b_str);
+
+ if (retval < 0) {
+ goto out;
+ }
+
+ *strp_out = join_strp;
+
+ out:
+ return retval;
+}
+
+static int compare_strings(const void *a, const void *b)
+{
+ const char *a_str = *(const char * const *)a;
+ const char *b_str = *(const char * const *)b;
+
+ if (a_str == NULL && b_str == NULL) {
+ return 0;
+ }
+ else if (a_str == NULL) {
+ return -1;
+ }
+ else if (b_str == NULL) {
+ return 1;
+ }
+ else {
+ return strcmp(a_str, b_str);
+ }
+}
+
+static int filter_dirents(const struct dirent *d)
+{
+ return (d->d_type == DT_REG || d->d_type == DT_LNK);
+}
+
+static void try_to_display_directories_with_overrides(pam_handle_t *pamh,
+ char **motd_dir_path_split, unsigned int num_motd_dirs, int report_missing)
+{
+ struct dirent ***dirscans = NULL;
+ unsigned int *dirscans_sizes = NULL;
+ unsigned int dirscans_size_total = 0;
+ char **dirnames_all = NULL;
+ unsigned int i;
+ int i_dirnames = 0;
+
+ if (pamh == NULL || motd_dir_path_split == NULL) {
+ goto out;
+ }
+ if (num_motd_dirs < 1) {
+ goto out;
+ }
+
+ if ((dirscans = calloc(num_motd_dirs, sizeof(*dirscans))) == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "failed to allocate dirent arrays");
+ goto out;
+ }
+ if ((dirscans_sizes = calloc(num_motd_dirs, sizeof(*dirscans_sizes))) == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "failed to allocate dirent array sizes");
+ goto out;
+ }
+
+ for (i = 0; i < num_motd_dirs; i++) {
+ int rv;
+ rv = scandir(motd_dir_path_split[i], &(dirscans[i]),
+ filter_dirents, alphasort);
+ if (rv < 0) {
+ if (errno != ENOENT || report_missing) {
+ pam_syslog(pamh, LOG_ERR, "error scanning directory %s: %m",
+ motd_dir_path_split[i]);
+ }
+ } else {
+ dirscans_sizes[i] = rv;
+ }
+ dirscans_size_total += dirscans_sizes[i];
+ }
+
+ if (dirscans_size_total == 0)
+ goto out;
+
+ /* Allocate space for all file names found in the directories, including duplicates. */
+ if ((dirnames_all = calloc(dirscans_size_total, sizeof(*dirnames_all))) == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "failed to allocate dirname array");
+ goto out;
+ }
+
+ for (i = 0; i < num_motd_dirs; i++) {
+ unsigned int j;
+
+ for (j = 0; j < dirscans_sizes[i]; j++) {
+ dirnames_all[i_dirnames] = dirscans[i][j]->d_name;
+ i_dirnames++;
+ }
+ }
+
+ qsort(dirnames_all, dirscans_size_total,
+ sizeof(const char *), compare_strings);
+
+ for (i = 0; i < dirscans_size_total; i++) {
+ unsigned int j;
+
+ if (dirnames_all[i] == NULL) {
+ continue;
+ }
+
+ /* Skip duplicate file names. */
+ if (i > 0 && strcmp(dirnames_all[i], dirnames_all[i - 1]) == 0) {
+ continue;
+ }
+
+ for (j = 0; j < num_motd_dirs; j++) {
+ char *abs_path = NULL;
+ int fd;
+
+ if (join_dir_strings(&abs_path, motd_dir_path_split[j],
+ dirnames_all[i]) < 0 || abs_path == NULL) {
+ continue;
+ }
+
+ fd = open(abs_path, O_RDONLY, 0);
+ _pam_drop(abs_path);
+
+ if (fd >= 0) {
+ try_to_display_fd(pamh, fd);
+ close(fd);
+
+ /* We displayed a file, skip to the next file name. */
+ break;
+ }
+ }
+ }
+
+ out:
+ _pam_drop(dirnames_all);
+ if (dirscans_sizes != NULL) {
+ for (i = 0; i < num_motd_dirs; i++) {
+ unsigned int j;
+
+ for (j = 0; j < dirscans_sizes[i]; j++)
+ _pam_drop(dirscans[i][j]);
+ _pam_drop(dirscans[i]);
+ }
+ _pam_drop(dirscans_sizes);
+ }
+ _pam_drop(dirscans);
+}
+
+static int drop_privileges(pam_handle_t *pamh, struct pam_modutil_privs *privs)
+{
+ struct passwd *pw;
+ const char *username;
+ int retval;
+
+ retval = pam_get_user(pamh, &username, NULL);
+
+ if (retval == PAM_SUCCESS) {
+ pw = pam_modutil_getpwnam (pamh, username);
+ } else {
+ return PAM_SESSION_ERR;
+ }
+
+ if (pw == NULL || pam_modutil_drop_priv(pamh, privs, pw)) {
+ return PAM_SESSION_ERR;
+ }
+
+ return PAM_SUCCESS;
+}
+
+static int try_to_display(pam_handle_t *pamh, char **motd_path_split,
+ unsigned int num_motd_paths,
+ char **motd_dir_path_split,
+ unsigned int num_motd_dir_paths, int report_missing)
+{
+ PAM_MODUTIL_DEF_PRIVS(privs);
+
+ if (drop_privileges(pamh, &privs) != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR, "Unable to drop privileges");
+ return PAM_SESSION_ERR;
+ }
+
+ if (motd_path_split != NULL) {
+ unsigned int i;
+
+ for (i = 0; i < num_motd_paths; i++) {
+ int fd = open(motd_path_split[i], O_RDONLY, 0);
+
+ if (fd >= 0) {
+ try_to_display_fd(pamh, fd);
+ close(fd);
+
+ /* We found and displayed a file,
+ * move onto next filename.
+ */
+ break;
+ }
+ }
+ }
+
+ if (motd_dir_path_split != NULL) {
+ try_to_display_directories_with_overrides(pamh,
+ motd_dir_path_split,
+ num_motd_dir_paths,
+ report_missing);
+ }
+
+ if (pam_modutil_regain_priv(pamh, &privs)) {
+ pam_syslog(pamh, LOG_ERR, "Unable to regain privileges");
+ return PAM_SESSION_ERR;
+ }
+
+ return PAM_SUCCESS;
+}
+
+int pam_sm_open_session(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ int retval = PAM_IGNORE;
+ const char *motd_path = NULL;
+ char *motd_path_copy = NULL;
+ unsigned int num_motd_paths = 0;
+ char **motd_path_split = NULL;
+ const char *motd_dir_path = NULL;
+ char *motd_dir_path_copy = NULL;
+ unsigned int num_motd_dir_paths = 0;
+ char **motd_dir_path_split = NULL;
+ int report_missing;
+
+ if (flags & PAM_SILENT) {
+ return retval;
+ }
+
+ for (; argc-- > 0; ++argv) {
+ const char *str;
+ if ((str = pam_str_skip_prefix(*argv, "motd=")) != NULL) {
+
+ motd_path = str;
+ if (*motd_path != '\0') {
+ D(("set motd path: %s", motd_path));
+ } else {
+ motd_path = NULL;
+ pam_syslog(pamh, LOG_ERR,
+ "motd= specification missing argument - ignored");
+ }
+ }
+ else if ((str = pam_str_skip_prefix(*argv, "motd_dir=")) != NULL) {
+
+ motd_dir_path = str;
+ if (*motd_dir_path != '\0') {
+ D(("set motd.d path: %s", motd_dir_path));
+ } else {
+ motd_dir_path = NULL;
+ pam_syslog(pamh, LOG_ERR,
+ "motd_dir= specification missing argument - ignored");
+ }
+ }
+ else
+ pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
+ }
+
+ if (motd_path == NULL && motd_dir_path == NULL) {
+ motd_path = default_motd;
+ motd_dir_path = default_motd_dir;
+ report_missing = 0;
+ } else {
+ report_missing = 1;
+ }
+
+ if (motd_path != NULL) {
+ motd_path_copy = strdup(motd_path);
+ }
+
+ if (motd_path_copy != NULL) {
+ if (pam_split_string(pamh, motd_path_copy, ':',
+ &motd_path_split, &num_motd_paths) == 0) {
+ goto out;
+ }
+ }
+
+ if (motd_dir_path != NULL) {
+ motd_dir_path_copy = strdup(motd_dir_path);
+ }
+
+ if (motd_dir_path_copy != NULL) {
+ if (pam_split_string(pamh, motd_dir_path_copy, ':',
+ &motd_dir_path_split, &num_motd_dir_paths) == 0) {
+ goto out;
+ }
+ }
+
+ retval = try_to_display(pamh, motd_path_split, num_motd_paths,
+ motd_dir_path_split, num_motd_dir_paths,
+ report_missing);
+
+ out:
+ _pam_drop(motd_path_copy);
+ _pam_drop(motd_path_split);
+ _pam_drop(motd_dir_path_copy);
+ _pam_drop(motd_dir_path_split);
+
+ if (retval == PAM_SUCCESS) {
+ retval = pam_putenv(pamh, "MOTD_SHOWN=pam");
+ return retval == PAM_SUCCESS ? PAM_IGNORE : retval;
+ } else {
+ return retval;
+ }
+}
+
+/* end of module definition */
diff --git a/modules/pam_motd/tst-pam_motd b/modules/pam_motd/tst-pam_motd
new file mode 100755
index 0000000..155e230
--- /dev/null
+++ b/modules/pam_motd/tst-pam_motd
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_motd.so
diff --git a/modules/pam_namespace/Makefile.am b/modules/pam_namespace/Makefile.am
new file mode 100644
index 0000000..47cc38e
--- /dev/null
+++ b/modules/pam_namespace/Makefile.am
@@ -0,0 +1,48 @@
+#
+# Copyright (c) 2009 Thorsten Kukuk <kukuk@thkukuk.de>
+# Copyright (c) 2006 Red Hat, Inc.
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = namespace.conf.5 pam_namespace.8 pam_namespace_helper.8
+endif
+XMLS = README.xml namespace.conf.5.xml pam_namespace.8.xml pam_namespace_helper.8.xml
+dist_check_SCRIPTS = tst-pam_namespace
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+namespaceddir = $(SCONFIGDIR)/namespace.d
+servicedir = $(systemdunitdir)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DSECURECONF_DIR=\"$(SCONFIGDIR)/\" $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+noinst_HEADERS = md5.h pam_namespace.h argv_parse.h
+
+securelib_LTLIBRARIES = pam_namespace.la
+pam_namespace_la_SOURCES = pam_namespace.c md5.c argv_parse.c
+pam_namespace_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBSELINUX@
+
+dist_secureconf_DATA = namespace.conf
+dist_secureconf_SCRIPTS = namespace.init
+service_DATA = pam_namespace.service
+
+install-data-local:
+ mkdir -p $(DESTDIR)$(namespaceddir)
+
+sbin_SCRIPTS = pam_namespace_helper
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_namespace/Makefile.in b/modules/pam_namespace/Makefile.in
new file mode 100644
index 0000000..e21c836
--- /dev/null
+++ b/modules/pam_namespace/Makefile.in
@@ -0,0 +1,1348 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2009 Thorsten Kukuk <kukuk@thkukuk.de>
+# Copyright (c) 2006 Red Hat, Inc.
+#
+
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_namespace
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(dist_secureconf_SCRIPTS) $(am__dist_noinst_DATA_DIST) \
+ $(dist_secureconf_DATA) $(noinst_HEADERS) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = pam_namespace_helper pam_namespace.service
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" \
+ "$(DESTDIR)$(secureconfdir)" "$(DESTDIR)$(sbindir)" \
+ "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" \
+ "$(DESTDIR)$(secureconfdir)" "$(DESTDIR)$(servicedir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_namespace_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+am_pam_namespace_la_OBJECTS = pam_namespace.lo md5.lo argv_parse.lo
+pam_namespace_la_OBJECTS = $(am_pam_namespace_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+SCRIPTS = $(dist_secureconf_SCRIPTS) $(sbin_SCRIPTS)
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/argv_parse.Plo ./$(DEPDIR)/md5.Plo \
+ ./$(DEPDIR)/pam_namespace.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(pam_namespace_la_SOURCES)
+DIST_SOURCES = $(pam_namespace_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man5dir = $(mandir)/man5
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA) $(dist_secureconf_DATA) $(service_DATA)
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(srcdir)/pam_namespace.service.in \
+ $(srcdir)/pam_namespace_helper.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = namespace.conf.5 pam_namespace.8 pam_namespace_helper.8
+XMLS = README.xml namespace.conf.5.xml pam_namespace.8.xml pam_namespace_helper.8.xml
+dist_check_SCRIPTS = tst-pam_namespace
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+namespaceddir = $(SCONFIGDIR)/namespace.d
+servicedir = $(systemdunitdir)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DSECURECONF_DIR=\"$(SCONFIGDIR)/\" $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+noinst_HEADERS = md5.h pam_namespace.h argv_parse.h
+securelib_LTLIBRARIES = pam_namespace.la
+pam_namespace_la_SOURCES = pam_namespace.c md5.c argv_parse.c
+pam_namespace_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBSELINUX@
+dist_secureconf_DATA = namespace.conf
+dist_secureconf_SCRIPTS = namespace.init
+service_DATA = pam_namespace.service
+sbin_SCRIPTS = pam_namespace_helper
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_namespace/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_namespace/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+pam_namespace_helper: $(top_builddir)/config.status $(srcdir)/pam_namespace_helper.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+pam_namespace.service: $(top_builddir)/config.status $(srcdir)/pam_namespace.service.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_namespace.la: $(pam_namespace_la_OBJECTS) $(pam_namespace_la_DEPENDENCIES) $(EXTRA_pam_namespace_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_namespace_la_OBJECTS) $(pam_namespace_la_LIBADD) $(LIBS)
+install-dist_secureconfSCRIPTS: $(dist_secureconf_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_secureconf_SCRIPTS)'; test -n "$(secureconfdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(secureconfdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(secureconfdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n' \
+ -e 'h;s|.*|.|' \
+ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+ if (++n[d] == $(am__install_max)) { \
+ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+ else { print "f", d "/" $$4, $$1 } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(secureconfdir)$$dir'"; \
+ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(secureconfdir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-dist_secureconfSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_secureconf_SCRIPTS)'; test -n "$(secureconfdir)" || exit 0; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 's,.*/,,;$(transform)'`; \
+ dir='$(DESTDIR)$(secureconfdir)'; $(am__uninstall_files_from_dir)
+install-sbinSCRIPTS: $(sbin_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ @list='$(sbin_SCRIPTS)'; test -n "$(sbindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n' \
+ -e 'h;s|.*|.|' \
+ -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+ if (++n[d] == $(am__install_max)) { \
+ print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+ else { print "f", d "/" $$4, $$1 } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
+ $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-sbinSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sbin_SCRIPTS)'; test -n "$(sbindir)" || exit 0; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 's,.*/,,;$(transform)'`; \
+ dir='$(DESTDIR)$(sbindir)'; $(am__uninstall_files_from_dir)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/argv_parse.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_namespace.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man5: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man5dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.5[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man5:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man5dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.5[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir)
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+install-dist_secureconfDATA: $(dist_secureconf_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_secureconf_DATA)'; test -n "$(secureconfdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(secureconfdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(secureconfdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(secureconfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(secureconfdir)" || exit $$?; \
+ done
+
+uninstall-dist_secureconfDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_secureconf_DATA)'; test -n "$(secureconfdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(secureconfdir)'; $(am__uninstall_files_from_dir)
+install-serviceDATA: $(service_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(service_DATA)'; test -n "$(servicedir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(servicedir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(servicedir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(servicedir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(servicedir)" || exit $$?; \
+ done
+
+uninstall-serviceDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(service_DATA)'; test -n "$(servicedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(servicedir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_namespace.log: tst-pam_namespace
+ @p='tst-pam_namespace'; \
+ b='tst-pam_namespace'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(SCRIPTS) $(MANS) $(DATA) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(secureconfdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(secureconfdir)" "$(DESTDIR)$(servicedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/argv_parse.Plo
+ -rm -f ./$(DEPDIR)/md5.Plo
+ -rm -f ./$(DEPDIR)/pam_namespace.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-data-local install-dist_secureconfDATA \
+ install-dist_secureconfSCRIPTS install-man \
+ install-securelibLTLIBRARIES install-serviceDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-sbinSCRIPTS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man5 install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/argv_parse.Plo
+ -rm -f ./$(DEPDIR)/md5.Plo
+ -rm -f ./$(DEPDIR)/pam_namespace.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-dist_secureconfDATA \
+ uninstall-dist_secureconfSCRIPTS uninstall-man \
+ uninstall-sbinSCRIPTS uninstall-securelibLTLIBRARIES \
+ uninstall-serviceDATA
+
+uninstall-man: uninstall-man5 uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-data-local install-dist_secureconfDATA \
+ install-dist_secureconfSCRIPTS install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-man5 \
+ install-man8 install-pdf install-pdf-am install-ps \
+ install-ps-am install-sbinSCRIPTS install-securelibLTLIBRARIES \
+ install-serviceDATA install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \
+ uninstall uninstall-am uninstall-dist_secureconfDATA \
+ uninstall-dist_secureconfSCRIPTS uninstall-man uninstall-man5 \
+ uninstall-man8 uninstall-sbinSCRIPTS \
+ uninstall-securelibLTLIBRARIES uninstall-serviceDATA
+
+.PRECIOUS: Makefile
+
+
+install-data-local:
+ mkdir -p $(DESTDIR)$(namespaceddir)
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_namespace/README b/modules/pam_namespace/README
new file mode 100644
index 0000000..106a073
--- /dev/null
+++ b/modules/pam_namespace/README
@@ -0,0 +1,227 @@
+pam_namespace — PAM module for configuring namespace for a session
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+The pam_namespace PAM module sets up a private namespace for a session with
+polyinstantiated directories. A polyinstantiated directory provides a different
+instance of itself based on user name, or when using SELinux, user name,
+security context or both. If an executable script /etc/security/namespace.init
+exists, it is used to initialize the instance directory after it is set up and
+mounted on the polyinstantiated directory. The script receives the
+polyinstantiated directory path, the instance directory path, flag whether the
+instance directory was newly created (0 for no, 1 for yes), and the user name
+as its arguments.
+
+The pam_namespace module disassociates the session namespace from the parent
+namespace. Any mounts/unmounts performed in the parent namespace, such as
+mounting of devices, are not reflected in the session namespace. To propagate
+selected mount/unmount events from the parent namespace into the disassociated
+session namespace, an administrator may use the special shared-subtree feature.
+For additional information on shared-subtree feature, please refer to the mount
+(8) man page and the shared-subtree description at http://lwn.net/Articles/
+159077 and http://lwn.net/Articles/159092.
+
+OPTIONS
+
+debug
+
+ A lot of debug information is logged using syslog
+
+unmnt_remnt
+
+ For programs such as su and newrole, the login session has already setup a
+ polyinstantiated namespace. For these programs, polyinstantiation is
+ performed based on new user id or security context, however the command
+ first needs to undo the polyinstantiation performed by login. This argument
+ instructs the command to first undo previous polyinstantiation before
+ proceeding with new polyinstantiation based on new id/context
+
+unmnt_only
+
+ For trusted programs that want to undo any existing bind mounts and process
+ instance directories on their own, this argument allows them to unmount
+ currently mounted instance directories
+
+require_selinux
+
+ If selinux is not enabled, return failure
+
+gen_hash
+
+ Instead of using the security context string for the instance name,
+ generate and use its md5 hash.
+
+ignore_config_error
+
+ If a line in the configuration file corresponding to a polyinstantiated
+ directory contains format error, skip that line process the next line.
+ Without this option, pam will return an error to the calling program
+ resulting in termination of the session.
+
+ignore_instance_parent_mode
+
+ Instance parent directories by default are expected to have the restrictive
+ mode of 000. Using this option, an administrator can choose to ignore the
+ mode of the instance parent. This option should be used with caution as it
+ will reduce security and isolation goals of the polyinstantiation
+ mechanism.
+
+unmount_on_close
+
+ Explicitly unmount the polyinstantiated directories instead of relying on
+ automatic namespace destruction after the last process in a namespace
+ exits. This option should be used only in case it is ensured by other means
+ that there cannot be any processes running in the private namespace left
+ after the session close. It is also useful only in case there are multiple
+ pam session calls in sequence from the same process.
+
+use_current_context
+
+ Useful for services which do not change the SELinux context with setexeccon
+ call. The module will use the current SELinux context of the calling
+ process for the level and context polyinstantiation.
+
+use_default_context
+
+ Useful for services which do not use pam_selinux for changing the SELinux
+ context with setexeccon call. The module will use the default SELinux
+ context of the user for the level and context polyinstantiation.
+
+mount_private
+
+ This option can be used on systems where the / mount point or its submounts
+ are made shared (for example with a mount --make-rshared / command). The
+ module will mark the whole directory tree so any mount and unmount
+ operations in the polyinstantiation namespace are private. Normally the
+ pam_namespace will try to detect the shared / mount point and make the
+ polyinstantiated directories private automatically. This option has to be
+ used just when only a subtree is shared and / is not.
+
+ Note that mounts and unmounts done in the private namespace will not affect
+ the parent namespace if this option is used or when the shared / mount
+ point is autodetected.
+
+DESCRIPTION
+
+The pam_namespace.so module allows setup of private namespaces with
+polyinstantiated directories. Directories can be polyinstantiated based on user
+name or, in the case of SELinux, user name, sensitivity level or complete
+security context. If an executable script /etc/security/namespace.init exists,
+it is used to initialize the namespace every time an instance directory is set
+up and mounted. The script receives the polyinstantiated directory path and the
+instance directory path as its arguments.
+
+The /etc/security/namespace.conf file specifies which directories are
+polyinstantiated, how they are polyinstantiated, how instance directories would
+be named, and any users for whom polyinstantiation would not be performed.
+
+When someone logs in, the file namespace.conf is scanned. Comments are marked
+by # characters. Each non comment line represents one polyinstantiated
+directory. The fields are separated by spaces but can be quoted by " characters
+also escape sequences \b, \n, and \t are recognized. The fields are as follows:
+
+polydir instance_prefix method list_of_uids
+
+The first field, polydir, is the absolute pathname of the directory to
+polyinstantiate. The special string $HOME is replaced with the user's home
+directory, and $USER with the username. This field cannot be blank.
+
+The second field, instance_prefix is the string prefix used to build the
+pathname for the instantiation of <polydir>. Depending on the polyinstantiation
+method it is then appended with "instance differentiation string" to generate
+the final instance directory path. This directory is created if it did not
+exist already, and is then bind mounted on the <polydir> to provide an instance
+of <polydir> based on the <method> column. The special string $HOME is replaced
+with the user's home directory, and $USER with the username. This field cannot
+be blank.
+
+The third field, method, is the method used for polyinstantiation. It can take
+these values; "user" for polyinstantiation based on user name, "level" for
+polyinstantiation based on process MLS level and user name, "context" for
+polyinstantiation based on process security context and user name, "tmpfs" for
+mounting tmpfs filesystem as an instance dir, and "tmpdir" for creating
+temporary directory as an instance dir which is removed when the user's session
+is closed. Methods "context" and "level" are only available with SELinux. This
+field cannot be blank.
+
+The fourth field, list_of_uids, is a comma separated list of user names for
+whom the polyinstantiation is not performed. If left blank, polyinstantiation
+will be performed for all users. If the list is preceded with a single "~"
+character, polyinstantiation is performed only for users in the list.
+
+The method field can contain also following optional flags separated by :
+characters.
+
+create=mode,owner,group - create the polyinstantiated directory. The mode,
+owner and group parameters are optional. The default for mode is determined by
+umask, the default owner is the user whose session is opened, the default group
+is the primary group of the user.
+
+iscript=path - path to the instance directory init script. The base directory
+for relative paths is /etc/security/namespace.d.
+
+noinit - instance directory init script will not be executed.
+
+shared - the instance directories for "context" and "level" methods will not
+contain the user name and will be shared among all users.
+
+mntopts=value - value of this flag is passed to the mount call when the tmpfs
+mount is done. It allows for example the specification of the maximum size of
+the tmpfs instance that is created by the mount call. In addition to options
+specified in the tmpfs(5) manual the nosuid, noexec, and nodev flags can be
+used to respectively disable setuid bit effect, disable running executables,
+and disable devices to be interpreted on the mounted tmpfs filesystem.
+
+The directory where polyinstantiated instances are to be created, must exist
+and must have, by default, the mode of 0000. The requirement that the instance
+parent be of mode 0000 can be overridden with the command line option
+ignore_instance_parent_mode
+
+In case of context or level polyinstantiation the SELinux context which is used
+for polyinstantiation is the context used for executing a new process as
+obtained by getexeccon. This context must be set by the calling application or
+pam_selinux.so module. If this context is not set the polyinstatiation will be
+based just on user name.
+
+The "instance differentiation string" is <user name> for "user" method and
+<user name>_<raw directory context> for "context" and "level" methods. If the
+whole string is too long the end of it is replaced with md5sum of itself. Also
+when command line option gen_hash is used the whole string is replaced with
+md5sum of itself.
+
+EXAMPLES
+
+These are some example lines which might be specified in /etc/security/
+namespace.conf.
+
+
+      # The following three lines will polyinstantiate /tmp,
+      # /var/tmp and user's home directories. /tmp and /var/tmp
+      # will be polyinstantiated based on the security level
+      # as well as user name, whereas home directory will be
+      # polyinstantiated based on the full security context and user name.
+      # Polyinstantiation will not be performed for user root
+      # and adm for directories /tmp and /var/tmp, whereas home
+      # directories will be polyinstantiated for all users.
+      #
+      # Note that instance directories do not have to reside inside
+      # the polyinstantiated directory. In the examples below,
+      # instances of /tmp will be created in /tmp-inst directory,
+      # where as instances of /var/tmp and users home directories
+      # will reside within the directories that are being
+      # polyinstantiated.
+      #
+      /tmp     /tmp-inst/               level      root,adm
+      /var/tmp /var/tmp/tmp-inst/    level      root,adm
+      $HOME    $HOME/$USER.inst/inst- context
+    
+
+For the <service>s you need polyinstantiation (login for example) put the
+following line in /etc/pam.d/<service> as the last line for session group:
+
+session required pam_namespace.so [arguments]
+
+This module also depends on pam_selinux.so setting the context.
+
diff --git a/modules/pam_namespace/README.xml b/modules/pam_namespace/README.xml
new file mode 100644
index 0000000..4ef99c9
--- /dev/null
+++ b/modules/pam_namespace/README.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamns SYSTEM "pam_namespace.8.xml">
+-->
+<!--
+<!ENTITY nsconf SYSTEM "namespace.conf.5.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_namespace.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_namespace-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_namespace.8.xml" xpointer='xpointer(//refsect1[@id = "pam_namespace-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_namespace.8.xml" xpointer='xpointer(//refsect1[@id = "pam_namespace-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="namespace.conf.5.xml" xpointer='xpointer(//refsect1[@id = "namespace.conf-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="namespace.conf.5.xml" xpointer='xpointer(//refsect1[@id = "namespace.conf-examples"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_namespace/argv_parse.c b/modules/pam_namespace/argv_parse.c
new file mode 100644
index 0000000..4051054
--- /dev/null
+++ b/modules/pam_namespace/argv_parse.c
@@ -0,0 +1,172 @@
+/*
+ * argv_parse.c --- utility function for parsing a string into a
+ * argc, argv array.
+ *
+ * This file defines a function argv_parse() which parsing a
+ * passed-in string, handling double quotes and backslashes, and
+ * creates an allocated argv vector which can be freed using the
+ * argv_free() function.
+ *
+ * See argv_parse.h for the formal definition of the functions.
+ *
+ * Copyright 1999 by Theodore Ts'o.
+ *
+ * Permission to use, copy, modify, and distribute this software for
+ * any purpose with or without fee is hereby granted, provided that
+ * the above copyright notice and this permission notice appear in all
+ * copies. THE SOFTWARE IS PROVIDED "AS IS" AND THEODORE TS'O (THE
+ * AUTHOR) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. (Isn't
+ * it sick that the U.S. culture of lawsuit-happy lawyers requires
+ * this kind of disclaimer?)
+ *
+ * Version 1.1, modified 2/27/1999
+ */
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include "argv_parse.h"
+
+#define STATE_WHITESPACE 1
+#define STATE_TOKEN 2
+#define STATE_QUOTED 3
+
+/*
+ * Returns 0 on success, -1 on failure.
+ */
+int argv_parse(const char *in_buf, int *ret_argc, char ***ret_argv)
+{
+ int argc = 0, max_argc = 0;
+ char **argv, **new_argv, *buf, ch;
+ const char *cp = NULL;
+ char *outcp = NULL;
+ int state = STATE_WHITESPACE;
+
+ buf = malloc(strlen(in_buf)+1);
+ if (!buf)
+ return -1;
+
+ argv = NULL;
+ outcp = buf;
+ for (cp = in_buf; (ch = *cp); cp++) {
+ if (state == STATE_WHITESPACE) {
+ if (isspace((int) ch))
+ continue;
+ /* Not whitespace, so start a new token */
+ state = STATE_TOKEN;
+ if (argc >= max_argc) {
+ max_argc += 3;
+ new_argv = realloc(argv,
+ (max_argc+1)*sizeof(char *));
+ if (!new_argv) {
+ if (argv) free(argv);
+ free(buf);
+ return -1;
+ }
+ argv = new_argv;
+ }
+ argv[argc++] = outcp;
+ }
+ if (state == STATE_QUOTED) {
+ if (ch == '"')
+ state = STATE_TOKEN;
+ else
+ *outcp++ = ch;
+ continue;
+ }
+ /* Must be processing characters in a word */
+ if (isspace((int) ch)) {
+ /*
+ * Terminate the current word and start
+ * looking for the beginning of the next word.
+ */
+ *outcp++ = 0;
+ state = STATE_WHITESPACE;
+ continue;
+ }
+ if (ch == '"') {
+ state = STATE_QUOTED;
+ continue;
+ }
+ if (ch == '\\') {
+ ch = *++cp;
+ switch (ch) {
+ case '\0':
+ ch = '\\'; cp--; break;
+ case 'n':
+ ch = '\n'; break;
+ case 't':
+ ch = '\t'; break;
+ case 'b':
+ ch = '\b'; break;
+ }
+ }
+ *outcp++ = ch;
+ }
+ if (state != STATE_WHITESPACE)
+ *outcp++ = '\0';
+ if (ret_argv) {
+ if (argv == NULL) {
+ free(buf);
+ if ((argv=malloc(sizeof(char *))) == NULL)
+ return -1;
+ }
+ argv[argc] = NULL;
+ *ret_argv = argv;
+ } else {
+ free(buf);
+ free(argv);
+ }
+ if (ret_argc)
+ *ret_argc = argc;
+ return 0;
+}
+
+void argv_free(char **argv)
+{
+ if (argv) {
+ if (*argv)
+ free(*argv);
+ free(argv);
+ }
+}
+
+#ifdef DEBUG_ARGV_PARSE
+/*
+ * For debugging
+ */
+
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ int ac, ret;
+ char **av, **cpp;
+ char buf[256];
+
+ while (!feof(stdin)) {
+ if (fgets(buf, sizeof(buf), stdin) == NULL)
+ break;
+ ret = argv_parse(buf, &ac, &av);
+ if (ret != 0) {
+ printf("Argv_parse returned %d!\n", ret);
+ continue;
+ }
+ printf("Argv_parse returned %d arguments...\n", ac);
+ for (cpp = av; *cpp; cpp++) {
+ if (cpp != av)
+ printf(", ");
+ printf("'%s'", *cpp);
+ }
+ printf("\n");
+ argv_free(av);
+ }
+ exit(0);
+}
+#endif
diff --git a/modules/pam_namespace/argv_parse.h b/modules/pam_namespace/argv_parse.h
new file mode 100644
index 0000000..c7878fc
--- /dev/null
+++ b/modules/pam_namespace/argv_parse.h
@@ -0,0 +1,43 @@
+/*
+ * argv_parse.h --- header file for the argv parser.
+ *
+ * This file defines the interface for the functions argv_parse() and
+ * argv_free().
+ *
+ ***********************************************************************
+ * int argv_parse(char *in_buf, int *ret_argc, char ***ret_argv)
+ *
+ * This function takes as its first argument a string which it will
+ * parse into an argv argument vector, with each white-space separated
+ * word placed into its own slot in the argv. This function handles
+ * double quotes and backslashes so that the parsed words can contain
+ * special characters. The count of the number words found in the
+ * parsed string, as well as the argument vector, are returned into
+ * ret_argc and ret_argv, respectively.
+ ***********************************************************************
+ * extern void argv_free(char **argv);
+ *
+ * This function frees the argument vector created by argv_parse().
+ ***********************************************************************
+ *
+ * Copyright 1999 by Theodore Ts'o.
+ *
+ * Permission to use, copy, modify, and distribute this software for
+ * any purpose with or without fee is hereby granted, provided that
+ * the above copyright notice and this permission notice appear in all
+ * copies. THE SOFTWARE IS PROVIDED "AS IS" AND THEODORE TS'O (THE
+ * AUTHOR) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. (Isn't
+ * it sick that the U.S. culture of lawsuit-happy lawyers requires
+ * this kind of disclaimer?)
+ *
+ * Version 1.1, modified 2/27/1999
+ */
+
+extern int argv_parse(const char *in_buf, int *ret_argc, char ***ret_argv);
+extern void argv_free(char **argv);
diff --git a/modules/pam_namespace/md5.c b/modules/pam_namespace/md5.c
new file mode 100644
index 0000000..22e41ee
--- /dev/null
+++ b/modules/pam_namespace/md5.c
@@ -0,0 +1,261 @@
+/*
+ * $Id$
+ *
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ *
+ */
+
+#include "md5.h"
+#include <string.h>
+
+#define MD5Name(x) x
+
+#ifdef WORDS_BIGENDIAN
+typedef unsigned char PAM_ATTRIBUTE_ALIGNED(4) uint8_aligned;
+
+static void byteReverse(uint8_aligned *buf, unsigned longs);
+
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+static void byteReverse(uint8_aligned *buf, unsigned longs)
+{
+ uint32 t;
+ do {
+ t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
+ ((unsigned) buf[1] << 8 | buf[0]);
+ *(uint32 *) buf = t;
+ buf += 4;
+ } while (--longs);
+}
+#else
+#define byteReverse(buf, len) /* Nothing */
+#endif
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void MD5Name(MD5Init)(struct MD5Context *ctx)
+{
+ ctx->buf.i[0] = 0x67452301U;
+ ctx->buf.i[1] = 0xefcdab89U;
+ ctx->buf.i[2] = 0x98badcfeU;
+ ctx->buf.i[3] = 0x10325476U;
+
+ ctx->bits[0] = 0;
+ ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void MD5Name(MD5Update)(struct MD5Context *ctx, unsigned const char *buf, unsigned len)
+{
+ uint32 t;
+
+ /* Update bitcount */
+
+ t = ctx->bits[0];
+ if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
+ ctx->bits[1]++; /* Carry from low to high */
+ ctx->bits[1] += len >> 29;
+
+ t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
+
+ /* Handle any leading odd-sized chunks */
+
+ if (t) {
+ unsigned char *p = ctx->in.c + t;
+
+ t = 64 - t;
+ if (len < t) {
+ memcpy(p, buf, len);
+ return;
+ }
+ memcpy(p, buf, t);
+ byteReverse(ctx->in.c, 16);
+ MD5Name(MD5Transform)(ctx->buf.i, ctx->in.i);
+ buf += t;
+ len -= t;
+ }
+ /* Process data in 64-byte chunks */
+
+ while (len >= 64) {
+ memcpy(ctx->in.c, buf, 64);
+ byteReverse(ctx->in.c, 16);
+ MD5Name(MD5Transform)(ctx->buf.i, ctx->in.i);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+
+ memcpy(ctx->in.c, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void MD5Name(MD5Final)(unsigned char digest[16], struct MD5Context *ctx)
+{
+ unsigned count;
+ unsigned char *p;
+
+ /* Compute number of bytes mod 64 */
+ count = (ctx->bits[0] >> 3) & 0x3F;
+
+ /* Set the first char of padding to 0x80. This is safe since there is
+ always at least one byte free */
+ p = ctx->in.c + count;
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 64 bytes */
+ count = 64 - 1 - count;
+
+ /* Pad out to 56 mod 64 */
+ if (count < 8) {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ memset(p, 0, count);
+ byteReverse(ctx->in.c, 16);
+ MD5Name(MD5Transform)(ctx->buf.i, ctx->in.i);
+
+ /* Now fill the next block with 56 bytes */
+ memset(ctx->in.c, 0, 56);
+ } else {
+ /* Pad block to 56 bytes */
+ memset(p, 0, count - 8);
+ }
+ byteReverse(ctx->in.c, 14);
+
+ /* Append length in bits and transform */
+ memcpy(ctx->in.i + 14, ctx->bits, 2*sizeof(uint32));
+
+ MD5Name(MD5Transform)(ctx->buf.i, ctx->in.i);
+ byteReverse(ctx->buf.c, 4);
+ memcpy(digest, ctx->buf.c, 16);
+ memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
+}
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void MD5Name(MD5Transform)(uint32 buf[4], uint32 const in[16])
+{
+ register uint32 a, b, c, d;
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478U, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756U, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070dbU, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceeeU, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0fafU, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62aU, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613U, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501U, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8U, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7afU, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1U, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7beU, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122U, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193U, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438eU, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821U, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562U, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340U, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51U, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aaU, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105dU, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453U, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681U, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8U, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6U, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6U, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87U, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14edU, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905U, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8U, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9U, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8aU, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942U, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681U, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122U, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380cU, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44U, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9U, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60U, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70U, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6U, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127faU, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085U, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05U, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039U, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5U, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8U, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665U, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244U, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97U, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7U, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039U, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3U, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92U, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47dU, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1U, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4fU, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0U, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314U, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1U, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82U, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235U, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bbU, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391U, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+
+void MD5Name(MD5)(unsigned const char *buf, unsigned len, unsigned char digest[16])
+{
+ struct MD5Context ctx;
+ MD5Name(MD5Init)(&ctx);
+ MD5Name(MD5Update)(&ctx, buf, len);
+ MD5Name(MD5Final)(digest, &ctx);
+}
diff --git a/modules/pam_namespace/md5.h b/modules/pam_namespace/md5.h
new file mode 100644
index 0000000..501aab4
--- /dev/null
+++ b/modules/pam_namespace/md5.h
@@ -0,0 +1,36 @@
+
+#ifndef MD5_H
+#define MD5_H
+
+#include "pam_cc_compat.h"
+
+typedef unsigned int uint32;
+
+struct MD5Context {
+ union {
+ uint32 i[4];
+ unsigned char c[16] PAM_ATTRIBUTE_ALIGNED(4);
+ } buf;
+ uint32 bits[2];
+ union {
+ uint32 i[16];
+ unsigned char c[64] PAM_ATTRIBUTE_ALIGNED(4);
+ } in;
+};
+
+#define MD5_DIGEST_LENGTH 16
+
+void MD5Init(struct MD5Context *);
+void MD5Update(struct MD5Context *, unsigned const char *, unsigned);
+void MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], struct MD5Context *);
+void MD5Transform(uint32 buf[4], uint32 const in[MD5_DIGEST_LENGTH]);
+void MD5(unsigned const char *, unsigned, unsigned char digest[MD5_DIGEST_LENGTH]);
+
+
+/*
+ * This is needed to make RSAREF happy on some MS-DOS compilers.
+ */
+
+typedef struct MD5Context MD5_CTX;
+
+#endif /* MD5_H */
diff --git a/modules/pam_namespace/namespace.conf b/modules/pam_namespace/namespace.conf
new file mode 100644
index 0000000..75ec619
--- /dev/null
+++ b/modules/pam_namespace/namespace.conf
@@ -0,0 +1,31 @@
+# /etc/security/namespace.conf
+#
+# See /usr/share/doc/pam-*/txts/README.pam_namespace for more information.
+#
+# Uncommenting the following three lines will polyinstantiate
+# /tmp, /var/tmp and user's home directories. /tmp and /var/tmp will
+# be polyinstantiated based on the MLS level part of the security context as well as user
+# name, Polyinstantion will not be performed for user root and adm for directories
+# /tmp and /var/tmp, whereas home directories will be polyinstantiated for all users.
+# The user name and context is appended to the instance prefix.
+#
+# Note that instance directories do not have to reside inside the
+# polyinstantiated directory. In the examples below, instances of /tmp
+# will be created in /tmp-inst directory, where as instances of /var/tmp
+# and users home directories will reside within the directories that
+# are being polyinstantiated.
+#
+# Instance parent directories must exist for the polyinstantiation
+# mechanism to work. By default, they should be created with the mode
+# of 000. pam_namespace module will enforce this mode unless it
+# is explicitly called with an argument to ignore the mode of the
+# instance parent. System administrators should use this argument with
+# caution, as it will reduce security and isolation achieved by
+# polyinstantiation. The parent directories (except $HOME) are created
+# at boot by pam_namespace_helper, but in a live system, system
+# administrators should create the parent directories before enabling
+# them here.
+#
+#/tmp /tmp-inst/ level root,adm
+#/var/tmp /var/tmp/tmp-inst/ level root,adm
+#$HOME $HOME/$USER.inst/ level
diff --git a/modules/pam_namespace/namespace.conf.5 b/modules/pam_namespace/namespace.conf.5
new file mode 100644
index 0000000..ff122cb
--- /dev/null
+++ b/modules/pam_namespace/namespace.conf.5
@@ -0,0 +1,168 @@
+'\" t
+.\" Title: namespace.conf
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "NAMESPACE\&.CONF" "5" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+namespace.conf \- the namespace configuration file
+.SH "DESCRIPTION"
+.PP
+The
+\fIpam_namespace\&.so\fR
+module allows setup of private namespaces with polyinstantiated directories\&. Directories can be polyinstantiated based on user name or, in the case of SELinux, user name, sensitivity level or complete security context\&. If an executable script
+/etc/security/namespace\&.init
+exists, it is used to initialize the namespace every time an instance directory is set up and mounted\&. The script receives the polyinstantiated directory path and the instance directory path as its arguments\&.
+.PP
+The
+/etc/security/namespace\&.conf
+file specifies which directories are polyinstantiated, how they are polyinstantiated, how instance directories would be named, and any users for whom polyinstantiation would not be performed\&.
+.PP
+When someone logs in, the file
+namespace\&.conf
+is scanned\&. Comments are marked by
+\fI#\fR
+characters\&. Each non comment line represents one polyinstantiated directory\&. The fields are separated by spaces but can be quoted by
+\fI"\fR
+characters also escape sequences
+\fI\eb\fR,
+\fI\en\fR, and
+\fI\et\fR
+are recognized\&. The fields are as follows:
+.PP
+\fIpolydir\fR
+\fIinstance_prefix\fR
+\fImethod\fR
+\fIlist_of_uids\fR
+.PP
+The first field,
+\fIpolydir\fR, is the absolute pathname of the directory to polyinstantiate\&. The special string
+\fI$HOME\fR
+is replaced with the user\*(Aqs home directory, and
+\fI$USER\fR
+with the username\&. This field cannot be blank\&.
+.PP
+The second field,
+\fIinstance_prefix\fR
+is the string prefix used to build the pathname for the instantiation of <polydir>\&. Depending on the polyinstantiation
+\fImethod\fR
+it is then appended with "instance differentiation string" to generate the final instance directory path\&. This directory is created if it did not exist already, and is then bind mounted on the <polydir> to provide an instance of <polydir> based on the <method> column\&. The special string
+\fI$HOME\fR
+is replaced with the user\*(Aqs home directory, and
+\fI$USER\fR
+with the username\&. This field cannot be blank\&.
+.PP
+The third field,
+\fImethod\fR, is the method used for polyinstantiation\&. It can take these values; "user" for polyinstantiation based on user name, "level" for polyinstantiation based on process MLS level and user name, "context" for polyinstantiation based on process security context and user name, "tmpfs" for mounting tmpfs filesystem as an instance dir, and "tmpdir" for creating temporary directory as an instance dir which is removed when the user\*(Aqs session is closed\&. Methods "context" and "level" are only available with SELinux\&. This field cannot be blank\&.
+.PP
+The fourth field,
+\fIlist_of_uids\fR, is a comma separated list of user names for whom the polyinstantiation is not performed\&. If left blank, polyinstantiation will be performed for all users\&. If the list is preceded with a single "~" character, polyinstantiation is performed only for users in the list\&.
+.PP
+The
+\fImethod\fR
+field can contain also following optional flags separated by
+\fI:\fR
+characters\&.
+.PP
+\fIcreate\fR=\fImode\fR,\fIowner\fR,\fIgroup\fR
+\- create the polyinstantiated directory\&. The mode, owner and group parameters are optional\&. The default for mode is determined by umask, the default owner is the user whose session is opened, the default group is the primary group of the user\&.
+.PP
+\fIiscript\fR=\fIpath\fR
+\- path to the instance directory init script\&. The base directory for relative paths is
+/etc/security/namespace\&.d\&.
+.PP
+\fInoinit\fR
+\- instance directory init script will not be executed\&.
+.PP
+\fIshared\fR
+\- the instance directories for "context" and "level" methods will not contain the user name and will be shared among all users\&.
+.PP
+\fImntopts\fR=\fIvalue\fR
+\- value of this flag is passed to the mount call when the tmpfs mount is done\&. It allows for example the specification of the maximum size of the tmpfs instance that is created by the mount call\&. In addition to options specified in the
+\fBtmpfs\fR(5)
+manual the
+\fInosuid\fR,
+\fInoexec\fR, and
+\fInodev\fR
+flags can be used to respectively disable setuid bit effect, disable running executables, and disable devices to be interpreted on the mounted tmpfs filesystem\&.
+.PP
+The directory where polyinstantiated instances are to be created, must exist and must have, by default, the mode of 0000\&. The requirement that the instance parent be of mode 0000 can be overridden with the command line option
+\fIignore_instance_parent_mode\fR
+.PP
+In case of context or level polyinstantiation the SELinux context which is used for polyinstantiation is the context used for executing a new process as obtained by getexeccon\&. This context must be set by the calling application or
+pam_selinux\&.so
+module\&. If this context is not set the polyinstatiation will be based just on user name\&.
+.PP
+The "instance differentiation string" is <user name> for "user" method and <user name>_<raw directory context> for "context" and "level" methods\&. If the whole string is too long the end of it is replaced with md5sum of itself\&. Also when command line option
+\fIgen_hash\fR
+is used the whole string is replaced with md5sum of itself\&.
+.SH "EXAMPLES"
+.PP
+These are some example lines which might be specified in
+/etc/security/namespace\&.conf\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ # The following three lines will polyinstantiate /tmp,
+ # /var/tmp and user\*(Aqs home directories\&. /tmp and /var/tmp
+ # will be polyinstantiated based on the security level
+ # as well as user name, whereas home directory will be
+ # polyinstantiated based on the full security context and user name\&.
+ # Polyinstantiation will not be performed for user root
+ # and adm for directories /tmp and /var/tmp, whereas home
+ # directories will be polyinstantiated for all users\&.
+ #
+ # Note that instance directories do not have to reside inside
+ # the polyinstantiated directory\&. In the examples below,
+ # instances of /tmp will be created in /tmp\-inst directory,
+ # where as instances of /var/tmp and users home directories
+ # will reside within the directories that are being
+ # polyinstantiated\&.
+ #
+ /tmp /tmp\-inst/ level root,adm
+ /var/tmp /var/tmp/tmp\-inst/ level root,adm
+ $HOME $HOME/$USER\&.inst/inst\- context
+
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+For the <service>s you need polyinstantiation (login for example) put the following line in /etc/pam\&.d/<service> as the last line for session group:
+.PP
+session required pam_namespace\&.so [arguments]
+.PP
+This module also depends on pam_selinux\&.so setting the context\&.
+.SH "SEE ALSO"
+.PP
+\fBpam_namespace\fR(8),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHORS"
+.PP
+The namespace\&.conf manual page was written by Janak Desai <janak@us\&.ibm\&.com>\&. More features added by Tomas Mraz <tmraz@redhat\&.com>\&.
diff --git a/modules/pam_namespace/namespace.conf.5.xml b/modules/pam_namespace/namespace.conf.5.xml
new file mode 100644
index 0000000..a94b49e
--- /dev/null
+++ b/modules/pam_namespace/namespace.conf.5.xml
@@ -0,0 +1,223 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="namespace.conf">
+
+ <refmeta>
+ <refentrytitle>namespace.conf</refentrytitle>
+ <manvolnum>5</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>namespace.conf</refname>
+ <refpurpose>the namespace configuration file</refpurpose>
+ </refnamediv>
+
+
+ <refsect1 id='namespace.conf-description'>
+ <title>DESCRIPTION</title>
+
+ <para>
+ The <emphasis>pam_namespace.so</emphasis> module allows setup of
+ private namespaces with polyinstantiated directories.
+ Directories can be polyinstantiated based on user name
+ or, in the case of SELinux, user name, sensitivity level or complete security context. If an
+ executable script <filename>/etc/security/namespace.init</filename>
+ exists, it is used to initialize the namespace every time an instance
+ directory is set up and mounted. The script receives the polyinstantiated
+ directory path and the instance directory path as its arguments.
+ </para>
+
+ <para>
+ The <filename>/etc/security/namespace.conf</filename> file specifies
+ which directories are polyinstantiated, how they are polyinstantiated,
+ how instance directories would be named, and any users for whom
+ polyinstantiation would not be performed.
+ </para>
+
+ <para>
+ When someone logs in, the file <filename>namespace.conf</filename> is
+ scanned. Comments are marked by <emphasis>#</emphasis> characters.
+ Each non comment line represents one polyinstantiated
+ directory. The fields are separated by spaces but can be quoted by
+ <emphasis>"</emphasis> characters also escape
+ sequences <emphasis>\b</emphasis>, <emphasis>\n</emphasis>, and
+ <emphasis>\t</emphasis> are recognized. The fields are as follows:
+ </para>
+
+ <para><replaceable>polydir</replaceable> <replaceable>instance_prefix</replaceable> <replaceable>method</replaceable> <replaceable>list_of_uids</replaceable>
+ </para>
+
+ <para>
+ The first field, <replaceable>polydir</replaceable>, is the absolute
+ pathname of the directory to polyinstantiate. The special string
+ <emphasis>$HOME</emphasis> is replaced with the user's home directory,
+ and <emphasis>$USER</emphasis> with the username. This field cannot
+ be blank.
+ </para>
+
+ <para>
+ The second field, <replaceable>instance_prefix</replaceable> is
+ the string prefix used to build the pathname for the instantiation
+ of &lt;polydir&gt;. Depending on the polyinstantiation
+ <replaceable>method</replaceable> it is then appended with
+ "instance differentiation string" to generate the final
+ instance directory path. This directory is created if it did not exist
+ already, and is then bind mounted on the &lt;polydir&gt; to provide an
+ instance of &lt;polydir&gt; based on the &lt;method&gt; column.
+ The special string <emphasis>$HOME</emphasis> is replaced with the
+ user's home directory, and <emphasis>$USER</emphasis> with the username.
+ This field cannot be blank.
+ </para>
+
+ <para>
+ The third field, <replaceable>method</replaceable>, is the method
+ used for polyinstantiation. It can take these values; "user"
+ for polyinstantiation based on user name, "level" for
+ polyinstantiation based on process MLS level and user name, "context" for
+ polyinstantiation based on process security context and user name,
+ "tmpfs" for mounting tmpfs filesystem as an instance dir, and
+ "tmpdir" for creating temporary directory as an instance dir which is
+ removed when the user's session is closed.
+ Methods "context" and "level" are only available with SELinux. This
+ field cannot be blank.
+ </para>
+
+ <para>
+ The fourth field, <replaceable>list_of_uids</replaceable>, is
+ a comma separated list of user names for whom the polyinstantiation
+ is not performed. If left blank, polyinstantiation will be performed
+ for all users. If the list is preceded with a single "~" character,
+ polyinstantiation is performed only for users in the list.
+ </para>
+
+ <para>
+ The <replaceable>method</replaceable> field can contain also following
+ optional flags separated by <emphasis>:</emphasis> characters.
+ </para>
+
+ <para><emphasis>create</emphasis>=<replaceable>mode</replaceable>,<replaceable>owner</replaceable>,<replaceable>group</replaceable>
+ - create the polyinstantiated directory. The mode, owner and group parameters
+ are optional. The default for mode is determined by umask, the default
+ owner is the user whose session is opened, the default group is the
+ primary group of the user.
+ </para>
+
+ <para><emphasis>iscript</emphasis>=<replaceable>path</replaceable>
+ - path to the instance directory init script. The base directory for relative
+ paths is <filename>/etc/security/namespace.d</filename>.
+ </para>
+
+ <para><emphasis>noinit</emphasis>
+ - instance directory init script will not be executed.
+ </para>
+
+ <para><emphasis>shared</emphasis>
+ - the instance directories for "context" and "level" methods will not
+ contain the user name and will be shared among all users.
+ </para>
+
+ <para><emphasis>mntopts</emphasis>=<replaceable>value</replaceable>
+ - value of this flag is passed to the mount call when the tmpfs mount is
+ done. It allows for example the specification of the maximum size of the
+ tmpfs instance that is created by the mount call. In addition to
+ options specified in the <citerefentry>
+ <refentrytitle>tmpfs</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry> manual the <emphasis>nosuid</emphasis>,
+ <emphasis>noexec</emphasis>, and <emphasis>nodev</emphasis> flags
+ can be used to respectively disable setuid bit effect, disable running
+ executables, and disable devices to be interpreted on the mounted
+ tmpfs filesystem.
+ </para>
+
+ <para>
+ The directory where polyinstantiated instances are to be
+ created, must exist and must have, by default, the mode of 0000. The
+ requirement that the instance parent be of mode 0000 can be overridden
+ with the command line option <emphasis>ignore_instance_parent_mode</emphasis>
+ </para>
+
+ <para>
+ In case of context or level polyinstantiation the SELinux context
+ which is used for polyinstantiation is the context used for executing
+ a new process as obtained by getexeccon. This context must be set
+ by the calling application or <filename>pam_selinux.so</filename>
+ module. If this context is not set the polyinstatiation will be
+ based just on user name.
+ </para>
+
+ <para>
+ The "instance differentiation string" is &lt;user name&gt; for "user"
+ method and &lt;user name&gt;_&lt;raw directory context&gt; for "context"
+ and "level" methods. If the whole string is too long the end of it is
+ replaced with md5sum of itself. Also when command line option
+ <emphasis>gen_hash</emphasis> is used the whole string is replaced
+ with md5sum of itself.
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="namespace.conf-examples">
+ <title>EXAMPLES</title>
+ <para>
+ These are some example lines which might be specified in
+ <filename>/etc/security/namespace.conf</filename>.
+ </para>
+
+ <literallayout>
+ # The following three lines will polyinstantiate /tmp,
+ # /var/tmp and user's home directories. /tmp and /var/tmp
+ # will be polyinstantiated based on the security level
+ # as well as user name, whereas home directory will be
+ # polyinstantiated based on the full security context and user name.
+ # Polyinstantiation will not be performed for user root
+ # and adm for directories /tmp and /var/tmp, whereas home
+ # directories will be polyinstantiated for all users.
+ #
+ # Note that instance directories do not have to reside inside
+ # the polyinstantiated directory. In the examples below,
+ # instances of /tmp will be created in /tmp-inst directory,
+ # where as instances of /var/tmp and users home directories
+ # will reside within the directories that are being
+ # polyinstantiated.
+ #
+ /tmp /tmp-inst/ level root,adm
+ /var/tmp /var/tmp/tmp-inst/ level root,adm
+ $HOME $HOME/$USER.inst/inst- context
+ </literallayout>
+
+ <para>
+ For the &lt;service&gt;s you need polyinstantiation (login for example)
+ put the following line in /etc/pam.d/&lt;service&gt; as the last line for
+ session group:
+ </para>
+
+ <para>
+ session required pam_namespace.so [arguments]
+ </para>
+
+ <para>
+ This module also depends on pam_selinux.so setting the context.
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="namespace.conf-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry><refentrytitle>pam_namespace</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id="namespace.conf-author">
+ <title>AUTHORS</title>
+ <para>
+ The namespace.conf manual page was written by Janak Desai &lt;janak@us.ibm.com&gt;.
+ More features added by Tomas Mraz &lt;tmraz@redhat.com&gt;.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_namespace/namespace.init b/modules/pam_namespace/namespace.init
new file mode 100755
index 0000000..67d4aa2
--- /dev/null
+++ b/modules/pam_namespace/namespace.init
@@ -0,0 +1,25 @@
+#!/bin/sh
+# It receives polydir path as $1, the instance path as $2,
+# a flag whether the instance dir was newly created (0 - no, 1 - yes) in $3,
+# and user name in $4.
+#
+# The following section will copy the contents of /etc/skel if this is a
+# newly created home directory.
+if [ "$3" = 1 ]; then
+ # This line will fix the labeling on all newly created directories
+ [ -x /sbin/restorecon ] && /sbin/restorecon "$1"
+ user="$4"
+ passwd=$(getent passwd "$user")
+ homedir=$(echo "$passwd" | cut -f6 -d":")
+ if [ "$1" = "$homedir" ]; then
+ gid=$(echo "$passwd" | cut -f4 -d":")
+ cp -rT /etc/skel "$homedir"
+ chown -R "$user":"$gid" "$homedir"
+ mask=$(awk '/^UMASK/{gsub("#.*$", "", $2); print $2; exit}' /etc/login.defs)
+ mode=$(printf "%o" $((0777 & ~$mask)))
+ chmod ${mode:-700} "$homedir"
+ [ -x /sbin/restorecon ] && /sbin/restorecon -R "$homedir"
+ fi
+fi
+
+exit 0
diff --git a/modules/pam_namespace/pam_namespace.8 b/modules/pam_namespace/pam_namespace.8
new file mode 100644
index 0000000..d0afb6c
--- /dev/null
+++ b/modules/pam_namespace/pam_namespace.8
@@ -0,0 +1,154 @@
+'\" t
+.\" Title: pam_namespace
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_NAMESPACE" "8" "09/03/2021" "Linux-PAM Manual" "Linux-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_namespace \- PAM module for configuring namespace for a session
+.SH "SYNOPSIS"
+.HP \w'\fBpam_namespace\&.so\fR\ 'u
+\fBpam_namespace\&.so\fR [debug] [unmnt_remnt] [unmnt_only] [require_selinux] [gen_hash] [ignore_config_error] [ignore_instance_parent_mode] [unmount_on_close] [use_current_context] [use_default_context] [mount_private]
+.SH "DESCRIPTION"
+.PP
+The pam_namespace PAM module sets up a private namespace for a session with polyinstantiated directories\&. A polyinstantiated directory provides a different instance of itself based on user name, or when using SELinux, user name, security context or both\&. If an executable script
+/etc/security/namespace\&.init
+exists, it is used to initialize the instance directory after it is set up and mounted on the polyinstantiated directory\&. The script receives the polyinstantiated directory path, the instance directory path, flag whether the instance directory was newly created (0 for no, 1 for yes), and the user name as its arguments\&.
+.PP
+The pam_namespace module disassociates the session namespace from the parent namespace\&. Any mounts/unmounts performed in the parent namespace, such as mounting of devices, are not reflected in the session namespace\&. To propagate selected mount/unmount events from the parent namespace into the disassociated session namespace, an administrator may use the special shared\-subtree feature\&. For additional information on shared\-subtree feature, please refer to the mount(8) man page and the shared\-subtree description at http://lwn\&.net/Articles/159077 and http://lwn\&.net/Articles/159092\&.
+.SH "OPTIONS"
+.PP
+\fBdebug\fR
+.RS 4
+A lot of debug information is logged using syslog
+.RE
+.PP
+\fBunmnt_remnt\fR
+.RS 4
+For programs such as su and newrole, the login session has already setup a polyinstantiated namespace\&. For these programs, polyinstantiation is performed based on new user id or security context, however the command first needs to undo the polyinstantiation performed by login\&. This argument instructs the command to first undo previous polyinstantiation before proceeding with new polyinstantiation based on new id/context
+.RE
+.PP
+\fBunmnt_only\fR
+.RS 4
+For trusted programs that want to undo any existing bind mounts and process instance directories on their own, this argument allows them to unmount currently mounted instance directories
+.RE
+.PP
+\fBrequire_selinux\fR
+.RS 4
+If selinux is not enabled, return failure
+.RE
+.PP
+\fBgen_hash\fR
+.RS 4
+Instead of using the security context string for the instance name, generate and use its md5 hash\&.
+.RE
+.PP
+\fBignore_config_error\fR
+.RS 4
+If a line in the configuration file corresponding to a polyinstantiated directory contains format error, skip that line process the next line\&. Without this option, pam will return an error to the calling program resulting in termination of the session\&.
+.RE
+.PP
+\fBignore_instance_parent_mode\fR
+.RS 4
+Instance parent directories by default are expected to have the restrictive mode of 000\&. Using this option, an administrator can choose to ignore the mode of the instance parent\&. This option should be used with caution as it will reduce security and isolation goals of the polyinstantiation mechanism\&.
+.RE
+.PP
+\fBunmount_on_close\fR
+.RS 4
+Explicitly unmount the polyinstantiated directories instead of relying on automatic namespace destruction after the last process in a namespace exits\&. This option should be used only in case it is ensured by other means that there cannot be any processes running in the private namespace left after the session close\&. It is also useful only in case there are multiple pam session calls in sequence from the same process\&.
+.RE
+.PP
+\fBuse_current_context\fR
+.RS 4
+Useful for services which do not change the SELinux context with setexeccon call\&. The module will use the current SELinux context of the calling process for the level and context polyinstantiation\&.
+.RE
+.PP
+\fBuse_default_context\fR
+.RS 4
+Useful for services which do not use pam_selinux for changing the SELinux context with setexeccon call\&. The module will use the default SELinux context of the user for the level and context polyinstantiation\&.
+.RE
+.PP
+\fBmount_private\fR
+.RS 4
+This option can be used on systems where the / mount point or its submounts are made shared (for example with a
+\fBmount \-\-make\-rshared /\fR
+command)\&. The module will mark the whole directory tree so any mount and unmount operations in the polyinstantiation namespace are private\&. Normally the pam_namespace will try to detect the shared / mount point and make the polyinstantiated directories private automatically\&. This option has to be used just when only a subtree is shared and / is not\&.
+.sp
+Note that mounts and unmounts done in the private namespace will not affect the parent namespace if this option is used or when the shared / mount point is autodetected\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+Only the
+\fBsession\fR
+module type is provided\&. The module must not be called from multithreaded processes\&.
+.SH "RETURN VALUES"
+.PP
+PAM_SUCCESS
+.RS 4
+Namespace setup was successful\&.
+.RE
+.PP
+PAM_SERVICE_ERR
+.RS 4
+Unexpected system error occurred while setting up namespace\&.
+.RE
+.PP
+PAM_SESSION_ERR
+.RS 4
+Unexpected namespace configuration error occurred\&.
+.RE
+.SH "FILES"
+.PP
+/etc/security/namespace\&.conf
+.RS 4
+Main configuration file
+.RE
+.PP
+/etc/security/namespace\&.d
+.RS 4
+Directory for additional configuration files
+.RE
+.PP
+/etc/security/namespace\&.init
+.RS 4
+Init script for instance directories
+.RE
+.SH "EXAMPLES"
+.PP
+For the <service>s you need polyinstantiation (login for example) put the following line in /etc/pam\&.d/<service> as the last line for session group:
+.PP
+session required pam_namespace\&.so [arguments]
+.PP
+To use polyinstantiation with graphical display manager gdm, please refer to gdm\*(Aqs documentation\&.
+.SH "SEE ALSO"
+.PP
+\fBnamespace.conf\fR(5),
+\fBpam.d\fR(5),
+\fBmount\fR(8),
+\fBpam\fR(8)\&.
+.SH "AUTHORS"
+.PP
+The namespace setup scheme was designed by Stephen Smalley, Janak Desai and Chad Sellers\&. The pam_namespace PAM module was developed by Janak Desai <janak@us\&.ibm\&.com>, Chad Sellers <csellers@tresys\&.com> and Steve Grubb <sgrubb@redhat\&.com>\&. Additional improvements by Xavier Toth <txtoth@gmail\&.com> and Tomas Mraz <tmraz@redhat\&.com>\&.
diff --git a/modules/pam_namespace/pam_namespace.8.xml b/modules/pam_namespace/pam_namespace.8.xml
new file mode 100644
index 0000000..57c44c4
--- /dev/null
+++ b/modules/pam_namespace/pam_namespace.8.xml
@@ -0,0 +1,381 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+
+<refentry id='pam_namespace'>
+
+ <refmeta>
+ <refentrytitle>pam_namespace</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id='pam_namespace-name'>
+ <refname>pam_namespace</refname>
+ <refpurpose>
+ PAM module for configuring namespace for a session
+ </refpurpose>
+ </refnamediv>
+
+<!-- body begins here -->
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_namespace-cmdsynopsis">
+ <command>pam_namespace.so</command>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ unmnt_remnt
+ </arg>
+ <arg choice="opt">
+ unmnt_only
+ </arg>
+ <arg choice="opt">
+ require_selinux
+ </arg>
+ <arg choice="opt">
+ gen_hash
+ </arg>
+ <arg choice="opt">
+ ignore_config_error
+ </arg>
+ <arg choice="opt">
+ ignore_instance_parent_mode
+ </arg>
+ <arg choice="opt">
+ unmount_on_close
+ </arg>
+ <arg choice="opt">
+ use_current_context
+ </arg>
+ <arg choice="opt">
+ use_default_context
+ </arg>
+ <arg choice="opt">
+ mount_private
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1 id="pam_namespace-description">
+ <title>DESCRIPTION</title>
+ <para>
+ The pam_namespace PAM module sets up a private namespace for a session
+ with polyinstantiated directories. A polyinstantiated directory
+ provides a different instance of itself based on user name, or when
+ using SELinux, user name, security context or both. If an executable
+ script <filename>/etc/security/namespace.init</filename> exists, it
+ is used to initialize the instance directory after it is set up
+ and mounted on the polyinstantiated directory. The script receives the
+ polyinstantiated directory path, the instance directory path, flag
+ whether the instance directory was newly created (0 for no, 1 for yes),
+ and the user name as its arguments.
+ </para>
+
+ <para>
+ The pam_namespace module disassociates the session namespace from
+ the parent namespace. Any mounts/unmounts performed in the parent
+ namespace, such as mounting of devices, are not reflected in the
+ session namespace. To propagate selected mount/unmount events from
+ the parent namespace into the disassociated session namespace, an
+ administrator may use the special shared-subtree feature. For
+ additional information on shared-subtree feature, please refer to
+ the mount(8) man page and the shared-subtree description at
+ http://lwn.net/Articles/159077 and http://lwn.net/Articles/159092.
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="pam_namespace-options">
+ <title>OPTIONS</title>
+ <variablelist>
+
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ A lot of debug information is logged using syslog
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>unmnt_remnt</option>
+ </term>
+ <listitem>
+ <para>
+ For programs such as su and newrole, the login
+ session has already setup a polyinstantiated
+ namespace. For these programs, polyinstantiation
+ is performed based on new user id or security
+ context, however the command first needs to
+ undo the polyinstantiation performed by login.
+ This argument instructs the command to
+ first undo previous polyinstantiation before
+ proceeding with new polyinstantiation based on
+ new id/context
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>unmnt_only</option>
+ </term>
+ <listitem>
+ <para>
+ For trusted programs that want to undo any
+ existing bind mounts and process instance
+ directories on their own, this argument allows
+ them to unmount currently mounted instance
+ directories
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>require_selinux</option>
+ </term>
+ <listitem>
+ <para>
+ If selinux is not enabled, return failure
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>gen_hash</option>
+ </term>
+ <listitem>
+ <para>
+ Instead of using the security context string
+ for the instance name, generate and use its
+ md5 hash.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>ignore_config_error</option>
+ </term>
+ <listitem>
+ <para>
+ If a line in the configuration file corresponding
+ to a polyinstantiated directory contains format
+ error, skip that line process the next line.
+ Without this option, pam will return an error
+ to the calling program resulting in termination
+ of the session.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>ignore_instance_parent_mode</option>
+ </term>
+ <listitem>
+ <para>
+ Instance parent directories by default are expected to have
+ the restrictive mode of 000. Using this option, an administrator
+ can choose to ignore the mode of the instance parent. This option
+ should be used with caution as it will reduce security and
+ isolation goals of the polyinstantiation mechanism.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>unmount_on_close</option>
+ </term>
+ <listitem>
+ <para>
+ Explicitly unmount the polyinstantiated directories instead
+ of relying on automatic namespace destruction after the last
+ process in a namespace exits. This option should be used
+ only in case it is ensured by other means that there cannot be
+ any processes running in the private namespace left after the
+ session close. It is also useful only in case there are
+ multiple pam session calls in sequence from the same process.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>use_current_context</option>
+ </term>
+ <listitem>
+ <para>
+ Useful for services which do not change the SELinux context
+ with setexeccon call. The module will use the current SELinux
+ context of the calling process for the level and context
+ polyinstantiation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>use_default_context</option>
+ </term>
+ <listitem>
+ <para>
+ Useful for services which do not use pam_selinux for changing
+ the SELinux context with setexeccon call. The module will use
+ the default SELinux context of the user for the level and context
+ polyinstantiation.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>mount_private</option>
+ </term>
+ <listitem>
+ <para>
+ This option can be used on systems where the / mount point or
+ its submounts are made shared (for example with a
+ <command>mount --make-rshared /</command> command).
+ The module will mark the whole directory tree so any mount and
+ unmount operations in the polyinstantiation namespace are private.
+ Normally the pam_namespace will try to detect the
+ shared / mount point and make the polyinstantiated directories
+ private automatically. This option has to be used just when
+ only a subtree is shared and / is not.
+ </para>
+ <para>
+ Note that mounts and unmounts done in the private namespace will not
+ affect the parent namespace if this option is used or when the
+ shared / mount point is autodetected.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_namespace-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ Only the <option>session</option> module type is provided.
+ The module must not be called from multithreaded processes.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_namespace-return_values">
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Namespace setup was successful.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ Unexpected system error occurred while setting up namespace.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SESSION_ERR</term>
+ <listitem>
+ <para>
+ Unexpected namespace configuration error occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_namespace-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/security/namespace.conf</filename></term>
+ <listitem>
+ <para>Main configuration file</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>/etc/security/namespace.d</filename></term>
+ <listitem>
+ <para>Directory for additional configuration files</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><filename>/etc/security/namespace.init</filename></term>
+ <listitem>
+ <para>Init script for instance directories</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_namespace-examples">
+ <title>EXAMPLES</title>
+
+ <para>
+ For the &lt;service&gt;s you need polyinstantiation (login for example)
+ put the following line in /etc/pam.d/&lt;service&gt; as the last line for
+ session group:
+ </para>
+
+ <para>
+ session required pam_namespace.so [arguments]
+ </para>
+
+ <para>
+ To use polyinstantiation with graphical display manager gdm, please refer
+ to gdm's documentation.
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="pam_namespace-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>namespace.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_namespace-authors">
+ <title>AUTHORS</title>
+ <para>
+ The namespace setup scheme was designed by Stephen Smalley, Janak Desai
+ and Chad Sellers.
+ The pam_namespace PAM module was developed by Janak Desai &lt;janak@us.ibm.com&gt;,
+ Chad Sellers &lt;csellers@tresys.com&gt; and Steve Grubb &lt;sgrubb@redhat.com&gt;.
+ Additional improvements by Xavier Toth &lt;txtoth@gmail.com&gt; and Tomas Mraz
+ &lt;tmraz@redhat.com&gt;.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c
new file mode 100644
index 0000000..4d4188d
--- /dev/null
+++ b/modules/pam_namespace/pam_namespace.c
@@ -0,0 +1,2272 @@
+/******************************************************************************
+ * A module for Linux-PAM that will set the default namespace after
+ * establishing a session via PAM.
+ *
+ * (C) Copyright IBM Corporation 2005
+ * (C) Copyright Red Hat, Inc. 2006, 2008
+ * All Rights Reserved.
+ *
+ * Written by: Janak Desai <janak@us.ibm.com>
+ * With Revisions by: Steve Grubb <sgrubb@redhat.com>
+ * Contributions by: Xavier Toth <txtoth@gmail.com>,
+ * Tomas Mraz <tmraz@redhat.com>
+ * Derived from a namespace setup patch by Chad Sellers <cdselle@tycho.nsa.gov>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#define _ATFILE_SOURCE
+
+#include "pam_cc_compat.h"
+#include "pam_inline.h"
+#include "pam_namespace.h"
+#include "argv_parse.h"
+
+/*
+ * Adds an entry for a polyinstantiated directory to the linked list of
+ * polyinstantiated directories. It is called from process_line() while
+ * parsing the namespace configuration file.
+ */
+static void add_polydir_entry(struct instance_data *idata,
+ struct polydir_s *ent)
+{
+ /* Now attach to linked list */
+ ent->next = NULL;
+ if (idata->polydirs_ptr == NULL)
+ idata->polydirs_ptr = ent;
+ else {
+ struct polydir_s *tail;
+
+ tail = idata->polydirs_ptr;
+ while (tail->next)
+ tail = tail->next;
+ tail->next = ent;
+ }
+}
+
+static void del_polydir(struct polydir_s *poly)
+{
+ if (poly) {
+ free(poly->uid);
+ free(poly->init_script);
+ free(poly->mount_opts);
+ free(poly);
+ }
+}
+
+/*
+ * Deletes all the entries in the linked list.
+ */
+static void del_polydir_list(struct polydir_s *polydirs_ptr)
+{
+ struct polydir_s *dptr = polydirs_ptr;
+
+ while (dptr) {
+ struct polydir_s *tptr = dptr;
+ dptr = dptr->next;
+ del_polydir(tptr);
+ }
+}
+
+static void unprotect_dirs(struct protect_dir_s *dir)
+{
+ struct protect_dir_s *next;
+
+ while (dir != NULL) {
+ umount(dir->dir);
+ free(dir->dir);
+ next = dir->next;
+ free(dir);
+ dir = next;
+ }
+}
+
+static void cleanup_polydir_data(pam_handle_t *pamh UNUSED , void *data, int err UNUSED)
+{
+ del_polydir_list(data);
+}
+
+static void cleanup_protect_data(pam_handle_t *pamh UNUSED , void *data, int err UNUSED)
+{
+ unprotect_dirs(data);
+}
+
+static char *expand_variables(const char *orig, const char *var_names[], const char *var_values[])
+{
+ const char *src = orig;
+ char *dst;
+ char *expanded;
+ char c;
+ size_t dstlen = 0;
+ while (*src) {
+ if (*src == '$') {
+ int i;
+ for (i = 0; var_names[i]; i++) {
+ int namelen = strlen(var_names[i]);
+ if (strncmp(var_names[i], src+1, namelen) == 0) {
+ dstlen += strlen(var_values[i]) - 1; /* $ */
+ src += namelen;
+ break;
+ }
+ }
+ }
+ ++dstlen;
+ ++src;
+ }
+ if ((dst=expanded=malloc(dstlen + 1)) == NULL)
+ return NULL;
+ src = orig;
+ while ((c=*src) != '\0') {
+ if (c == '$') {
+ int i;
+ for (i = 0; var_names[i]; i++) {
+ int namelen = strlen(var_names[i]);
+ if (strncmp(var_names[i], src+1, namelen) == 0) {
+ dst = stpcpy(dst, var_values[i]);
+ --dst;
+ c = *dst; /* replace $ */
+ src += namelen;
+ break;
+ }
+ }
+ }
+ *dst = c;
+ ++dst;
+ ++src;
+ }
+ *dst = '\0';
+ return expanded;
+}
+
+static int parse_create_params(char *params, struct polydir_s *poly)
+{
+ char *next;
+ struct passwd *pwd = NULL;
+ struct group *grp;
+
+ poly->mode = (mode_t)ULONG_MAX;
+ poly->owner = (uid_t)ULONG_MAX;
+ poly->group = (gid_t)ULONG_MAX;
+
+ if (*params != '=')
+ return 0;
+ params++;
+
+ next = strchr(params, ',');
+ if (next != NULL) {
+ *next = '\0';
+ next++;
+ }
+
+ if (*params != '\0') {
+ errno = 0;
+ poly->mode = (mode_t)strtoul(params, NULL, 0);
+ if (errno != 0) {
+ poly->mode = (mode_t)ULONG_MAX;
+ }
+ }
+
+ params = next;
+ if (params == NULL)
+ return 0;
+ next = strchr(params, ',');
+ if (next != NULL) {
+ *next = '\0';
+ next++;
+ }
+
+ if (*params != '\0') {
+ pwd = getpwnam(params); /* session modules are not reentrant */
+ if (pwd == NULL)
+ return -1;
+ poly->owner = pwd->pw_uid;
+ }
+
+ params = next;
+ if (params == NULL || *params == '\0') {
+ if (pwd != NULL)
+ poly->group = pwd->pw_gid;
+ return 0;
+ }
+ grp = getgrnam(params);
+ if (grp == NULL)
+ return -1;
+ poly->group = grp->gr_gid;
+
+ return 0;
+}
+
+static int parse_iscript_params(char *params, struct polydir_s *poly)
+{
+ if (*params != '=')
+ return 0;
+ params++;
+
+ if (*params != '\0') {
+ if (*params != '/') { /* path is relative to NAMESPACE_D_DIR */
+ if (asprintf(&poly->init_script, "%s%s", NAMESPACE_D_DIR, params) == -1)
+ return -1;
+ } else {
+ poly->init_script = strdup(params);
+ }
+ if (poly->init_script == NULL)
+ return -1;
+ }
+ return 0;
+}
+
+struct mntflag {
+ const char *name;
+ size_t len;
+ unsigned long flag;
+};
+
+#define LITERAL_AND_LEN(x) x, sizeof(x) - 1
+
+static const struct mntflag mntflags[] = {
+ { LITERAL_AND_LEN("noexec"), MS_NOEXEC },
+ { LITERAL_AND_LEN("nosuid"), MS_NOSUID },
+ { LITERAL_AND_LEN("nodev"), MS_NODEV }
+ };
+
+static int filter_mntopts(const char *opts, char **filtered,
+ unsigned long *mountflags)
+{
+ size_t origlen = strlen(opts);
+ const char *end;
+ char *dest;
+
+ dest = *filtered = NULL;
+ *mountflags = 0;
+
+ if (origlen == 0)
+ return 0;
+
+ do {
+ size_t len;
+ unsigned int i;
+
+ end = strchr(opts, ',');
+ if (end == NULL) {
+ len = strlen(opts);
+ } else {
+ len = end - opts;
+ }
+
+ for (i = 0; i < PAM_ARRAY_SIZE(mntflags); i++) {
+ if (mntflags[i].len != len)
+ continue;
+ if (memcmp(mntflags[i].name, opts, len) == 0) {
+ *mountflags |= mntflags[i].flag;
+ opts = end;
+ break;
+ }
+ }
+
+ if (opts != end) {
+ if (dest != NULL) {
+ *dest = ',';
+ ++dest;
+ } else {
+ dest = *filtered = calloc(1, origlen + 1);
+ if (dest == NULL)
+ return -1;
+ }
+ memcpy(dest, opts, len);
+ dest += len;
+ }
+
+ opts = end + 1;
+ } while (end != NULL);
+
+ return 0;
+}
+
+static int parse_method(char *method, struct polydir_s *poly,
+ struct instance_data *idata)
+{
+ enum polymethod pm;
+ char *sptr = NULL;
+ static const char *method_names[] = { "user", "context", "level", "tmpdir",
+ "tmpfs", NULL };
+ static const char *flag_names[] = { "create", "noinit", "iscript",
+ "shared", "mntopts", NULL };
+ static const unsigned int flag_values[] = { POLYDIR_CREATE, POLYDIR_NOINIT,
+ POLYDIR_ISCRIPT, POLYDIR_SHARED, POLYDIR_MNTOPTS };
+ int i;
+ char *flag;
+
+ method = strtok_r(method, ":", &sptr);
+ pm = NONE;
+
+ for (i = 0; method_names[i]; i++) {
+ if (strcmp(method, method_names[i]) == 0) {
+ pm = i + 1; /* 0 = NONE */
+ }
+ }
+
+ if (pm == NONE) {
+ pam_syslog(idata->pamh, LOG_NOTICE, "Unknown method");
+ return -1;
+ }
+
+ poly->method = pm;
+
+ while ((flag=strtok_r(NULL, ":", &sptr)) != NULL) {
+ for (i = 0; flag_names[i]; i++) {
+ int namelen = strlen(flag_names[i]);
+
+ if (strncmp(flag, flag_names[i], namelen) == 0) {
+ poly->flags |= flag_values[i];
+ switch (flag_values[i]) {
+ case POLYDIR_CREATE:
+ if (parse_create_params(flag+namelen, poly) != 0) {
+ pam_syslog(idata->pamh, LOG_CRIT, "Invalid create parameters");
+ return -1;
+ }
+ break;
+
+ case POLYDIR_ISCRIPT:
+ if (parse_iscript_params(flag+namelen, poly) != 0) {
+ pam_syslog(idata->pamh, LOG_CRIT, "Memory allocation error");
+ return -1;
+ };
+ break;
+
+ case POLYDIR_MNTOPTS:
+ if (flag[namelen] != '=')
+ break;
+ if (poly->method != TMPFS) {
+ pam_syslog(idata->pamh, LOG_WARNING, "Mount options applicable only to tmpfs method");
+ break;
+ }
+ free(poly->mount_opts); /* if duplicate mntopts specified */
+ poly->mount_opts = NULL;
+ if (filter_mntopts(flag+namelen+1, &poly->mount_opts, &poly->mount_flags) != 0) {
+ pam_syslog(idata->pamh, LOG_CRIT, "Memory allocation error");
+ return -1;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Called from parse_config_file, this function processes a single line
+ * of the namespace configuration file. It skips over comments and incomplete
+ * or malformed lines. It processes a valid line with information on
+ * polyinstantiating a directory by populating appropriate fields of a
+ * polyinstatiated directory structure and then calling add_polydir_entry to
+ * add that entry to the linked list of polyinstantiated directories.
+ */
+static int process_line(char *line, const char *home, const char *rhome,
+ struct instance_data *idata)
+{
+ char *dir = NULL, *instance_prefix = NULL, *rdir = NULL;
+ char *method, *uids;
+ char *tptr;
+ struct polydir_s *poly;
+ int retval = 0;
+ char **config_options = NULL;
+ static const char *var_names[] = {"HOME", "USER", NULL};
+ const char *var_values[] = {home, idata->user};
+ const char *rvar_values[] = {rhome, idata->ruser};
+ int len;
+
+ /*
+ * skip the leading white space
+ */
+ while (*line && isspace(*line))
+ line++;
+
+ /*
+ * Rip off the comments
+ */
+ tptr = strchr(line,'#');
+ if (tptr)
+ *tptr = '\0';
+
+ /*
+ * Rip off the newline char
+ */
+ tptr = strchr(line,'\n');
+ if (tptr)
+ *tptr = '\0';
+
+ /*
+ * Anything left ?
+ */
+ if (line[0] == 0)
+ return 0;
+
+ poly = calloc(1, sizeof(*poly));
+ if (poly == NULL)
+ goto erralloc;
+
+ /*
+ * Initialize and scan the five strings from the line from the
+ * namespace configuration file.
+ */
+ retval = argv_parse(line, NULL, &config_options);
+ if (retval != 0) {
+ goto erralloc;
+ }
+
+ dir = config_options[0];
+ if (dir == NULL) {
+ pam_syslog(idata->pamh, LOG_NOTICE, "Invalid line missing polydir");
+ goto skipping;
+ }
+ instance_prefix = config_options[1];
+ if (instance_prefix == NULL) {
+ pam_syslog(idata->pamh, LOG_NOTICE, "Invalid line missing instance_prefix");
+ instance_prefix = NULL;
+ goto skipping;
+ }
+ method = config_options[2];
+ if (method == NULL) {
+ pam_syslog(idata->pamh, LOG_NOTICE, "Invalid line missing method");
+ instance_prefix = NULL;
+ dir = NULL;
+ goto skipping;
+ }
+
+ /*
+ * Only the uids field is allowed to be blank, to indicate no
+ * override users for polyinstantiation of that directory. If
+ * any of the other fields are blank, the line is incomplete so
+ * skip it.
+ */
+ uids = config_options[3];
+
+ /*
+ * Expand $HOME and $USER in poly dir and instance dir prefix
+ */
+ if ((rdir=expand_variables(dir, var_names, rvar_values)) == NULL) {
+ instance_prefix = NULL;
+ dir = NULL;
+ goto erralloc;
+ }
+
+ if ((dir=expand_variables(dir, var_names, var_values)) == NULL) {
+ instance_prefix = NULL;
+ goto erralloc;
+ }
+
+ if ((instance_prefix=expand_variables(instance_prefix, var_names, var_values))
+ == NULL) {
+ goto erralloc;
+ }
+
+ if (idata->flags & PAMNS_DEBUG) {
+ pam_syslog(idata->pamh, LOG_DEBUG, "Expanded polydir: '%s'", dir);
+ pam_syslog(idata->pamh, LOG_DEBUG, "Expanded ruser polydir: '%s'", rdir);
+ pam_syslog(idata->pamh, LOG_DEBUG, "Expanded instance prefix: '%s'", instance_prefix);
+ }
+
+ len = strlen(dir);
+ if (len > 0 && dir[len-1] == '/') {
+ dir[len-1] = '\0';
+ }
+
+ len = strlen(rdir);
+ if (len > 0 && rdir[len-1] == '/') {
+ rdir[len-1] = '\0';
+ }
+
+ if (dir[0] == '\0' || rdir[0] == '\0') {
+ pam_syslog(idata->pamh, LOG_NOTICE, "Invalid polydir");
+ goto skipping;
+ }
+
+ /*
+ * Populate polyinstantiated directory structure with appropriate
+ * pathnames and the method with which to polyinstantiate.
+ */
+ if (strlen(dir) >= sizeof(poly->dir)
+ || strlen(rdir) >= sizeof(poly->rdir)
+ || strlen(instance_prefix) >= sizeof(poly->instance_prefix)) {
+ pam_syslog(idata->pamh, LOG_NOTICE, "Pathnames too long");
+ goto skipping;
+ }
+ strcpy(poly->dir, dir);
+ strcpy(poly->rdir, rdir);
+ strcpy(poly->instance_prefix, instance_prefix);
+
+ if (parse_method(method, poly, idata) != 0) {
+ goto skipping;
+ }
+
+ if (poly->method == TMPDIR) {
+ if (sizeof(poly->instance_prefix) - strlen(poly->instance_prefix) < 7) {
+ pam_syslog(idata->pamh, LOG_NOTICE, "Pathnames too long");
+ goto skipping;
+ }
+ strcat(poly->instance_prefix, "XXXXXX");
+ }
+
+ /*
+ * Ensure that all pathnames are absolute path names.
+ */
+ if ((poly->dir[0] != '/') || (poly->method != TMPFS && poly->instance_prefix[0] != '/')) {
+ pam_syslog(idata->pamh, LOG_NOTICE, "Pathnames must start with '/'");
+ goto skipping;
+ }
+ if (strstr(dir, "..") || strstr(poly->instance_prefix, "..")) {
+ pam_syslog(idata->pamh, LOG_NOTICE, "Pathnames must not contain '..'");
+ goto skipping;
+ }
+
+ /*
+ * If the line in namespace.conf for a directory to polyinstantiate
+ * contains a list of override users (users for whom polyinstantiation
+ * is not performed), read the user ids, convert names into uids, and
+ * add to polyinstantiated directory structure.
+ */
+ if (uids) {
+ uid_t *uidptr;
+ const char *ustr, *sstr;
+ int count, i;
+
+ if (*uids == '~') {
+ poly->flags |= POLYDIR_EXCLUSIVE;
+ uids++;
+ }
+ for (count = 0, ustr = sstr = uids; sstr; ustr = sstr + 1, count++)
+ sstr = strchr(ustr, ',');
+
+ poly->num_uids = count;
+ poly->uid = (uid_t *) malloc(count * sizeof (uid_t));
+ uidptr = poly->uid;
+ if (uidptr == NULL) {
+ goto erralloc;
+ }
+
+ ustr = uids;
+ for (i = 0; i < count; i++) {
+ struct passwd *pwd;
+
+ tptr = strchr(ustr, ',');
+ if (tptr)
+ *tptr = '\0';
+
+ pwd = pam_modutil_getpwnam(idata->pamh, ustr);
+ if (pwd == NULL) {
+ pam_syslog(idata->pamh, LOG_ERR, "Unknown user %s in configuration", ustr);
+ poly->num_uids--;
+ } else {
+ *uidptr = pwd->pw_uid;
+ uidptr++;
+ }
+ ustr = tptr + 1;
+ }
+ }
+
+ /*
+ * Add polyinstantiated directory structure to the linked list
+ * of all polyinstantiated directory structures.
+ */
+ add_polydir_entry(idata, poly);
+
+ goto out;
+
+erralloc:
+ pam_syslog(idata->pamh, LOG_CRIT, "Memory allocation error");
+
+skipping:
+ if (idata->flags & PAMNS_IGN_CONFIG_ERR)
+ retval = 0;
+ else
+ retval = PAM_SERVICE_ERR;
+ del_polydir(poly);
+out:
+ free(rdir);
+ free(dir);
+ free(instance_prefix);
+ argv_free(config_options);
+ return retval;
+}
+
+
+/*
+ * Parses /etc/security/namespace.conf file to build a linked list of
+ * polyinstantiated directory structures of type polydir_s. Each entry
+ * in the linked list contains information needed to polyinstantiate
+ * one directory.
+ */
+static int parse_config_file(struct instance_data *idata)
+{
+ FILE *fil;
+ char *home, *rhome;
+ const char *confname;
+ struct passwd *cpwd;
+ char *line;
+ int retval;
+ size_t len = 0;
+ glob_t globbuf;
+ const char *oldlocale;
+ size_t n;
+
+ /*
+ * Extract the user's home directory to resolve $HOME entries
+ * in the namespace configuration file.
+ */
+ cpwd = pam_modutil_getpwnam(idata->pamh, idata->user);
+ if (!cpwd) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error getting home dir for '%s'", idata->user);
+ return PAM_SESSION_ERR;
+ }
+ if ((home=strdup(cpwd->pw_dir)) == NULL) {
+ pam_syslog(idata->pamh, LOG_CRIT,
+ "Memory allocation error");
+ return PAM_SESSION_ERR;
+ }
+
+ cpwd = pam_modutil_getpwnam(idata->pamh, idata->ruser);
+ if (!cpwd) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error getting home dir for '%s'", idata->ruser);
+ free(home);
+ return PAM_SESSION_ERR;
+ }
+
+ if ((rhome=strdup(cpwd->pw_dir)) == NULL) {
+ pam_syslog(idata->pamh, LOG_CRIT,
+ "Memory allocation error");
+ free(home);
+ return PAM_SESSION_ERR;
+ }
+
+ /*
+ * Open configuration file, read one line at a time and call
+ * process_line to process each line.
+ */
+
+ memset(&globbuf, '\0', sizeof(globbuf));
+ oldlocale = setlocale(LC_COLLATE, "C");
+ glob(NAMESPACE_D_GLOB, 0, NULL, &globbuf);
+ if (oldlocale != NULL)
+ setlocale(LC_COLLATE, oldlocale);
+
+ confname = PAM_NAMESPACE_CONFIG;
+ n = 0;
+ for (;;) {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "Parsing config file %s",
+ confname);
+ fil = fopen(confname, "r");
+ if (fil == NULL) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error opening config file %s",
+ confname);
+ globfree(&globbuf);
+ free(rhome);
+ free(home);
+ return PAM_SERVICE_ERR;
+ }
+
+ /* Use unlocked IO */
+ __fsetlocking(fil, FSETLOCKING_BYCALLER);
+
+ line = NULL;
+ /* loop reading the file */
+ while (getline(&line, &len, fil) > 0) {
+ retval = process_line(line, home, rhome, idata);
+ if (retval) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error processing conf file %s line %s", confname, line);
+ fclose(fil);
+ free(line);
+ globfree(&globbuf);
+ free(rhome);
+ free(home);
+ return PAM_SERVICE_ERR;
+ }
+ }
+ fclose(fil);
+ free(line);
+
+ if (n >= globbuf.gl_pathc)
+ break;
+
+ confname = globbuf.gl_pathv[n];
+ n++;
+ }
+
+ globfree(&globbuf);
+ free(rhome);
+ free(home);
+
+ /* All done...just some debug stuff */
+ if (idata->flags & PAMNS_DEBUG) {
+ struct polydir_s *dptr = idata->polydirs_ptr;
+ uid_t *iptr;
+ uid_t i;
+
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ dptr?"Configured poly dirs:":"No configured poly dirs");
+ while (dptr) {
+ pam_syslog(idata->pamh, LOG_DEBUG, "dir='%s' iprefix='%s' meth=%d",
+ dptr->dir, dptr->instance_prefix, dptr->method);
+ for (i = 0, iptr = dptr->uid; i < dptr->num_uids; i++, iptr++)
+ pam_syslog(idata->pamh, LOG_DEBUG, "override user %d ", *iptr);
+ dptr = dptr->next;
+ }
+ }
+
+ return PAM_SUCCESS;
+}
+
+
+/*
+ * This function returns true if a given uid is present in the polyinstantiated
+ * directory's list of override uids. If the uid is one of the override
+ * uids for the polyinstantiated directory, polyinstantiation is not
+ * performed for that user for that directory.
+ * If exclusive is set the returned values are opposite.
+ */
+static int ns_override(struct polydir_s *polyptr, struct instance_data *idata,
+ uid_t uid)
+{
+ unsigned int i;
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Checking for ns override in dir %s for uid %d",
+ polyptr->dir, uid);
+
+ for (i = 0; i < polyptr->num_uids; i++) {
+ if (uid == polyptr->uid[i]) {
+ return !(polyptr->flags & POLYDIR_EXCLUSIVE);
+ }
+ }
+
+ return !!(polyptr->flags & POLYDIR_EXCLUSIVE);
+}
+
+/*
+ * md5hash generates a hash of the passed in instance directory name.
+ */
+static char *md5hash(const char *instname, struct instance_data *idata)
+{
+ int i;
+ char *md5inst = NULL;
+ char *to;
+ unsigned char inst_digest[MD5_DIGEST_LENGTH];
+
+ /*
+ * Create MD5 hashes for instance pathname.
+ */
+
+ MD5((const unsigned char *)instname, strlen(instname), inst_digest);
+
+ if ((md5inst = malloc(MD5_DIGEST_LENGTH * 2 + 1)) == NULL) {
+ pam_syslog(idata->pamh, LOG_CRIT, "Unable to allocate buffer");
+ return NULL;
+ }
+
+ to = md5inst;
+ for (i = 0; i < MD5_DIGEST_LENGTH; i++) {
+ snprintf(to, 3, "%02x", (unsigned int)inst_digest[i]);
+ to += 2;
+ }
+
+ return md5inst;
+}
+
+#ifdef WITH_SELINUX
+static int form_context(const struct polydir_s *polyptr,
+ char **i_context, char **origcon,
+ struct instance_data *idata)
+{
+ int rc = PAM_SUCCESS;
+ char *scon = NULL;
+ security_class_t tclass;
+
+ /*
+ * Get the security context of the directory to polyinstantiate.
+ */
+ rc = getfilecon(polyptr->dir, origcon);
+ if (rc < 0 || *origcon == NULL) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error getting poly dir context, %m");
+ return PAM_SESSION_ERR;
+ }
+
+ if (polyptr->method == USER) return PAM_SUCCESS;
+
+ if (idata->flags & PAMNS_USE_CURRENT_CONTEXT) {
+ rc = getcon(&scon);
+ } else if (idata->flags & PAMNS_USE_DEFAULT_CONTEXT) {
+ char *seuser = NULL, *level = NULL;
+
+ if ((rc=getseuserbyname(idata->user, &seuser, &level)) == 0) {
+ rc = get_default_context_with_level(seuser, level, NULL, &scon);
+ free(seuser);
+ free(level);
+ }
+ } else {
+ rc = getexeccon(&scon);
+ }
+ if (rc < 0 || scon == NULL) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error getting exec context, %m");
+ return PAM_SESSION_ERR;
+ }
+
+ /*
+ * If polyinstantiating based on security context, get current
+ * process security context, get security class for directories,
+ * and ask the policy to provide security context of the
+ * polyinstantiated instance directory.
+ */
+
+ if (polyptr->method == CONTEXT) {
+ tclass = string_to_security_class("dir");
+ if (tclass == 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error getting dir security class");
+ freecon(scon);
+ return PAM_SESSION_ERR;
+ }
+
+ if (security_compute_member(scon, *origcon, tclass,
+ i_context) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error computing poly dir member context");
+ freecon(scon);
+ return PAM_SESSION_ERR;
+ } else if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "member context returned by policy %s", *i_context);
+ freecon(scon);
+ return PAM_SUCCESS;
+ }
+
+ /*
+ * If polyinstantiating based on security level, get current
+ * process security context, get security class for directories,
+ * and change the directories MLS Level to match process.
+ */
+
+ if (polyptr->method == LEVEL) {
+ context_t scontext = NULL;
+ context_t fcontext = NULL;
+ rc = PAM_SESSION_ERR;
+
+ scontext = context_new(scon);
+ if (! scontext) {
+ pam_syslog(idata->pamh, LOG_CRIT, "out of memory");
+ goto fail;
+ }
+ fcontext = context_new(*origcon);
+ if (! fcontext) {
+ pam_syslog(idata->pamh, LOG_CRIT, "out of memory");
+ goto fail;
+ }
+ if (context_range_set(fcontext, context_range_get(scontext)) != 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Unable to set MLS Component of context");
+ goto fail;
+ }
+ *i_context=strdup(context_str(fcontext));
+ if (! *i_context) {
+ pam_syslog(idata->pamh, LOG_CRIT, "out of memory");
+ goto fail;
+ }
+
+ rc = PAM_SUCCESS;
+ fail:
+ context_free(scontext);
+ context_free(fcontext);
+ freecon(scon);
+ return rc;
+ }
+ /* Should never get here */
+ return PAM_SUCCESS;
+}
+#endif
+
+/*
+ * poly_name returns the name of the polyinstantiated instance directory
+ * based on the method used for polyinstantiation (user, context or level)
+ * In addition, the function also returns the security contexts of the
+ * original directory to polyinstantiate and the polyinstantiated instance
+ * directory.
+ */
+#ifdef WITH_SELINUX
+static int poly_name(const struct polydir_s *polyptr, char **i_name,
+ char **i_context, char **origcon,
+ struct instance_data *idata)
+#else
+static int poly_name(const struct polydir_s *polyptr, char **i_name,
+ struct instance_data *idata)
+#endif
+{
+ int rc;
+ char *hash = NULL;
+ enum polymethod pm;
+#ifdef WITH_SELINUX
+ char *rawcon = NULL;
+#endif
+
+ *i_name = NULL;
+#ifdef WITH_SELINUX
+ *i_context = NULL;
+ *origcon = NULL;
+ if ((idata->flags & PAMNS_SELINUX_ENABLED) &&
+ (rc=form_context(polyptr, i_context, origcon, idata)) != PAM_SUCCESS) {
+ return rc;
+ }
+#endif
+
+ rc = PAM_SESSION_ERR;
+ /*
+ * Set the name of the polyinstantiated instance dir based on the
+ * polyinstantiation method.
+ */
+
+ pm = polyptr->method;
+ if (pm == LEVEL || pm == CONTEXT)
+#ifdef WITH_SELINUX
+ if (!(idata->flags & PAMNS_CTXT_BASED_INST)) {
+#else
+ {
+ pam_syslog(idata->pamh, LOG_NOTICE,
+ "Context and level methods not available, using user method");
+#endif
+ if (polyptr->flags & POLYDIR_SHARED) {
+ rc = PAM_IGNORE;
+ goto fail;
+ }
+ pm = USER;
+ }
+
+ switch (pm) {
+ case USER:
+ if (asprintf(i_name, "%s", idata->user) < 0) {
+ *i_name = NULL;
+ goto fail;
+ }
+ break;
+
+#ifdef WITH_SELINUX
+ case LEVEL:
+ case CONTEXT:
+ if (selinux_trans_to_raw_context(*i_context, &rawcon) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error translating directory context");
+ goto fail;
+ }
+ if (polyptr->flags & POLYDIR_SHARED) {
+ if (asprintf(i_name, "%s", rawcon) < 0) {
+ *i_name = NULL;
+ goto fail;
+ }
+ } else {
+ if (asprintf(i_name, "%s_%s", rawcon, idata->user) < 0) {
+ *i_name = NULL;
+ goto fail;
+ }
+ }
+ break;
+
+#endif /* WITH_SELINUX */
+
+ case TMPDIR:
+ case TMPFS:
+ if ((*i_name=strdup("")) == NULL)
+ goto fail;
+ return PAM_SUCCESS;
+
+ default:
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_ERR, "Unknown method");
+ goto fail;
+ }
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "poly_name %s", *i_name);
+
+ if ((idata->flags & PAMNS_GEN_HASH) || strlen(*i_name) > NAMESPACE_MAX_DIR_LEN) {
+ hash = md5hash(*i_name, idata);
+ if (hash == NULL) {
+ goto fail;
+ }
+ if (idata->flags & PAMNS_GEN_HASH) {
+ free(*i_name);
+ *i_name = hash;
+ hash = NULL;
+ } else {
+ char *newname;
+ if (asprintf(&newname, "%.*s_%s", NAMESPACE_MAX_DIR_LEN-1-(int)strlen(hash),
+ *i_name, hash) < 0) {
+ goto fail;
+ }
+ free(*i_name);
+ *i_name = newname;
+ }
+ }
+ rc = PAM_SUCCESS;
+
+fail:
+ free(hash);
+#ifdef WITH_SELINUX
+ freecon(rawcon);
+#endif
+ if (rc != PAM_SUCCESS) {
+#ifdef WITH_SELINUX
+ freecon(*i_context);
+ *i_context = NULL;
+ freecon(*origcon);
+ *origcon = NULL;
+#endif
+ free(*i_name);
+ *i_name = NULL;
+ }
+ return rc;
+}
+
+static int protect_mount(int dfd, const char *path, struct instance_data *idata)
+{
+ struct protect_dir_s *dir = idata->protect_dirs;
+ char tmpbuf[64];
+
+ while (dir != NULL) {
+ if (strcmp(path, dir->dir) == 0) {
+ return 0;
+ }
+ dir = dir->next;
+ }
+
+ dir = calloc(1, sizeof(*dir));
+
+ if (dir == NULL) {
+ return -1;
+ }
+
+ dir->dir = strdup(path);
+
+ if (dir->dir == NULL) {
+ free(dir);
+ return -1;
+ }
+
+ snprintf(tmpbuf, sizeof(tmpbuf), "/proc/self/fd/%d", dfd);
+
+ if (idata->flags & PAMNS_DEBUG) {
+ pam_syslog(idata->pamh, LOG_INFO,
+ "Protect mount of %s over itself", path);
+ }
+
+ if (mount(tmpbuf, tmpbuf, NULL, MS_BIND, NULL) != 0) {
+ int save_errno = errno;
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Protect mount of %s failed: %m", tmpbuf);
+ free(dir->dir);
+ free(dir);
+ errno = save_errno;
+ return -1;
+ }
+
+ dir->next = idata->protect_dirs;
+ idata->protect_dirs = dir;
+
+ return 0;
+}
+
+static int protect_dir(const char *path, mode_t mode, int do_mkdir,
+ struct instance_data *idata)
+{
+ char *p = strdup(path);
+ char *d;
+ char *dir = p;
+ int dfd = AT_FDCWD;
+ int dfd_next;
+ int save_errno;
+ int flags = O_RDONLY;
+ int rv = -1;
+ struct stat st;
+
+ if (p == NULL) {
+ goto error;
+ }
+
+ if (*dir == '/') {
+ dfd = open("/", flags);
+ if (dfd == -1) {
+ goto error;
+ }
+ dir++; /* assume / is safe */
+ }
+
+ while ((d=strchr(dir, '/')) != NULL) {
+ *d = '\0';
+ dfd_next = openat(dfd, dir, flags);
+ if (dfd_next == -1) {
+ goto error;
+ }
+
+ if (dfd != AT_FDCWD)
+ close(dfd);
+ dfd = dfd_next;
+
+ if (fstat(dfd, &st) != 0) {
+ goto error;
+ }
+
+ if (flags & O_NOFOLLOW) {
+ /* we are inside user-owned dir - protect */
+ if (protect_mount(dfd, p, idata) == -1)
+ goto error;
+ } else if (st.st_uid != 0 || st.st_gid != 0 ||
+ (st.st_mode & S_IWOTH)) {
+ /* do not follow symlinks on subdirectories */
+ flags |= O_NOFOLLOW;
+ }
+
+ *d = '/';
+ dir = d + 1;
+ }
+
+ rv = openat(dfd, dir, flags);
+
+ if (rv == -1) {
+ if (!do_mkdir || mkdirat(dfd, dir, mode) != 0) {
+ goto error;
+ }
+ rv = openat(dfd, dir, flags);
+ }
+
+ if (rv != -1) {
+ if (fstat(rv, &st) != 0) {
+ save_errno = errno;
+ close(rv);
+ rv = -1;
+ errno = save_errno;
+ goto error;
+ }
+ if (!S_ISDIR(st.st_mode)) {
+ close(rv);
+ errno = ENOTDIR;
+ rv = -1;
+ goto error;
+ }
+ }
+
+ if (flags & O_NOFOLLOW) {
+ /* we are inside user-owned dir - protect */
+ if (protect_mount(rv, p, idata) == -1) {
+ save_errno = errno;
+ close(rv);
+ rv = -1;
+ errno = save_errno;
+ }
+ }
+
+error:
+ save_errno = errno;
+ free(p);
+ if (dfd != AT_FDCWD && dfd >= 0)
+ close(dfd);
+ errno = save_errno;
+
+ return rv;
+}
+
+static int check_inst_parent(char *ipath, struct instance_data *idata)
+{
+ struct stat instpbuf;
+ char *inst_parent, *trailing_slash;
+ int dfd;
+ /*
+ * stat the instance parent path to make sure it exists
+ * and is a directory. Check that its mode is 000 (unless the
+ * admin explicitly instructs to ignore the instance parent
+ * mode by the "ignore_instance_parent_mode" argument).
+ */
+ inst_parent = (char *) malloc(strlen(ipath)+1);
+ if (!inst_parent) {
+ pam_syslog(idata->pamh, LOG_CRIT, "Error allocating pathname string");
+ return PAM_SESSION_ERR;
+ }
+
+ strcpy(inst_parent, ipath);
+ trailing_slash = strrchr(inst_parent, '/');
+ if (trailing_slash)
+ *trailing_slash = '\0';
+
+ dfd = protect_dir(inst_parent, 0, 1, idata);
+
+ if (dfd == -1 || fstat(dfd, &instpbuf) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error creating or accessing instance parent %s, %m", inst_parent);
+ if (dfd != -1)
+ close(dfd);
+ free(inst_parent);
+ return PAM_SESSION_ERR;
+ }
+
+ if ((idata->flags & PAMNS_IGN_INST_PARENT_MODE) == 0) {
+ if ((instpbuf.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) || instpbuf.st_uid != 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Mode of inst parent %s not 000 or owner not root",
+ inst_parent);
+ close(dfd);
+ free(inst_parent);
+ return PAM_SESSION_ERR;
+ }
+ }
+ close(dfd);
+ free(inst_parent);
+ return PAM_SUCCESS;
+}
+
+/*
+* Check to see if there is a namespace initialization script in
+* the /etc/security directory. If such a script exists
+* execute it and pass directory to polyinstantiate and instance
+* directory as arguments.
+*/
+static int inst_init(const struct polydir_s *polyptr, const char *ipath,
+ struct instance_data *idata, int newdir)
+{
+ pid_t rc, pid;
+ struct sigaction newsa, oldsa;
+ int status;
+ const char *init_script = NAMESPACE_INIT_SCRIPT;
+
+ memset(&newsa, '\0', sizeof(newsa));
+ newsa.sa_handler = SIG_DFL;
+ if (sigaction(SIGCHLD, &newsa, &oldsa) == -1) {
+ pam_syslog(idata->pamh, LOG_ERR, "Cannot set signal value");
+ return PAM_SESSION_ERR;
+ }
+
+ if ((polyptr->flags & POLYDIR_ISCRIPT) && polyptr->init_script)
+ init_script = polyptr->init_script;
+
+ if (access(init_script, F_OK) == 0) {
+ if (access(init_script, X_OK) < 0) {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Namespace init script not executable");
+ rc = PAM_SESSION_ERR;
+ goto out;
+ } else {
+ pid = fork();
+ if (pid == 0) {
+ static char *envp[] = { NULL };
+#ifdef WITH_SELINUX
+ if (idata->flags & PAMNS_SELINUX_ENABLED) {
+ if (setexeccon(NULL) < 0)
+ _exit(1);
+ }
+#endif
+ /* Pass maximum privs when we exec() */
+ if (setuid(geteuid()) < 0) {
+ /* ignore failures, they don't matter */
+ }
+
+ if (execle(init_script, init_script,
+ polyptr->dir, ipath, newdir?"1":"0", idata->user, NULL, envp) < 0)
+ _exit(1);
+ } else if (pid > 0) {
+ while (((rc = waitpid(pid, &status, 0)) == (pid_t)-1) &&
+ (errno == EINTR));
+ if (rc == (pid_t)-1) {
+ pam_syslog(idata->pamh, LOG_ERR, "waitpid failed- %m");
+ rc = PAM_SESSION_ERR;
+ goto out;
+ }
+ if (!WIFEXITED(status) || WIFSIGNALED(status) > 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error initializing instance");
+ rc = PAM_SESSION_ERR;
+ goto out;
+ }
+ } else if (pid < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Cannot fork to run namespace init script, %m");
+ rc = PAM_SESSION_ERR;
+ goto out;
+ }
+ }
+ }
+ rc = PAM_SUCCESS;
+out:
+ (void) sigaction(SIGCHLD, &oldsa, NULL);
+
+ return rc;
+}
+
+static int create_polydir(struct polydir_s *polyptr,
+ struct instance_data *idata)
+{
+ mode_t mode;
+ int rc;
+#ifdef WITH_SELINUX
+ char *dircon_raw, *oldcon_raw = NULL;
+ struct selabel_handle *label_handle;
+#endif
+ const char *dir = polyptr->dir;
+ uid_t uid;
+ gid_t gid;
+
+ if (polyptr->mode != (mode_t)ULONG_MAX)
+ mode = polyptr->mode;
+ else
+ mode = 0777;
+
+#ifdef WITH_SELINUX
+ if (idata->flags & PAMNS_SELINUX_ENABLED) {
+ getfscreatecon_raw(&oldcon_raw);
+
+ label_handle = selabel_open(SELABEL_CTX_FILE, NULL, 0);
+ if (!label_handle) {
+ pam_syslog(idata->pamh, LOG_NOTICE,
+ "Unable to initialize SELinux labeling handle: %m");
+ } else {
+ rc = selabel_lookup_raw(label_handle, &dircon_raw, dir, S_IFDIR);
+ if (rc) {
+ pam_syslog(idata->pamh, LOG_NOTICE,
+ "Unable to get default context for directory %s, check your policy: %m", dir);
+ } else {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Polydir %s context: %s", dir, dircon_raw);
+ if (setfscreatecon_raw(dircon_raw) != 0)
+ pam_syslog(idata->pamh, LOG_NOTICE,
+ "Error setting context for directory %s: %m", dir);
+ freecon(dircon_raw);
+ }
+ selabel_close(label_handle);
+ }
+ }
+#endif
+
+ rc = protect_dir(dir, mode, 1, idata);
+ if (rc == -1) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error creating directory %s: %m", dir);
+ return PAM_SESSION_ERR;
+ }
+
+#ifdef WITH_SELINUX
+ if (idata->flags & PAMNS_SELINUX_ENABLED) {
+ if (setfscreatecon_raw(oldcon_raw) != 0)
+ pam_syslog(idata->pamh, LOG_NOTICE,
+ "Error resetting fs create context: %m");
+ freecon(oldcon_raw);
+ }
+#endif
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "Created polydir %s", dir);
+
+ if (polyptr->mode != (mode_t)ULONG_MAX) {
+ /* explicit mode requested */
+ if (fchmod(rc, mode) != 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error changing mode of directory %s: %m", dir);
+ close(rc);
+ umount(dir); /* undo the eventual protection bind mount */
+ rmdir(dir);
+ return PAM_SESSION_ERR;
+ }
+ }
+
+ if (polyptr->owner != (uid_t)ULONG_MAX)
+ uid = polyptr->owner;
+ else
+ uid = idata->uid;
+
+ if (polyptr->group != (gid_t)ULONG_MAX)
+ gid = polyptr->group;
+ else
+ gid = idata->gid;
+
+ if (fchown(rc, uid, gid) != 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Unable to change owner on directory %s: %m", dir);
+ close(rc);
+ umount(dir); /* undo the eventual protection bind mount */
+ rmdir(dir);
+ return PAM_SESSION_ERR;
+ }
+
+ close(rc);
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Polydir owner %u group %u", uid, gid);
+
+ return PAM_SUCCESS;
+}
+
+/*
+ * Create polyinstantiated instance directory (ipath).
+ */
+#ifdef WITH_SELINUX
+static int create_instance(struct polydir_s *polyptr, char *ipath, struct stat *statbuf,
+ const char *icontext, const char *ocontext,
+ struct instance_data *idata)
+#else
+static int create_instance(struct polydir_s *polyptr, char *ipath, struct stat *statbuf,
+ struct instance_data *idata)
+#endif
+{
+ struct stat newstatbuf;
+ int fd;
+
+ /*
+ * Check to make sure instance parent is valid.
+ */
+ if (check_inst_parent(ipath, idata))
+ return PAM_SESSION_ERR;
+
+ /*
+ * Create instance directory and set its security context to the context
+ * returned by the security policy. Set its mode and ownership
+ * attributes to match that of the original directory that is being
+ * polyinstantiated.
+ */
+
+ if (polyptr->method == TMPDIR) {
+ if (mkdtemp(polyptr->instance_prefix) == NULL) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error creating temporary instance %s, %m",
+ polyptr->instance_prefix);
+ polyptr->method = NONE; /* do not clean up! */
+ return PAM_SESSION_ERR;
+ }
+ /* copy the actual directory name to ipath */
+ strcpy(ipath, polyptr->instance_prefix);
+ } else if (mkdir(ipath, S_IRUSR) < 0) {
+ if (errno == EEXIST)
+ return PAM_IGNORE;
+ else {
+ pam_syslog(idata->pamh, LOG_ERR, "Error creating %s, %m",
+ ipath);
+ return PAM_SESSION_ERR;
+ }
+ }
+
+ /* Open a descriptor to it to prevent races */
+ fd = open(ipath, O_DIRECTORY | O_RDONLY);
+ if (fd < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error opening %s, %m", ipath);
+ rmdir(ipath);
+ return PAM_SESSION_ERR;
+ }
+#ifdef WITH_SELINUX
+ /* If SE Linux is disabled, no need to label it */
+ if (idata->flags & PAMNS_SELINUX_ENABLED) {
+ /* If method is USER, icontext is NULL */
+ if (icontext) {
+ if (fsetfilecon(fd, icontext) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error setting context of %s to %s", ipath, icontext);
+ close(fd);
+ rmdir(ipath);
+ return PAM_SESSION_ERR;
+ }
+ } else {
+ if (fsetfilecon(fd, ocontext) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error setting context of %s to %s", ipath, ocontext);
+ close(fd);
+ rmdir(ipath);
+ return PAM_SESSION_ERR;
+ }
+ }
+ }
+#endif
+ if (fstat(fd, &newstatbuf) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error stating %s, %m",
+ ipath);
+ close(fd);
+ rmdir(ipath);
+ return PAM_SESSION_ERR;
+ }
+ if (newstatbuf.st_uid != statbuf->st_uid ||
+ newstatbuf.st_gid != statbuf->st_gid) {
+ if (fchown(fd, statbuf->st_uid, statbuf->st_gid) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error changing owner for %s, %m",
+ ipath);
+ close(fd);
+ rmdir(ipath);
+ return PAM_SESSION_ERR;
+ }
+ }
+ if (fchmod(fd, statbuf->st_mode & 07777) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error changing mode for %s, %m",
+ ipath);
+ close(fd);
+ rmdir(ipath);
+ return PAM_SESSION_ERR;
+ }
+ close(fd);
+ return PAM_SUCCESS;
+}
+
+
+/*
+ * This function performs the namespace setup for a particular directory
+ * that is being polyinstantiated. It calls poly_name to create name of instance
+ * directory, calls create_instance to mkdir it with appropriate
+ * security attributes, and performs bind mount to setup the process
+ * namespace.
+ */
+static int ns_setup(struct polydir_s *polyptr,
+ struct instance_data *idata)
+{
+ int retval;
+ int newdir = 1;
+ char *inst_dir = NULL;
+ char *instname = NULL;
+ struct stat statbuf;
+#ifdef WITH_SELINUX
+ char *instcontext = NULL, *origcontext = NULL;
+#endif
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Set namespace for directory %s", polyptr->dir);
+
+ retval = protect_dir(polyptr->dir, 0, 0, idata);
+
+ if (retval < 0 && errno != ENOENT) {
+ pam_syslog(idata->pamh, LOG_ERR, "Polydir %s access error: %m",
+ polyptr->dir);
+ return PAM_SESSION_ERR;
+ }
+
+ if (retval < 0) {
+ if ((polyptr->flags & POLYDIR_CREATE) &&
+ create_polydir(polyptr, idata) != PAM_SUCCESS)
+ return PAM_SESSION_ERR;
+ } else {
+ close(retval);
+ }
+
+ if (polyptr->method == TMPFS) {
+ if (mount("tmpfs", polyptr->dir, "tmpfs", polyptr->mount_flags, polyptr->mount_opts) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error mounting tmpfs on %s, %m",
+ polyptr->dir);
+ return PAM_SESSION_ERR;
+ }
+
+ if (polyptr->flags & POLYDIR_NOINIT)
+ return PAM_SUCCESS;
+
+ return inst_init(polyptr, "tmpfs", idata, 1);
+ }
+
+ if (stat(polyptr->dir, &statbuf) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error stating %s: %m",
+ polyptr->dir);
+ return PAM_SESSION_ERR;
+ }
+
+ /*
+ * Obtain the name of instance pathname based on the
+ * polyinstantiation method and instance context returned by
+ * security policy.
+ */
+#ifdef WITH_SELINUX
+ retval = poly_name(polyptr, &instname, &instcontext,
+ &origcontext, idata);
+#else
+ retval = poly_name(polyptr, &instname, idata);
+#endif
+
+ if (retval != PAM_SUCCESS) {
+ if (retval != PAM_IGNORE)
+ pam_syslog(idata->pamh, LOG_ERR, "Error getting instance name");
+ goto cleanup;
+ } else {
+#ifdef WITH_SELINUX
+ if ((idata->flags & PAMNS_DEBUG) &&
+ (idata->flags & PAMNS_SELINUX_ENABLED))
+ pam_syslog(idata->pamh, LOG_DEBUG, "Inst ctxt %s Orig ctxt %s",
+ instcontext, origcontext);
+#endif
+ }
+
+ if (asprintf(&inst_dir, "%s%s", polyptr->instance_prefix, instname) < 0)
+ goto error_out;
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "instance_dir %s",
+ inst_dir);
+
+ /*
+ * Create instance directory with appropriate security
+ * contexts, owner, group and mode bits.
+ */
+#ifdef WITH_SELINUX
+ retval = create_instance(polyptr, inst_dir, &statbuf, instcontext,
+ origcontext, idata);
+#else
+ retval = create_instance(polyptr, inst_dir, &statbuf, idata);
+#endif
+
+ if (retval == PAM_IGNORE) {
+ newdir = 0;
+ retval = PAM_SUCCESS;
+ }
+
+ if (retval != PAM_SUCCESS) {
+ goto error_out;
+ }
+
+ /*
+ * Bind mount instance directory on top of the polyinstantiated
+ * directory to provide an instance of polyinstantiated directory
+ * based on polyinstantiated method.
+ */
+ if (mount(inst_dir, polyptr->dir, NULL, MS_BIND, NULL) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error mounting %s on %s, %m",
+ inst_dir, polyptr->dir);
+ goto error_out;
+ }
+
+ if (!(polyptr->flags & POLYDIR_NOINIT))
+ retval = inst_init(polyptr, inst_dir, idata, newdir);
+
+ goto cleanup;
+
+ /*
+ * various error exit points. Free allocated memory and set return
+ * value to indicate a pam session error.
+ */
+error_out:
+ retval = PAM_SESSION_ERR;
+
+cleanup:
+ free(inst_dir);
+ free(instname);
+#ifdef WITH_SELINUX
+ freecon(instcontext);
+ freecon(origcontext);
+#endif
+ return retval;
+}
+
+
+/*
+ * This function checks to see if the current working directory is
+ * inside the directory passed in as the first argument.
+ */
+static int cwd_in(char *dir, struct instance_data *idata)
+{
+ int retval = 0;
+ char cwd[PATH_MAX];
+
+ if (getcwd(cwd, PATH_MAX) == NULL) {
+ pam_syslog(idata->pamh, LOG_ERR, "Can't get current dir, %m");
+ return -1;
+ }
+
+ if (strncmp(cwd, dir, strlen(dir)) == 0) {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "cwd is inside %s", dir);
+ retval = 1;
+ } else {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "cwd is outside %s", dir);
+ }
+
+ return retval;
+}
+
+static int cleanup_tmpdirs(struct instance_data *idata)
+{
+ struct polydir_s *pptr;
+ pid_t rc, pid;
+ struct sigaction newsa, oldsa;
+ int status;
+
+ memset(&newsa, '\0', sizeof(newsa));
+ newsa.sa_handler = SIG_DFL;
+ if (sigaction(SIGCHLD, &newsa, &oldsa) == -1) {
+ pam_syslog(idata->pamh, LOG_ERR, "Cannot set signal value");
+ return PAM_SESSION_ERR;
+ }
+
+ for (pptr = idata->polydirs_ptr; pptr; pptr = pptr->next) {
+ if (pptr->method == TMPDIR && access(pptr->instance_prefix, F_OK) == 0) {
+ pid = fork();
+ if (pid == 0) {
+ static char *envp[] = { NULL };
+#ifdef WITH_SELINUX
+ if (idata->flags & PAMNS_SELINUX_ENABLED) {
+ if (setexeccon(NULL) < 0)
+ _exit(1);
+ }
+#endif
+ if (execle("/bin/rm", "/bin/rm", "-rf", pptr->instance_prefix, NULL, envp) < 0)
+ _exit(1);
+ } else if (pid > 0) {
+ while (((rc = waitpid(pid, &status, 0)) == (pid_t)-1) &&
+ (errno == EINTR));
+ if (rc == (pid_t)-1) {
+ pam_syslog(idata->pamh, LOG_ERR, "waitpid failed: %m");
+ rc = PAM_SESSION_ERR;
+ goto out;
+ }
+ if (!WIFEXITED(status) || WIFSIGNALED(status) > 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error removing %s", pptr->instance_prefix);
+ }
+ } else if (pid < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Cannot fork to run namespace init script, %m");
+ rc = PAM_SESSION_ERR;
+ goto out;
+ }
+ }
+ }
+
+ rc = PAM_SUCCESS;
+out:
+ sigaction(SIGCHLD, &oldsa, NULL);
+ return rc;
+}
+
+/*
+ * This function checks to see if polyinstantiation is needed for any
+ * of the directories listed in the configuration file. If needed,
+ * cycles through all polyinstantiated directory entries and calls
+ * ns_setup to setup polyinstantiation for each one of them.
+ */
+static int setup_namespace(struct instance_data *idata, enum unmnt_op unmnt)
+{
+ int retval = 0, need_poly = 0, changing_dir = 0;
+ char *cptr, *fptr, poly_parent[PATH_MAX];
+ struct polydir_s *pptr;
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "Set up namespace for pid %d",
+ getpid());
+
+ /*
+ * Cycle through all polyinstantiated directory entries to see if
+ * polyinstantiation is needed at all.
+ */
+ for (pptr = idata->polydirs_ptr; pptr; pptr = pptr->next) {
+ if (ns_override(pptr, idata, idata->uid)) {
+ if (unmnt == NO_UNMNT || ns_override(pptr, idata, idata->ruid)) {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Overriding poly for user %d for dir %s",
+ idata->uid, pptr->dir);
+ } else {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Need unmount ns for user %d for dir %s",
+ idata->ruid, pptr->dir);
+ need_poly = 1;
+ break;
+ }
+ continue;
+ } else {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Need poly ns for user %d for dir %s",
+ idata->uid, pptr->dir);
+ need_poly = 1;
+ break;
+ }
+ }
+
+ /*
+ * If polyinstantiation is needed, call the unshare system call to
+ * disassociate from the parent namespace.
+ */
+ if (need_poly) {
+ if (unshare(CLONE_NEWNS) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Unable to unshare from parent namespace, %m");
+ return PAM_SESSION_ERR;
+ }
+ if (idata->flags & PAMNS_MOUNT_PRIVATE) {
+ /*
+ * Remount / as SLAVE so that nothing mounted in the namespace
+ * shows up in the parent
+ */
+ if (mount("/", "/", NULL, MS_SLAVE | MS_REC , NULL) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Failed to mark / as a slave mount point, %m");
+ return PAM_SESSION_ERR;
+ }
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "The / mount point was marked as slave");
+ }
+ } else {
+ del_polydir_list(idata->polydirs_ptr);
+ return PAM_SUCCESS;
+ }
+
+ /*
+ * Again cycle through all polyinstantiated directories, this time,
+ * call ns_setup to setup polyinstantiation for a particular entry.
+ */
+ for (pptr = idata->polydirs_ptr; pptr; pptr = pptr->next) {
+ enum unmnt_op dir_unmnt = unmnt;
+
+ if (ns_override(pptr, idata, idata->ruid)) {
+ dir_unmnt = NO_UNMNT;
+ }
+ if (ns_override(pptr, idata, idata->uid)) {
+ if (dir_unmnt == NO_UNMNT) {
+ continue;
+ } else {
+ dir_unmnt = UNMNT_ONLY;
+ }
+ }
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Setting poly ns for user %d for dir %s",
+ idata->uid, pptr->dir);
+
+ if ((dir_unmnt == UNMNT_REMNT) || (dir_unmnt == UNMNT_ONLY)) {
+ /*
+ * Check to see if process current directory is in the
+ * bind mounted instance_parent directory that we are trying to
+ * umount
+ */
+ if ((changing_dir = cwd_in(pptr->rdir, idata)) < 0) {
+ retval = PAM_SESSION_ERR;
+ goto out;
+ } else if (changing_dir) {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "changing cwd");
+
+ /*
+ * Change current working directory to the parent of
+ * the mount point, that is parent of the orig
+ * directory where original contents of the polydir
+ * are available from
+ */
+ strcpy(poly_parent, pptr->rdir);
+ fptr = strchr(poly_parent, '/');
+ cptr = strrchr(poly_parent, '/');
+ if (fptr && cptr && (fptr == cptr))
+ strcpy(poly_parent, "/");
+ else if (cptr)
+ *cptr = '\0';
+ if (chdir(poly_parent) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Can't chdir to %s, %m", poly_parent);
+ }
+ }
+
+ if (umount(pptr->rdir) < 0) {
+ int saved_errno = errno;
+ pam_syslog(idata->pamh, LOG_ERR, "Unmount of %s failed, %m",
+ pptr->rdir);
+ if (saved_errno != EINVAL) {
+ retval = PAM_SESSION_ERR;
+ goto out;
+ }
+ } else if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "Umount succeeded %s",
+ pptr->rdir);
+ }
+
+ if (dir_unmnt != UNMNT_ONLY) {
+ retval = ns_setup(pptr, idata);
+ if (retval == PAM_IGNORE)
+ retval = PAM_SUCCESS;
+ if (retval != PAM_SUCCESS)
+ break;
+ }
+ }
+out:
+ if (retval != PAM_SUCCESS) {
+ cleanup_tmpdirs(idata);
+ unprotect_dirs(idata->protect_dirs);
+ } else if (pam_set_data(idata->pamh, NAMESPACE_PROTECT_DATA, idata->protect_dirs,
+ cleanup_protect_data) != PAM_SUCCESS) {
+ pam_syslog(idata->pamh, LOG_ERR, "Unable to set namespace protect data");
+ cleanup_tmpdirs(idata);
+ unprotect_dirs(idata->protect_dirs);
+ return PAM_SYSTEM_ERR;
+ } else if (pam_set_data(idata->pamh, NAMESPACE_POLYDIR_DATA, idata->polydirs_ptr,
+ cleanup_polydir_data) != PAM_SUCCESS) {
+ pam_syslog(idata->pamh, LOG_ERR, "Unable to set namespace polydir data");
+ cleanup_tmpdirs(idata);
+ pam_set_data(idata->pamh, NAMESPACE_PROTECT_DATA, NULL, NULL);
+ idata->protect_dirs = NULL;
+ return PAM_SYSTEM_ERR;
+ }
+ return retval;
+}
+
+
+/*
+ * Orig namespace. This function is called from when closing a pam
+ * session. If authorized, it unmounts instance directory.
+ */
+static int orig_namespace(struct instance_data *idata)
+{
+ struct polydir_s *pptr;
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "orig namespace for pid %d",
+ getpid());
+
+ /*
+ * Cycle through all polyinstantiated directories from the namespace
+ * configuration file to see if polyinstantiation was performed for
+ * this user for each of the entry. If it was, try and unmount
+ * appropriate polyinstantiated instance directories.
+ */
+ for (pptr = idata->polydirs_ptr; pptr; pptr = pptr->next) {
+ if (ns_override(pptr, idata, idata->uid))
+ continue;
+ else {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Unmounting instance dir for user %d & dir %s",
+ idata->uid, pptr->dir);
+
+ if (umount(pptr->dir) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Unmount of %s failed, %m",
+ pptr->dir);
+ return PAM_SESSION_ERR;
+ } else if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "Unmount of %s succeeded",
+ pptr->dir);
+ }
+ }
+
+ cleanup_tmpdirs(idata);
+ return 0;
+}
+
+
+#ifdef WITH_SELINUX
+/*
+ * This function checks if the calling program has requested context
+ * change by calling setexeccon(). If context change is not requested
+ * then it does not make sense to polyinstantiate based on context.
+ * The return value from this function is used when selecting the
+ * polyinstantiation method. If context change is not requested then
+ * the polyinstantiation method is set to USER, even if the configuration
+ * file lists the method as "context" or "level".
+ */
+static int ctxt_based_inst_needed(void)
+{
+ char *scon = NULL;
+ int rc = 0;
+
+ rc = getexeccon(&scon);
+ if (rc < 0 || scon == NULL)
+ return 0;
+ else {
+ freecon(scon);
+ return 1;
+ }
+}
+#endif
+
+static int root_shared(void)
+{
+ FILE *f;
+ char *line = NULL;
+ size_t n = 0;
+ int rv = 0;
+
+ f = fopen("/proc/self/mountinfo", "r");
+
+ if (f == NULL)
+ return 0;
+
+ while(getline(&line, &n, f) != -1) {
+ char *l;
+ char *sptr;
+ int i;
+
+ l = line;
+ sptr = NULL;
+ for (i = 0; i < 7; i++) {
+ char *tok;
+
+ tok = strtok_r(l, " ", &sptr);
+ l = NULL;
+ if (tok == NULL)
+ /* next mountinfo line */
+ break;
+
+ if (i == 4 && strcmp(tok, "/") != 0)
+ /* next mountinfo line */
+ break;
+
+ if (i == 6) {
+ if (pam_str_skip_prefix(tok, "shared:") != NULL)
+ /* there might be more / mounts, the last one counts */
+ rv = 1;
+ else
+ rv = 0;
+ }
+ }
+ }
+
+ free(line);
+ fclose(f);
+
+ return rv;
+}
+
+static int get_user_data(struct instance_data *idata)
+{
+ int retval;
+ char *user_name;
+ struct passwd *pwd;
+ /*
+ * Lookup user and fill struct items
+ */
+ retval = pam_get_item(idata->pamh, PAM_USER, (void*) &user_name );
+ if ( user_name == NULL || retval != PAM_SUCCESS ) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error recovering pam user name");
+ return PAM_SESSION_ERR;
+ }
+
+ pwd = pam_modutil_getpwnam(idata->pamh, user_name);
+ if (!pwd) {
+ pam_syslog(idata->pamh, LOG_ERR, "user unknown '%s'", user_name);
+ return PAM_USER_UNKNOWN;
+ }
+
+ /*
+ * Add the user info to the instance data so we can refer to them later.
+ */
+ idata->user[0] = 0;
+ strncat(idata->user, user_name, sizeof(idata->user) - 1);
+ idata->uid = pwd->pw_uid;
+ idata->gid = pwd->pw_gid;
+
+ /* Fill in RUSER too */
+ retval = pam_get_item(idata->pamh, PAM_RUSER, (void*) &user_name );
+ if ( user_name != NULL && retval == PAM_SUCCESS && user_name[0] != '\0' ) {
+ strncat(idata->ruser, user_name, sizeof(idata->ruser) - 1);
+ pwd = pam_modutil_getpwnam(idata->pamh, user_name);
+ } else {
+ pwd = pam_modutil_getpwuid(idata->pamh, getuid());
+ }
+ if (!pwd) {
+ pam_syslog(idata->pamh, LOG_ERR, "user unknown '%s'", user_name);
+ return PAM_USER_UNKNOWN;
+ }
+ user_name = pwd->pw_name;
+
+ idata->ruser[0] = 0;
+ strncat(idata->ruser, user_name, sizeof(idata->ruser) - 1);
+ idata->ruid = pwd->pw_uid;
+
+ return PAM_SUCCESS;
+}
+
+/*
+ * Entry point from pam_open_session call.
+ */
+int pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ int i, retval;
+ struct instance_data idata;
+ enum unmnt_op unmnt = NO_UNMNT;
+
+ /* init instance data */
+ idata.flags = 0;
+ idata.polydirs_ptr = NULL;
+ idata.protect_dirs = NULL;
+ idata.pamh = pamh;
+#ifdef WITH_SELINUX
+ if (is_selinux_enabled())
+ idata.flags |= PAMNS_SELINUX_ENABLED;
+ if (ctxt_based_inst_needed())
+ idata.flags |= PAMNS_CTXT_BASED_INST;
+#endif
+
+ /* Parse arguments. */
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "debug") == 0)
+ idata.flags |= PAMNS_DEBUG;
+ if (strcmp(argv[i], "gen_hash") == 0)
+ idata.flags |= PAMNS_GEN_HASH;
+ if (strcmp(argv[i], "ignore_config_error") == 0)
+ idata.flags |= PAMNS_IGN_CONFIG_ERR;
+ if (strcmp(argv[i], "ignore_instance_parent_mode") == 0)
+ idata.flags |= PAMNS_IGN_INST_PARENT_MODE;
+ if (strcmp(argv[i], "use_current_context") == 0) {
+ idata.flags |= PAMNS_USE_CURRENT_CONTEXT;
+ idata.flags |= PAMNS_CTXT_BASED_INST;
+ }
+ if (strcmp(argv[i], "use_default_context") == 0) {
+ idata.flags |= PAMNS_USE_DEFAULT_CONTEXT;
+ idata.flags |= PAMNS_CTXT_BASED_INST;
+ }
+ if (strcmp(argv[i], "mount_private") == 0) {
+ idata.flags |= PAMNS_MOUNT_PRIVATE;
+ }
+ if (strcmp(argv[i], "unmnt_remnt") == 0)
+ unmnt = UNMNT_REMNT;
+ if (strcmp(argv[i], "unmnt_only") == 0)
+ unmnt = UNMNT_ONLY;
+ if (strcmp(argv[i], "require_selinux") == 0) {
+ if (!(idata.flags & PAMNS_SELINUX_ENABLED)) {
+ pam_syslog(idata.pamh, LOG_ERR,
+ "selinux_required option given and selinux is disabled");
+ return PAM_SESSION_ERR;
+ }
+ }
+ }
+ if (idata.flags & PAMNS_DEBUG)
+ pam_syslog(idata.pamh, LOG_DEBUG, "open_session - start");
+
+ retval = get_user_data(&idata);
+ if (retval != PAM_SUCCESS)
+ return retval;
+
+ if (root_shared()) {
+ idata.flags |= PAMNS_MOUNT_PRIVATE;
+ }
+
+ /*
+ * Parse namespace configuration file which lists directories to
+ * polyinstantiate, directory where instance directories are to
+ * be created and the method used for polyinstantiation.
+ */
+ retval = parse_config_file(&idata);
+ if (retval != PAM_SUCCESS) {
+ del_polydir_list(idata.polydirs_ptr);
+ return PAM_SESSION_ERR;
+ }
+
+ if (idata.polydirs_ptr) {
+ retval = setup_namespace(&idata, unmnt);
+ if (idata.flags & PAMNS_DEBUG) {
+ if (retval)
+ pam_syslog(idata.pamh, LOG_DEBUG,
+ "namespace setup failed for pid %d", getpid());
+ else
+ pam_syslog(idata.pamh, LOG_DEBUG,
+ "namespace setup ok for pid %d", getpid());
+ }
+ } else if (idata.flags & PAMNS_DEBUG)
+ pam_syslog(idata.pamh, LOG_DEBUG, "Nothing to polyinstantiate");
+
+ if (retval != PAM_SUCCESS)
+ del_polydir_list(idata.polydirs_ptr);
+ return retval;
+}
+
+
+/*
+ * Entry point from pam_close_session call.
+ */
+int pam_sm_close_session(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ int i, retval;
+ struct instance_data idata;
+ const void *polyptr;
+
+ /* init instance data */
+ idata.flags = 0;
+ idata.polydirs_ptr = NULL;
+ idata.pamh = pamh;
+#ifdef WITH_SELINUX
+ if (is_selinux_enabled())
+ idata.flags |= PAMNS_SELINUX_ENABLED;
+ if (ctxt_based_inst_needed())
+ idata.flags |= PAMNS_CTXT_BASED_INST;
+#endif
+
+ /* Parse arguments. */
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "debug") == 0)
+ idata.flags |= PAMNS_DEBUG;
+ if (strcmp(argv[i], "ignore_config_error") == 0)
+ idata.flags |= PAMNS_IGN_CONFIG_ERR;
+ if (strcmp(argv[i], "unmount_on_close") == 0)
+ idata.flags |= PAMNS_UNMOUNT_ON_CLOSE;
+ }
+
+ if (idata.flags & PAMNS_DEBUG)
+ pam_syslog(idata.pamh, LOG_DEBUG, "close_session - start");
+
+ /*
+ * Normally the unmount is implicitly done when the last
+ * process in the private namespace exits.
+ * If it is ensured that there are no child processes left in
+ * the private namespace by other means and if there are
+ * multiple sessions opened and closed sequentially by the
+ * same process, the "unmount_on_close" option might be
+ * used to unmount the polydirs explicitly.
+ */
+ if (!(idata.flags & PAMNS_UNMOUNT_ON_CLOSE)) {
+ pam_set_data(idata.pamh, NAMESPACE_POLYDIR_DATA, NULL, NULL);
+ pam_set_data(idata.pamh, NAMESPACE_PROTECT_DATA, NULL, NULL);
+
+ if (idata.flags & PAMNS_DEBUG)
+ pam_syslog(idata.pamh, LOG_DEBUG, "close_session - successful");
+ return PAM_SUCCESS;
+ }
+
+ retval = get_user_data(&idata);
+ if (retval != PAM_SUCCESS)
+ return retval;
+
+ retval = pam_get_data(idata.pamh, NAMESPACE_POLYDIR_DATA, &polyptr);
+ if (retval != PAM_SUCCESS || polyptr == NULL)
+ /* nothing to reset */
+ return PAM_SUCCESS;
+
+ DIAG_PUSH_IGNORE_CAST_QUAL;
+ idata.polydirs_ptr = (void *)polyptr;
+ DIAG_POP_IGNORE_CAST_QUAL;
+
+ if (idata.flags & PAMNS_DEBUG)
+ pam_syslog(idata.pamh, LOG_DEBUG, "Resetting namespace for pid %d",
+ getpid());
+
+ retval = orig_namespace(&idata);
+ if (idata.flags & PAMNS_DEBUG) {
+ if (retval)
+ pam_syslog(idata.pamh, LOG_DEBUG,
+ "resetting namespace failed for pid %d", getpid());
+ else
+ pam_syslog(idata.pamh, LOG_DEBUG,
+ "resetting namespace ok for pid %d", getpid());
+ }
+
+ pam_set_data(idata.pamh, NAMESPACE_POLYDIR_DATA, NULL, NULL);
+ pam_set_data(idata.pamh, NAMESPACE_PROTECT_DATA, NULL, NULL);
+
+ return PAM_SUCCESS;
+}
diff --git a/modules/pam_namespace/pam_namespace.h b/modules/pam_namespace/pam_namespace.h
new file mode 100644
index 0000000..b51f284
--- /dev/null
+++ b/modules/pam_namespace/pam_namespace.h
@@ -0,0 +1,192 @@
+/******************************************************************************
+ * A module for Linux-PAM that will set the default namespace after
+ * establishing a session via PAM.
+ *
+ * (C) Copyright IBM Corporation 2005
+ * (C) Copyright Red Hat 2006
+ * All Rights Reserved.
+ *
+ * Written by: Janak Desai <janak@us.ibm.com>
+ * With Revisions by: Steve Grubb <sgrubb@redhat.com>
+ * Derived from a namespace setup patch by Chad Sellers <cdselle@tycho.nsa.gov>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#if !(defined(linux))
+#error THIS CODE IS KNOWN TO WORK ONLY ON LINUX !!!
+#endif
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <syslog.h>
+#include <dlfcn.h>
+#include <stdarg.h>
+#include <pwd.h>
+#include <grp.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/resource.h>
+#include <sys/mount.h>
+#include <sys/wait.h>
+#include <libgen.h>
+#include <fcntl.h>
+#include <sched.h>
+#include <glob.h>
+#include <locale.h>
+#include "security/pam_modules.h"
+#include "security/pam_modutil.h"
+#include "security/pam_ext.h"
+#include "md5.h"
+
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#include <selinux/get_context_list.h>
+#include <selinux/context.h>
+#include <selinux/label.h>
+#endif
+
+#ifndef CLONE_NEWNS
+#define CLONE_NEWNS 0x00020000 /* Flag to create new namespace */
+#endif
+
+/* mount flags for mount_private */
+#ifndef MS_REC
+#define MS_REC (1<<14)
+#endif
+#ifndef MS_PRIVATE
+#define MS_PRIVATE (1<<18)
+#endif
+#ifndef MS_SLAVE
+#define MS_SLAVE (1<<19)
+#endif
+
+
+/*
+ * Module defines
+ */
+#ifndef SECURECONF_DIR
+#define SECURECONF_DIR "/etc/security/"
+#endif
+
+#define PAM_NAMESPACE_CONFIG (SECURECONF_DIR "namespace.conf")
+#define NAMESPACE_INIT_SCRIPT (SECURECONF_DIR "namespace.init")
+#define NAMESPACE_D_DIR (SECURECONF_DIR "namespace.d/")
+#define NAMESPACE_D_GLOB (SECURECONF_DIR "namespace.d/*.conf")
+
+/* module flags */
+#define PAMNS_DEBUG 0x00000100 /* Running in debug mode */
+#define PAMNS_SELINUX_ENABLED 0x00000400 /* SELinux is enabled */
+#define PAMNS_CTXT_BASED_INST 0x00000800 /* Context based instance needed */
+#define PAMNS_GEN_HASH 0x00002000 /* Generate md5 hash for inst names */
+#define PAMNS_IGN_CONFIG_ERR 0x00004000 /* Ignore format error in conf file */
+#define PAMNS_IGN_INST_PARENT_MODE 0x00008000 /* Ignore instance parent mode */
+#define PAMNS_UNMOUNT_ON_CLOSE 0x00010000 /* Unmount at session close */
+#define PAMNS_USE_CURRENT_CONTEXT 0x00020000 /* use getcon instead of getexeccon */
+#define PAMNS_USE_DEFAULT_CONTEXT 0x00040000 /* use get_default_context instead of getexeccon */
+#define PAMNS_MOUNT_PRIVATE 0x00080000 /* Make the polydir mounts private */
+
+/* polydir flags */
+#define POLYDIR_EXCLUSIVE 0x00000001 /* polyinstatiate exclusively for override uids */
+#define POLYDIR_CREATE 0x00000002 /* create the polydir */
+#define POLYDIR_NOINIT 0x00000004 /* no init script */
+#define POLYDIR_SHARED 0x00000008 /* share context/level instances among users */
+#define POLYDIR_ISCRIPT 0x00000010 /* non default init script */
+#define POLYDIR_MNTOPTS 0x00000020 /* mount options for tmpfs mount */
+
+
+#define NAMESPACE_MAX_DIR_LEN 80
+#define NAMESPACE_POLYDIR_DATA "pam_namespace:polydir_data"
+#define NAMESPACE_PROTECT_DATA "pam_namespace:protect_data"
+
+/*
+ * Polyinstantiation method options, based on user, security context
+ * or both
+ */
+enum polymethod {
+ NONE,
+ USER,
+ CONTEXT,
+ LEVEL,
+ TMPDIR,
+ TMPFS
+};
+
+/*
+ * Depending on the application using this namespace module, we
+ * may need to unmount previously bind mounted instance directory.
+ * Applications such as login and sshd, that establish a new
+ * session unmount of instance directory is not needed. For applications
+ * such as su and newrole, that switch the identity, this module
+ * has to unmount previous instance directory first and re-mount
+ * based on the new identity. For other trusted applications that
+ * just want to undo polyinstantiation, only unmount of previous
+ * instance directory is needed.
+ */
+enum unmnt_op {
+ NO_UNMNT,
+ UNMNT_REMNT,
+ UNMNT_ONLY,
+};
+
+/*
+ * Structure that holds information about a directory to polyinstantiate
+ */
+struct polydir_s {
+ char dir[PATH_MAX]; /* directory to polyinstantiate */
+ char rdir[PATH_MAX]; /* directory to unmount (based on RUSER) */
+ char instance_prefix[PATH_MAX]; /* prefix for instance dir path name */
+ enum polymethod method; /* method used to polyinstantiate */
+ unsigned int num_uids; /* number of override uids */
+ uid_t *uid; /* list of override uids */
+ unsigned int flags; /* polydir flags */
+ char *init_script; /* path to init script */
+ char *mount_opts; /* mount options for tmpfs mount */
+ unsigned long mount_flags; /* mount flags for tmpfs mount */
+ uid_t owner; /* user which should own the polydir */
+ gid_t group; /* group which should own the polydir */
+ mode_t mode; /* mode of the polydir */
+ struct polydir_s *next; /* pointer to the next polydir entry */
+};
+
+struct protect_dir_s {
+ char *dir; /* protected directory */
+ struct protect_dir_s *next; /* next entry */
+};
+
+struct instance_data {
+ pam_handle_t *pamh; /* The pam handle for this instance */
+ struct polydir_s *polydirs_ptr; /* The linked list pointer */
+ struct protect_dir_s *protect_dirs; /* The pointer to stack of mount-protected dirs */
+ char user[LOGIN_NAME_MAX]; /* User name */
+ char ruser[LOGIN_NAME_MAX]; /* Requesting user name */
+ uid_t uid; /* The uid of the user */
+ gid_t gid; /* The gid of the user's primary group */
+ uid_t ruid; /* The uid of the requesting user */
+ unsigned long flags; /* Flags for debug, selinux etc */
+};
diff --git a/modules/pam_namespace/pam_namespace.service.in b/modules/pam_namespace/pam_namespace.service.in
new file mode 100644
index 0000000..e231191
--- /dev/null
+++ b/modules/pam_namespace/pam_namespace.service.in
@@ -0,0 +1,11 @@
+[Unit]
+After=local-fs.target
+Before=multi-user.target shutdown.target
+Conflicts=shutdown.target
+DefaultDependencies=no
+Description=Make sure parent directories configured in @SCONFIGDIR@/namespace.conf for polyinstantiation exist
+Documentation=man:pam_namespace(8)
+
+[Service]
+ExecStart=@sbindir@/pam_namespace_helper
+Type=oneshot
diff --git a/modules/pam_namespace/pam_namespace_helper.8 b/modules/pam_namespace/pam_namespace_helper.8
new file mode 100644
index 0000000..df93df2
--- /dev/null
+++ b/modules/pam_namespace/pam_namespace_helper.8
@@ -0,0 +1,49 @@
+'\" t
+.\" Title: pam_namespace_helper
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_NAMESPACE_HELPER" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_namespace_helper \- Helper binary that creates home directories
+.SH "SYNOPSIS"
+.HP \w'\fBpam_namespace_helper\fR\ 'u
+\fBpam_namespace_helper\fR
+.SH "DESCRIPTION"
+.PP
+\fIpam_namespace_helper\fR
+is a helper program for the
+\fIpam_namespace\fR
+module that sets up a private namespace for a session with polyinstantiated directories\&. The helper ensures that the namespace mount points exist before they are started to be used for the polyinstantiated directories\&. Mount points for home directories (lines with $HOME) are not created\&.
+.PP
+\fIpam_namespace_helper\fR
+should be run by systemd at system startup\&. It should also be run by the administrator after defining the polyinstantiated directories but before enabling them\&.
+.SH "SEE ALSO"
+.PP
+\fBpam_namespace\fR(8)
+.SH "AUTHOR"
+.PP
+Written by Topi Miettinen\&.
diff --git a/modules/pam_namespace/pam_namespace_helper.8.xml b/modules/pam_namespace/pam_namespace_helper.8.xml
new file mode 100644
index 0000000..2f5adbe
--- /dev/null
+++ b/modules/pam_namespace/pam_namespace_helper.8.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_namespace_helper">
+
+ <refmeta>
+ <refentrytitle>pam_namespace_helper</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_namespace_helper-name">
+ <refname>pam_namespace_helper</refname>
+ <refpurpose>Helper binary that creates home directories</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_namespace_helper-cmdsynopsis">
+ <command>pam_namespace_helper</command>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_namespace_helper-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ <emphasis>pam_namespace_helper</emphasis> is a helper program
+ for the <emphasis>pam_namespace</emphasis> module that sets up a
+ private namespace for a session with polyinstantiated
+ directories. The helper ensures that the namespace mount points
+ exist before they are started to be used for the
+ polyinstantiated directories. Mount points for home directories
+ (lines with $HOME) are not created.
+ </para>
+
+ <para>
+ <emphasis>pam_namespace_helper</emphasis> should be run by
+ systemd at system startup. It should also be run by the
+ administrator after defining the polyinstantiated directories
+ but before enabling them.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_namespace_helper-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam_namespace</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_namespace_helper-author'>
+ <title>AUTHOR</title>
+ <para>
+ Written by Topi Miettinen.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_namespace/pam_namespace_helper.in b/modules/pam_namespace/pam_namespace_helper.in
new file mode 100644
index 0000000..b9c361f
--- /dev/null
+++ b/modules/pam_namespace/pam_namespace_helper.in
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+CONF=@SCONFIGDIR@/namespace.conf
+
+# Match logic of process_line(), except lines with $HOME are ignored
+# skip the leading white space, rip off the comments, ignore empty lines
+sed -e 's/^[ ]*//g' -e 's/#.*//g' -e '/.*\$HOME.*/d' -e '/^$/d' < $CONF | \
+ while read polydir instance_prefix method uids; do
+ if [ ! -e "$instance_prefix" ]; then
+ echo "mkdir $instance_prefix"
+ mkdir --parents --mode=0 -Z "$instance_prefix"
+ fi
+ done
+
+exit 0
diff --git a/modules/pam_namespace/tst-pam_namespace b/modules/pam_namespace/tst-pam_namespace
new file mode 100755
index 0000000..c929dfc
--- /dev/null
+++ b/modules/pam_namespace/tst-pam_namespace
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_namespace.so
diff --git a/modules/pam_nologin/Makefile.am b/modules/pam_nologin/Makefile.am
new file mode 100644
index 0000000..d1ec203
--- /dev/null
+++ b/modules/pam_nologin/Makefile.am
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_nologin.8
+endif
+XMLS = README.xml pam_nologin.8.xml
+dist_check_SCRIPTS = tst-pam_nologin
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_nologin.la
+pam_nologin_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+check_PROGRAMS = tst-pam_nologin-retval
+tst_pam_nologin_retval_LDADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_nologin/Makefile.in b/modules/pam_nologin/Makefile.in
new file mode 100644
index 0000000..0e84bd6
--- /dev/null
+++ b/modules/pam_nologin/Makefile.in
@@ -0,0 +1,1181 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+check_PROGRAMS = tst-pam_nologin-retval$(EXEEXT)
+subdir = modules/pam_nologin
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_nologin_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_nologin_la_SOURCES = pam_nologin.c
+pam_nologin_la_OBJECTS = pam_nologin.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+tst_pam_nologin_retval_SOURCES = tst-pam_nologin-retval.c
+tst_pam_nologin_retval_OBJECTS = tst-pam_nologin-retval.$(OBJEXT)
+tst_pam_nologin_retval_DEPENDENCIES = \
+ $(top_builddir)/libpam/libpam.la
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_nologin.Plo \
+ ./$(DEPDIR)/tst-pam_nologin-retval.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_nologin.c tst-pam_nologin-retval.c
+DIST_SOURCES = pam_nologin.c tst-pam_nologin-retval.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_nologin.8
+XMLS = README.xml pam_nologin.8.xml
+dist_check_SCRIPTS = tst-pam_nologin
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_nologin.la
+pam_nologin_la_LIBADD = $(top_builddir)/libpam/libpam.la
+tst_pam_nologin_retval_LDADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_nologin/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_nologin/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_nologin.la: $(pam_nologin_la_OBJECTS) $(pam_nologin_la_DEPENDENCIES) $(EXTRA_pam_nologin_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_nologin_la_OBJECTS) $(pam_nologin_la_LIBADD) $(LIBS)
+
+tst-pam_nologin-retval$(EXEEXT): $(tst_pam_nologin_retval_OBJECTS) $(tst_pam_nologin_retval_DEPENDENCIES) $(EXTRA_tst_pam_nologin_retval_DEPENDENCIES)
+ @rm -f tst-pam_nologin-retval$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tst_pam_nologin_retval_OBJECTS) $(tst_pam_nologin_retval_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_nologin.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-pam_nologin-retval.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_nologin.log: tst-pam_nologin
+ @p='tst-pam_nologin'; \
+ b='tst-pam_nologin'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+tst-pam_nologin-retval.log: tst-pam_nologin-retval$(EXEEXT)
+ @p='tst-pam_nologin-retval$(EXEEXT)'; \
+ b='tst-pam_nologin-retval'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) \
+ $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_nologin.Plo
+ -rm -f ./$(DEPDIR)/tst-pam_nologin-retval.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_nologin.Plo
+ -rm -f ./$(DEPDIR)/tst-pam_nologin-retval.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_nologin/README b/modules/pam_nologin/README
new file mode 100644
index 0000000..25b1e92
--- /dev/null
+++ b/modules/pam_nologin/README
@@ -0,0 +1,41 @@
+pam_nologin — Prevent non-root users from login
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+pam_nologin is a PAM module that prevents users from logging into the system
+when /var/run/nologin or /etc/nologin exists. The contents of the file are
+displayed to the user. The pam_nologin module has no effect on the root user's
+ability to log in.
+
+OPTIONS
+
+file=/path/nologin
+
+ Use this file instead the default /var/run/nologin or /etc/nologin.
+
+successok
+
+ Return PAM_SUCCESS if no file exists, the default is PAM_IGNORE.
+
+EXAMPLES
+
+The suggested usage for /etc/pam.d/login is:
+
+auth required pam_nologin.so
+
+
+NOTES
+
+In order to make this module effective, all login methods should be secured by
+it. It should be used as a required method listed before any sufficient methods
+in order to get standard Unix nologin semantics. Note, the use of successok
+module argument causes the module to return PAM_SUCCESS and as such would break
+such a configuration - failing sufficient modules would lead to a successful
+login because the nologin module succeeded.
+
+AUTHOR
+
+pam_nologin was written by Michael K. Johnson <johnsonm@redhat.com>.
+
diff --git a/modules/pam_nologin/README.xml b/modules/pam_nologin/README.xml
new file mode 100644
index 0000000..bc0808e
--- /dev/null
+++ b/modules/pam_nologin/README.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_nologin.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_nologin.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_nologin-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_nologin.8.xml" xpointer='xpointer(//refsect1[@id = "pam_nologin-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_nologin.8.xml" xpointer='xpointer(//refsect1[@id = "pam_nologin-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_nologin.8.xml" xpointer='xpointer(//refsect1[@id = "pam_nologin-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_nologin.8.xml" xpointer='xpointer(//refsect1[@id = "pam_nologin-note"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_nologin.8.xml" xpointer='xpointer(//refsect1[@id = "pam_nologin-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_nologin/pam_nologin.8 b/modules/pam_nologin/pam_nologin.8
new file mode 100644
index 0000000..df0c255
--- /dev/null
+++ b/modules/pam_nologin/pam_nologin.8
@@ -0,0 +1,130 @@
+'\" t
+.\" Title: pam_nologin
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_NOLOGIN" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_nologin \- Prevent non\-root users from login
+.SH "SYNOPSIS"
+.HP \w'\fBpam_nologin\&.so\fR\ 'u
+\fBpam_nologin\&.so\fR [file=\fI/path/nologin\fR] [successok]
+.SH "DESCRIPTION"
+.PP
+pam_nologin is a PAM module that prevents users from logging into the system when
+/var/run/nologin
+or
+/etc/nologin
+exists\&. The contents of the file are displayed to the user\&. The pam_nologin module has no effect on the root user\*(Aqs ability to log in\&.
+.SH "OPTIONS"
+.PP
+\fBfile=\fR\fB\fI/path/nologin\fR\fR
+.RS 4
+Use this file instead the default
+/var/run/nologin
+or
+/etc/nologin\&.
+.RE
+.PP
+\fBsuccessok\fR
+.RS 4
+Return PAM_SUCCESS if no file exists, the default is PAM_IGNORE\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+The
+\fBauth\fR
+and
+\fBaccount\fR
+module types are provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_AUTH_ERR
+.RS 4
+The user is not root and
+/etc/nologin
+exists, so the user is not permitted to log in\&.
+.RE
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_IGNORE
+.RS 4
+This is the default return value\&.
+.RE
+.PP
+PAM_SUCCESS
+.RS 4
+Success: either the user is root or the nologin file does not exist\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+User not known to the underlying authentication module\&.
+.RE
+.SH "EXAMPLES"
+.PP
+The suggested usage for
+/etc/pam\&.d/login
+is:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+auth required pam_nologin\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "NOTES"
+.PP
+In order to make this module effective, all login methods should be secured by it\&. It should be used as a
+\fIrequired\fR
+method listed before any
+\fIsufficient\fR
+methods in order to get standard Unix nologin semantics\&. Note, the use of
+\fBsuccessok\fR
+module argument causes the module to return
+\fIPAM_SUCCESS\fR
+and as such would break such a configuration \- failing
+\fIsufficient\fR
+modules would lead to a successful login because the nologin module
+\fIsucceeded\fR\&.
+.SH "SEE ALSO"
+.PP
+\fBnologin\fR(5),
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_nologin was written by Michael K\&. Johnson <johnsonm@redhat\&.com>\&.
diff --git a/modules/pam_nologin/pam_nologin.8.xml b/modules/pam_nologin/pam_nologin.8.xml
new file mode 100644
index 0000000..c86e376
--- /dev/null
+++ b/modules/pam_nologin/pam_nologin.8.xml
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_nologin">
+
+ <refmeta>
+ <refentrytitle>pam_nologin</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_nologin-name">
+ <refname>pam_nologin</refname>
+ <refpurpose>Prevent non-root users from login</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_nologin-cmdsynopsis">
+ <command>pam_nologin.so</command>
+ <arg choice="opt">
+ file=<replaceable>/path/nologin</replaceable>
+ </arg>
+ <arg choice="opt">
+ successok
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_nologin-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ pam_nologin is a PAM module that prevents users from logging into
+ the system when <filename>/var/run/nologin</filename> or
+ <filename>/etc/nologin</filename> exists. The contents
+ of the file are displayed to the user. The pam_nologin module
+ has no effect on the root user's ability to log in.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_nologin-options">
+
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>file=<replaceable>/path/nologin</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Use this file instead the default
+ <filename>/var/run/nologin</filename> or
+ <filename>/etc/nologin</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>successok</option>
+ </term>
+ <listitem>
+ <para>
+ Return PAM_SUCCESS if no file exists, the default is PAM_IGNORE.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_nologin-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ The <option>auth</option> and <option>account</option> module
+ types are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_nologin-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_AUTH_ERR</term>
+ <listitem>
+ <para>
+ The user is not root and <filename>/etc/nologin</filename>
+ exists, so the user is not permitted to log in.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>Memory buffer error.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ This is the default return value.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Success: either the user is root or the
+ nologin file does not exist.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ User not known to the underlying authentication module.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_nologin-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ The suggested usage for <filename>/etc/pam.d/login</filename> is:
+ <programlisting>
+auth required pam_nologin.so
+ </programlisting>
+ </para>
+ </refsect1>
+ <refsect1 id='pam_nologin-note'>
+ <title>NOTES</title>
+ <para>
+ In order to make this module effective, all login methods should be
+ secured by it. It should be used as a <emphasis>required</emphasis>
+ method listed before any <emphasis>sufficient</emphasis> methods in
+ order to get standard Unix nologin semantics. Note, the use of
+ <option>successok</option> module argument causes the module to
+ return <emphasis>PAM_SUCCESS</emphasis> and as such would break
+ such a configuration - failing <emphasis>sufficient</emphasis> modules
+ would lead to a successful login because the nologin module
+ <emphasis>succeeded</emphasis>.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_nologin-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>nologin</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_nologin-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_nologin was written by Michael K. Johnson &lt;johnsonm@redhat.com&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_nologin/pam_nologin.c b/modules/pam_nologin/pam_nologin.c
new file mode 100644
index 0000000..b7f9bab
--- /dev/null
+++ b/modules/pam_nologin/pam_nologin.c
@@ -0,0 +1,163 @@
+/*
+ * pam_nologin module
+ *
+ * Written by Michael K. Johnson <johnsonm@redhat.com> 1996/10/24
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <syslog.h>
+#include <pwd.h>
+
+#include <security/_pam_macros.h>
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+#include "pam_inline.h"
+
+#define DEFAULT_NOLOGIN_PATH "/var/run/nologin"
+#define COMPAT_NOLOGIN_PATH "/etc/nologin"
+
+/*
+ * parse some command line options
+ */
+struct opt_s {
+ int retval_when_nofile;
+ const char *nologin_file;
+};
+
+static void
+parse_args(pam_handle_t *pamh, int argc, const char **argv, struct opt_s *opts)
+{
+ int i;
+
+ memset(opts, 0, sizeof(*opts));
+
+ opts->retval_when_nofile = PAM_IGNORE;
+
+ for (i=0; i<argc; ++i) {
+ const char *str;
+
+ if (!strcmp("successok", argv[i])) {
+ opts->retval_when_nofile = PAM_SUCCESS;
+ } else if ((str = pam_str_skip_prefix(argv[i], "file=")) != NULL) {
+ opts->nologin_file = str;
+ } else {
+ pam_syslog(pamh, LOG_ERR, "unknown option: %s", argv[i]);
+ }
+ }
+}
+
+/*
+ * do the meat of the work for this module
+ */
+
+static int perform_check(pam_handle_t *pamh, struct opt_s *opts)
+{
+ const char *username;
+ int retval = opts->retval_when_nofile;
+ int fd = -1;
+
+ if ((pam_get_user(pamh, &username, NULL) != PAM_SUCCESS)) {
+ pam_syslog(pamh, LOG_NOTICE, "cannot determine user name");
+ return PAM_USER_UNKNOWN;
+ }
+
+ if (opts->nologin_file == NULL) {
+ if ((fd = open(DEFAULT_NOLOGIN_PATH, O_RDONLY, 0)) < 0) {
+ fd = open(COMPAT_NOLOGIN_PATH, O_RDONLY, 0);
+ }
+ } else {
+ fd = open(opts->nologin_file, O_RDONLY, 0);
+ }
+
+ if (fd >= 0) {
+
+ char *mtmp=NULL;
+ int msg_style = PAM_TEXT_INFO;
+ struct passwd *user_pwd;
+ struct stat st;
+
+ user_pwd = pam_modutil_getpwnam(pamh, username);
+ if (user_pwd == NULL) {
+ retval = PAM_USER_UNKNOWN;
+ msg_style = PAM_ERROR_MSG;
+ } else if (user_pwd->pw_uid) {
+ retval = PAM_AUTH_ERR;
+ msg_style = PAM_ERROR_MSG;
+ }
+
+ /* fill in message buffer with contents of /etc/nologin */
+ if (fstat(fd, &st) < 0) {
+ /* give up trying to display message */
+ goto clean_up_fd;
+ }
+
+ mtmp = malloc(st.st_size+1);
+ if (!mtmp) {
+ pam_syslog(pamh, LOG_CRIT, "out of memory");
+ retval = PAM_BUF_ERR;
+ goto clean_up_fd;
+ }
+
+ if (pam_modutil_read(fd, mtmp, st.st_size) == st.st_size) {
+ mtmp[st.st_size] = '\0';
+ (void) pam_prompt (pamh, msg_style, NULL, "%s", mtmp);
+ }
+ else
+ retval = PAM_SYSTEM_ERR;
+
+ free(mtmp);
+
+ clean_up_fd:
+
+ close(fd);
+ }
+
+ return retval;
+}
+
+/* --- authentication management functions --- */
+
+int
+pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ struct opt_s opts;
+
+ parse_args(pamh, argc, argv, &opts);
+
+ return perform_check(pamh, &opts);
+}
+
+int
+pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc, const char **argv)
+{
+ struct opt_s opts;
+
+ parse_args(pamh, argc, argv, &opts);
+
+ return opts.retval_when_nofile;
+}
+
+/* --- account management function --- */
+
+int
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ struct opt_s opts;
+
+ parse_args(pamh, argc, argv, &opts);
+
+ return perform_check(pamh, &opts);
+}
+
+/* end of module definition */
diff --git a/modules/pam_nologin/tst-pam_nologin b/modules/pam_nologin/tst-pam_nologin
new file mode 100755
index 0000000..caa91b6
--- /dev/null
+++ b/modules/pam_nologin/tst-pam_nologin
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_nologin.so
diff --git a/modules/pam_nologin/tst-pam_nologin-retval.c b/modules/pam_nologin/tst-pam_nologin-retval.c
new file mode 100644
index 0000000..0046eec
--- /dev/null
+++ b/modules/pam_nologin/tst-pam_nologin-retval.c
@@ -0,0 +1,226 @@
+/*
+ * Check pam_nologin return values.
+ *
+ * Copyright (c) 2020 Dmitry V. Levin <ldv@altlinux.org>
+ */
+
+#include "test_assert.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <security/pam_appl.h>
+
+#define MODULE_NAME "pam_nologin"
+#define TEST_NAME "tst-" MODULE_NAME "-retval"
+
+static const char service_file[] = TEST_NAME ".service";
+static const char missing_file[] = TEST_NAME ".missing";
+static const char empty_file[] = "/dev/null";
+static const char user_name[] = "";
+static struct pam_conv conv;
+
+int
+main(void)
+{
+ pam_handle_t *pamh = NULL;
+ FILE *fp;
+ struct passwd *pw;
+ char cwd[PATH_MAX];
+
+ ASSERT_NE(NULL, getcwd(cwd, sizeof(cwd)));
+
+ /* PAM_IGNORE -> PAM_PERM_DENIED */
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so file=%s\n"
+ "account required %s/.libs/%s.so file=%s\n"
+ "password required %s/.libs/%s.so file=%s\n"
+ "session required %s/.libs/%s.so file=%s\n",
+ cwd, MODULE_NAME, missing_file,
+ cwd, MODULE_NAME, missing_file,
+ cwd, MODULE_NAME, missing_file,
+ cwd, MODULE_NAME, missing_file));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, user_name, &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_PERM_DENIED, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ /* PAM_IGNORE -> PAM_SUCCESS */
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so file=%s\n"
+ "auth required %s/../pam_permit/.libs/pam_permit.so\n"
+ "account required %s/.libs/%s.so file=%s\n"
+ "account required %s/../pam_permit/.libs/pam_permit.so\n"
+ "password required %s/.libs/%s.so file=%s\n"
+ "password required %s/../pam_permit/.libs/pam_permit.so\n"
+ "session required %s/.libs/%s.so file=%s\n"
+ "session required %s/../pam_permit/.libs/pam_permit.so\n",
+ cwd, MODULE_NAME, missing_file, cwd,
+ cwd, MODULE_NAME, missing_file, cwd,
+ cwd, MODULE_NAME, missing_file, cwd,
+ cwd, MODULE_NAME, missing_file, cwd));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, user_name, &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ /* successok -> PAM_SUCCESS */
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so successok file=%s\n"
+ "account required %s/.libs/%s.so successok file=%s\n"
+ "password required %s/.libs/%s.so successok file=%s\n"
+ "session required %s/.libs/%s.so successok file=%s\n",
+ cwd, MODULE_NAME, missing_file,
+ cwd, MODULE_NAME, missing_file,
+ cwd, MODULE_NAME, missing_file,
+ cwd, MODULE_NAME, missing_file));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, user_name, &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ /* PAM_USER_UNKNOWN */
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so file=%s\n"
+ "account required %s/.libs/%s.so file=%s\n"
+ "password required %s/.libs/%s.so file=%s\n"
+ "session required %s/.libs/%s.so file=%s\n",
+ cwd, MODULE_NAME, empty_file,
+ cwd, MODULE_NAME, empty_file,
+ cwd, MODULE_NAME, empty_file,
+ cwd, MODULE_NAME, empty_file));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, user_name, &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_USER_UNKNOWN, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_USER_UNKNOWN, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ /* uid == 0 */
+ if ((pw = getpwuid(0)) != NULL) {
+ /* successok -> PAM_SUCCESS */
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so successok file=%s\n"
+ "account required %s/.libs/%s.so successok file=%s\n"
+ "password required %s/.libs/%s.so successok file=%s\n"
+ "session required %s/.libs/%s.so successok file=%s\n",
+ cwd, MODULE_NAME, empty_file,
+ cwd, MODULE_NAME, empty_file,
+ cwd, MODULE_NAME, empty_file,
+ cwd, MODULE_NAME, empty_file));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, pw->pw_name,
+ &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ /* PAM_SYSTEM_ERR */
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so file=%s\n"
+ "account required %s/.libs/%s.so file=%s\n"
+ "password required %s/.libs/%s.so file=%s\n"
+ "session required %s/.libs/%s.so file=%s\n",
+ cwd, MODULE_NAME, ".",
+ cwd, MODULE_NAME, ".",
+ cwd, MODULE_NAME, ".",
+ cwd, MODULE_NAME, "."));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, pw->pw_name,
+ &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_SYSTEM_ERR, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_SYSTEM_ERR, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+ }
+
+ /* uid != 0 */
+ if (geteuid() != 0 && (pw = getpwuid(geteuid())) != NULL) {
+ /* PAM_AUTH_ERR */
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so file=%s\n"
+ "account required %s/.libs/%s.so file=%s\n"
+ "password required %s/.libs/%s.so file=%s\n"
+ "session required %s/.libs/%s.so file=%s\n",
+ cwd, MODULE_NAME, empty_file,
+ cwd, MODULE_NAME, empty_file,
+ cwd, MODULE_NAME, empty_file,
+ cwd, MODULE_NAME, empty_file));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, pw->pw_name,
+ &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_AUTH_ERR, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_AUTH_ERR, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+ }
+
+ ASSERT_EQ(0, unlink(service_file));
+
+ return 0;
+}
diff --git a/modules/pam_permit/Makefile.am b/modules/pam_permit/Makefile.am
new file mode 100644
index 0000000..3fb4792
--- /dev/null
+++ b/modules/pam_permit/Makefile.am
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_permit.8
+endif
+XMLS = README.xml pam_permit.8.xml
+dist_check_SCRIPTS = tst-pam_permit
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_permit.la
+pam_permit_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+check_PROGRAMS = tst-pam_permit-retval
+tst_pam_permit_retval_LDADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_permit/Makefile.in b/modules/pam_permit/Makefile.in
new file mode 100644
index 0000000..1094172
--- /dev/null
+++ b/modules/pam_permit/Makefile.in
@@ -0,0 +1,1180 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+check_PROGRAMS = tst-pam_permit-retval$(EXEEXT)
+subdir = modules/pam_permit
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_permit_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_permit_la_SOURCES = pam_permit.c
+pam_permit_la_OBJECTS = pam_permit.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+tst_pam_permit_retval_SOURCES = tst-pam_permit-retval.c
+tst_pam_permit_retval_OBJECTS = tst-pam_permit-retval.$(OBJEXT)
+tst_pam_permit_retval_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_permit.Plo \
+ ./$(DEPDIR)/tst-pam_permit-retval.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_permit.c tst-pam_permit-retval.c
+DIST_SOURCES = pam_permit.c tst-pam_permit-retval.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_permit.8
+XMLS = README.xml pam_permit.8.xml
+dist_check_SCRIPTS = tst-pam_permit
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_permit.la
+pam_permit_la_LIBADD = $(top_builddir)/libpam/libpam.la
+tst_pam_permit_retval_LDADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_permit/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_permit/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_permit.la: $(pam_permit_la_OBJECTS) $(pam_permit_la_DEPENDENCIES) $(EXTRA_pam_permit_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_permit_la_OBJECTS) $(pam_permit_la_LIBADD) $(LIBS)
+
+tst-pam_permit-retval$(EXEEXT): $(tst_pam_permit_retval_OBJECTS) $(tst_pam_permit_retval_DEPENDENCIES) $(EXTRA_tst_pam_permit_retval_DEPENDENCIES)
+ @rm -f tst-pam_permit-retval$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tst_pam_permit_retval_OBJECTS) $(tst_pam_permit_retval_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_permit.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-pam_permit-retval.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_permit.log: tst-pam_permit
+ @p='tst-pam_permit'; \
+ b='tst-pam_permit'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+tst-pam_permit-retval.log: tst-pam_permit-retval$(EXEEXT)
+ @p='tst-pam_permit-retval$(EXEEXT)'; \
+ b='tst-pam_permit-retval'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) \
+ $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_permit.Plo
+ -rm -f ./$(DEPDIR)/tst-pam_permit-retval.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_permit.Plo
+ -rm -f ./$(DEPDIR)/tst-pam_permit-retval.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_permit/README b/modules/pam_permit/README
new file mode 100644
index 0000000..d479dcc
--- /dev/null
+++ b/modules/pam_permit/README
@@ -0,0 +1,30 @@
+pam_permit — The promiscuous module
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+pam_permit is a PAM module that always permit access. It does nothing else.
+
+In the case of authentication, the user's name will be set to nobody if the
+application didn't set one. Many applications and PAM modules become confused
+if this name is unknown.
+
+This module is very dangerous. It should be used with extreme caution.
+
+OPTIONS
+
+This module does not recognise any options.
+
+EXAMPLES
+
+Add this line to your other login entries to disable account management, but
+continue to permit users to log in.
+
+account required pam_permit.so
+
+
+AUTHOR
+
+pam_permit was written by Andrew G. Morgan, <morgan@kernel.org>.
+
diff --git a/modules/pam_permit/README.xml b/modules/pam_permit/README.xml
new file mode 100644
index 0000000..acb38b5
--- /dev/null
+++ b/modules/pam_permit/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_permit.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_permit.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_permit-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_permit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_permit-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_permit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_permit-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_permit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_permit-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_permit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_permit-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_permit/pam_permit.8 b/modules/pam_permit/pam_permit.8
new file mode 100644
index 0000000..88dff2b
--- /dev/null
+++ b/modules/pam_permit/pam_permit.8
@@ -0,0 +1,84 @@
+'\" t
+.\" Title: pam_permit
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_PERMIT" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_permit \- The promiscuous module
+.SH "SYNOPSIS"
+.HP \w'\fBpam_permit\&.so\fR\ 'u
+\fBpam_permit\&.so\fR
+.SH "DESCRIPTION"
+.PP
+pam_permit is a PAM module that always permit access\&. It does nothing else\&.
+.PP
+In the case of authentication, the user\*(Aqs name will be set to
+\fInobody\fR
+if the application didn\*(Aqt set one\&. Many applications and PAM modules become confused if this name is unknown\&.
+.PP
+This module is very dangerous\&. It should be used with extreme caution\&.
+.SH "OPTIONS"
+.PP
+This module does not recognise any options\&.
+.SH "MODULE TYPES PROVIDED"
+.PP
+The
+\fBauth\fR,
+\fBaccount\fR,
+\fBpassword\fR
+and
+\fBsession\fR
+module types are provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_SUCCESS
+.RS 4
+This module always returns this value\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Add this line to your other login entries to disable account management, but continue to permit users to log in\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+account required pam_permit\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.PP
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_permit was written by Andrew G\&. Morgan, <morgan@kernel\&.org>\&.
diff --git a/modules/pam_permit/pam_permit.8.xml b/modules/pam_permit/pam_permit.8.xml
new file mode 100644
index 0000000..6bb4965
--- /dev/null
+++ b/modules/pam_permit/pam_permit.8.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_permit">
+
+ <refmeta>
+ <refentrytitle>pam_permit</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_permit-name">
+ <refname>pam_permit</refname>
+ <refpurpose>The promiscuous module</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_permit-cmdsynopsis">
+ <command>pam_permit.so</command>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_permit-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ pam_permit is a PAM module that always permit access. It does
+ nothing else.
+ </para>
+ <para>
+ In the case of authentication, the user's name will be set to
+ <emphasis>nobody</emphasis> if the application didn't set one.
+ Many applications and PAM modules become confused if this name
+ is unknown.
+ </para>
+ <para>
+ This module is very dangerous. It should be used with extreme
+ caution.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_permit-options">
+
+ <title>OPTIONS</title>
+ <para> This module does not recognise any options.</para>
+ </refsect1>
+
+ <refsect1 id="pam_permit-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ The <option>auth</option>, <option>account</option>,
+ <option>password</option> and <option>session</option>
+ module types are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_permit-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ This module always returns this value.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_permit-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ Add this line to your other login entries to disable account
+ management, but continue to permit users to log in.
+ <programlisting>
+account required pam_permit.so
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_permit-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_permit-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_permit was written by Andrew G. Morgan, &lt;morgan@kernel.org&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_permit/pam_permit.c b/modules/pam_permit/pam_permit.c
new file mode 100644
index 0000000..4f97368
--- /dev/null
+++ b/modules/pam_permit/pam_permit.c
@@ -0,0 +1,84 @@
+/*
+ * pam_permit module
+ *
+ * Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11
+ */
+
+#include "config.h"
+#include <stdio.h>
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+
+#define DEFAULT_USER "nobody"
+
+/* --- authentication management functions --- */
+
+int
+pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ int retval;
+ const char *user=NULL;
+
+ /*
+ * authentication requires we know who the user wants to be
+ */
+ retval = pam_get_user(pamh, &user, NULL);
+ if (retval != PAM_SUCCESS) {
+ D(("get user returned error: %s", pam_strerror(pamh,retval)));
+ return retval;
+ }
+ if (*user == '\0') {
+ D(("username not known"));
+ retval = pam_set_item(pamh, PAM_USER, (const void *) DEFAULT_USER);
+ if (retval != PAM_SUCCESS)
+ return PAM_USER_UNKNOWN;
+ }
+ user = NULL; /* clean up */
+
+ return PAM_SUCCESS;
+}
+
+int
+pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
+
+/* --- account management functions --- */
+
+int
+pam_sm_acct_mgmt(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
+
+/* --- password management --- */
+
+int
+pam_sm_chauthtok(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
+
+/* --- session management --- */
+
+int
+pam_sm_open_session(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
+
+int
+pam_sm_close_session(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
+
+/* end of module definition */
diff --git a/modules/pam_permit/tst-pam_permit b/modules/pam_permit/tst-pam_permit
new file mode 100755
index 0000000..8adb427
--- /dev/null
+++ b/modules/pam_permit/tst-pam_permit
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_permit.so
diff --git a/modules/pam_permit/tst-pam_permit-retval.c b/modules/pam_permit/tst-pam_permit-retval.c
new file mode 100644
index 0000000..33a789f
--- /dev/null
+++ b/modules/pam_permit/tst-pam_permit-retval.c
@@ -0,0 +1,58 @@
+/*
+ * Check pam_permit return values.
+ *
+ * Copyright (c) 2020 Dmitry V. Levin <ldv@altlinux.org>
+ */
+
+#include "test_assert.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <security/pam_appl.h>
+
+#define MODULE_NAME "pam_permit"
+#define TEST_NAME "tst-" MODULE_NAME "-retval"
+
+static const char service_file[] = TEST_NAME ".service";
+static const char user_name[] = "";
+static struct pam_conv conv;
+
+int
+main(void)
+{
+ pam_handle_t *pamh = NULL;
+ FILE *fp;
+ char cwd[PATH_MAX];
+
+ ASSERT_NE(NULL, getcwd(cwd, sizeof(cwd)));
+
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so\n"
+ "account required %s/.libs/%s.so\n"
+ "password required %s/.libs/%s.so\n"
+ "session required %s/.libs/%s.so\n",
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, user_name, &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_chauthtok(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ ASSERT_EQ(0, unlink(service_file));
+
+ return 0;
+}
diff --git a/modules/pam_pwhistory/Makefile.am b/modules/pam_pwhistory/Makefile.am
new file mode 100644
index 0000000..8a4dbcb
--- /dev/null
+++ b/modules/pam_pwhistory/Makefile.am
@@ -0,0 +1,45 @@
+#
+# Copyright (c) 2008, 2009 Thorsten Kukuk <kukuk@suse.de>
+# Copyright (c) 2013 Red Hat, Inc.
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_pwhistory.8 pwhistory_helper.8
+endif
+XMLS = README.xml pam_pwhistory.8.xml pwhistory_helper.8.xml
+dist_check_SCRIPTS = tst-pam_pwhistory
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS) -DPWHISTORY_HELPER=\"$(sbindir)/pwhistory_helper\"
+
+pam_pwhistory_la_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ pam_pwhistory_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+noinst_HEADERS = opasswd.h
+
+securelib_LTLIBRARIES = pam_pwhistory.la
+pam_pwhistory_la_CFLAGS = $(AM_CFLAGS)
+pam_pwhistory_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@ @LIBSELINUX@
+pam_pwhistory_la_SOURCES = pam_pwhistory.c opasswd.c
+
+sbin_PROGRAMS = pwhistory_helper
+pwhistory_helper_CFLAGS = $(AM_CFLAGS) -DHELPER_COMPILE=\"pwhistory_helper\" @EXE_CFLAGS@
+pwhistory_helper_SOURCES = pwhistory_helper.c opasswd.c
+pwhistory_helper_LDFLAGS = @EXE_LDFLAGS@
+pwhistory_helper_LDADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_pwhistory/Makefile.in b/modules/pam_pwhistory/Makefile.in
new file mode 100644
index 0000000..cf1082b
--- /dev/null
+++ b/modules/pam_pwhistory/Makefile.in
@@ -0,0 +1,1289 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2008, 2009 Thorsten Kukuk <kukuk@suse.de>
+# Copyright (c) 2013 Red Hat, Inc.
+#
+
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+sbin_PROGRAMS = pwhistory_helper$(EXEEXT)
+subdir = modules/pam_pwhistory
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(noinst_HEADERS) \
+ $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(securelibdir)" \
+ "$(DESTDIR)$(man8dir)"
+PROGRAMS = $(sbin_PROGRAMS)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_pwhistory_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+am_pam_pwhistory_la_OBJECTS = pam_pwhistory_la-pam_pwhistory.lo \
+ pam_pwhistory_la-opasswd.lo
+pam_pwhistory_la_OBJECTS = $(am_pam_pwhistory_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+pam_pwhistory_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(pam_pwhistory_la_CFLAGS) $(CFLAGS) \
+ $(pam_pwhistory_la_LDFLAGS) $(LDFLAGS) -o $@
+am_pwhistory_helper_OBJECTS = \
+ pwhistory_helper-pwhistory_helper.$(OBJEXT) \
+ pwhistory_helper-opasswd.$(OBJEXT)
+pwhistory_helper_OBJECTS = $(am_pwhistory_helper_OBJECTS)
+pwhistory_helper_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pwhistory_helper_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(pwhistory_helper_CFLAGS) $(CFLAGS) \
+ $(pwhistory_helper_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_pwhistory_la-opasswd.Plo \
+ ./$(DEPDIR)/pam_pwhistory_la-pam_pwhistory.Plo \
+ ./$(DEPDIR)/pwhistory_helper-opasswd.Po \
+ ./$(DEPDIR)/pwhistory_helper-pwhistory_helper.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(pam_pwhistory_la_SOURCES) $(pwhistory_helper_SOURCES)
+DIST_SOURCES = $(pam_pwhistory_la_SOURCES) $(pwhistory_helper_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_pwhistory.8 pwhistory_helper.8
+XMLS = README.xml pam_pwhistory.8.xml pwhistory_helper.8.xml
+dist_check_SCRIPTS = tst-pam_pwhistory
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS) -DPWHISTORY_HELPER=\"$(sbindir)/pwhistory_helper\"
+
+pam_pwhistory_la_LDFLAGS = -no-undefined -avoid-version -module \
+ $(am__append_1)
+noinst_HEADERS = opasswd.h
+securelib_LTLIBRARIES = pam_pwhistory.la
+pam_pwhistory_la_CFLAGS = $(AM_CFLAGS)
+pam_pwhistory_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@ @LIBSELINUX@
+pam_pwhistory_la_SOURCES = pam_pwhistory.c opasswd.c
+pwhistory_helper_CFLAGS = $(AM_CFLAGS) -DHELPER_COMPILE=\"pwhistory_helper\" @EXE_CFLAGS@
+pwhistory_helper_SOURCES = pwhistory_helper.c opasswd.c
+pwhistory_helper_LDFLAGS = @EXE_LDFLAGS@
+pwhistory_helper_LDADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_pwhistory/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_pwhistory/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(sbindir)" && rm -f $$files
+
+clean-sbinPROGRAMS:
+ @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_pwhistory.la: $(pam_pwhistory_la_OBJECTS) $(pam_pwhistory_la_DEPENDENCIES) $(EXTRA_pam_pwhistory_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(pam_pwhistory_la_LINK) -rpath $(securelibdir) $(pam_pwhistory_la_OBJECTS) $(pam_pwhistory_la_LIBADD) $(LIBS)
+
+pwhistory_helper$(EXEEXT): $(pwhistory_helper_OBJECTS) $(pwhistory_helper_DEPENDENCIES) $(EXTRA_pwhistory_helper_DEPENDENCIES)
+ @rm -f pwhistory_helper$(EXEEXT)
+ $(AM_V_CCLD)$(pwhistory_helper_LINK) $(pwhistory_helper_OBJECTS) $(pwhistory_helper_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_pwhistory_la-opasswd.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_pwhistory_la-pam_pwhistory.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwhistory_helper-opasswd.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pwhistory_helper-pwhistory_helper.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+pam_pwhistory_la-pam_pwhistory.lo: pam_pwhistory.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_pwhistory_la_CFLAGS) $(CFLAGS) -MT pam_pwhistory_la-pam_pwhistory.lo -MD -MP -MF $(DEPDIR)/pam_pwhistory_la-pam_pwhistory.Tpo -c -o pam_pwhistory_la-pam_pwhistory.lo `test -f 'pam_pwhistory.c' || echo '$(srcdir)/'`pam_pwhistory.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pam_pwhistory_la-pam_pwhistory.Tpo $(DEPDIR)/pam_pwhistory_la-pam_pwhistory.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pam_pwhistory.c' object='pam_pwhistory_la-pam_pwhistory.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_pwhistory_la_CFLAGS) $(CFLAGS) -c -o pam_pwhistory_la-pam_pwhistory.lo `test -f 'pam_pwhistory.c' || echo '$(srcdir)/'`pam_pwhistory.c
+
+pam_pwhistory_la-opasswd.lo: opasswd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_pwhistory_la_CFLAGS) $(CFLAGS) -MT pam_pwhistory_la-opasswd.lo -MD -MP -MF $(DEPDIR)/pam_pwhistory_la-opasswd.Tpo -c -o pam_pwhistory_la-opasswd.lo `test -f 'opasswd.c' || echo '$(srcdir)/'`opasswd.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pam_pwhistory_la-opasswd.Tpo $(DEPDIR)/pam_pwhistory_la-opasswd.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='opasswd.c' object='pam_pwhistory_la-opasswd.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_pwhistory_la_CFLAGS) $(CFLAGS) -c -o pam_pwhistory_la-opasswd.lo `test -f 'opasswd.c' || echo '$(srcdir)/'`opasswd.c
+
+pwhistory_helper-pwhistory_helper.o: pwhistory_helper.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pwhistory_helper_CFLAGS) $(CFLAGS) -MT pwhistory_helper-pwhistory_helper.o -MD -MP -MF $(DEPDIR)/pwhistory_helper-pwhistory_helper.Tpo -c -o pwhistory_helper-pwhistory_helper.o `test -f 'pwhistory_helper.c' || echo '$(srcdir)/'`pwhistory_helper.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pwhistory_helper-pwhistory_helper.Tpo $(DEPDIR)/pwhistory_helper-pwhistory_helper.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pwhistory_helper.c' object='pwhistory_helper-pwhistory_helper.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pwhistory_helper_CFLAGS) $(CFLAGS) -c -o pwhistory_helper-pwhistory_helper.o `test -f 'pwhistory_helper.c' || echo '$(srcdir)/'`pwhistory_helper.c
+
+pwhistory_helper-pwhistory_helper.obj: pwhistory_helper.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pwhistory_helper_CFLAGS) $(CFLAGS) -MT pwhistory_helper-pwhistory_helper.obj -MD -MP -MF $(DEPDIR)/pwhistory_helper-pwhistory_helper.Tpo -c -o pwhistory_helper-pwhistory_helper.obj `if test -f 'pwhistory_helper.c'; then $(CYGPATH_W) 'pwhistory_helper.c'; else $(CYGPATH_W) '$(srcdir)/pwhistory_helper.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pwhistory_helper-pwhistory_helper.Tpo $(DEPDIR)/pwhistory_helper-pwhistory_helper.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pwhistory_helper.c' object='pwhistory_helper-pwhistory_helper.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pwhistory_helper_CFLAGS) $(CFLAGS) -c -o pwhistory_helper-pwhistory_helper.obj `if test -f 'pwhistory_helper.c'; then $(CYGPATH_W) 'pwhistory_helper.c'; else $(CYGPATH_W) '$(srcdir)/pwhistory_helper.c'; fi`
+
+pwhistory_helper-opasswd.o: opasswd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pwhistory_helper_CFLAGS) $(CFLAGS) -MT pwhistory_helper-opasswd.o -MD -MP -MF $(DEPDIR)/pwhistory_helper-opasswd.Tpo -c -o pwhistory_helper-opasswd.o `test -f 'opasswd.c' || echo '$(srcdir)/'`opasswd.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pwhistory_helper-opasswd.Tpo $(DEPDIR)/pwhistory_helper-opasswd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='opasswd.c' object='pwhistory_helper-opasswd.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pwhistory_helper_CFLAGS) $(CFLAGS) -c -o pwhistory_helper-opasswd.o `test -f 'opasswd.c' || echo '$(srcdir)/'`opasswd.c
+
+pwhistory_helper-opasswd.obj: opasswd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pwhistory_helper_CFLAGS) $(CFLAGS) -MT pwhistory_helper-opasswd.obj -MD -MP -MF $(DEPDIR)/pwhistory_helper-opasswd.Tpo -c -o pwhistory_helper-opasswd.obj `if test -f 'opasswd.c'; then $(CYGPATH_W) 'opasswd.c'; else $(CYGPATH_W) '$(srcdir)/opasswd.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pwhistory_helper-opasswd.Tpo $(DEPDIR)/pwhistory_helper-opasswd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='opasswd.c' object='pwhistory_helper-opasswd.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pwhistory_helper_CFLAGS) $(CFLAGS) -c -o pwhistory_helper-opasswd.obj `if test -f 'opasswd.c'; then $(CYGPATH_W) 'opasswd.c'; else $(CYGPATH_W) '$(srcdir)/opasswd.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_pwhistory.log: tst-pam_pwhistory
+ @p='tst-pam_pwhistory'; \
+ b='tst-pam_pwhistory'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(MANS) $(DATA) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \
+ clean-securelibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_pwhistory_la-opasswd.Plo
+ -rm -f ./$(DEPDIR)/pam_pwhistory_la-pam_pwhistory.Plo
+ -rm -f ./$(DEPDIR)/pwhistory_helper-opasswd.Po
+ -rm -f ./$(DEPDIR)/pwhistory_helper-pwhistory_helper.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-sbinPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_pwhistory_la-opasswd.Plo
+ -rm -f ./$(DEPDIR)/pam_pwhistory_la-pam_pwhistory.Plo
+ -rm -f ./$(DEPDIR)/pwhistory_helper-opasswd.Po
+ -rm -f ./$(DEPDIR)/pwhistory_helper-pwhistory_helper.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-sbinPROGRAMS \
+ uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool clean-sbinPROGRAMS \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-sbinPROGRAMS \
+ uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_pwhistory/README b/modules/pam_pwhistory/README
new file mode 100644
index 0000000..161bebc
--- /dev/null
+++ b/modules/pam_pwhistory/README
@@ -0,0 +1,66 @@
+pam_pwhistory — PAM module to remember last passwords
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+This module saves the last passwords for each user in order to force password
+change history and keep the user from alternating between the same password too
+frequently.
+
+This module does not work together with kerberos. In general, it does not make
+much sense to use this module in conjunction with NIS or LDAP, since the old
+passwords are stored on the local machine and are not available on another
+machine for password history checking.
+
+OPTIONS
+
+debug
+
+ Turns on debugging via syslog(3).
+
+use_authtok
+
+ When password changing enforce the module to use the new password provided
+ by a previously stacked password module (this is used in the example of the
+ stacking of the pam_passwdqc module documented below).
+
+enforce_for_root
+
+ If this option is set, the check is enforced for root, too.
+
+remember=N
+
+ The last N passwords for each user are saved in /etc/security/opasswd. The
+ default is 10. Value of 0 makes the module to keep the existing contents of
+ the opasswd file unchanged.
+
+retry=N
+
+ Prompt user at most N times before returning with error. The default is 1.
+
+authtok_type=STRING
+
+ See pam_get_authtok(3) for more details.
+
+EXAMPLES
+
+An example password section would be:
+
+#%PAM-1.0
+password required pam_pwhistory.so
+password required pam_unix.so use_authtok
+
+
+In combination with pam_passwdqc:
+
+#%PAM-1.0
+password required pam_passwdqc.so config=/etc/passwdqc.conf
+password required pam_pwhistory.so use_authtok
+password required pam_unix.so use_authtok
+
+
+AUTHOR
+
+pam_pwhistory was written by Thorsten Kukuk <kukuk@thkukuk.de>
+
diff --git a/modules/pam_pwhistory/README.xml b/modules/pam_pwhistory/README.xml
new file mode 100644
index 0000000..f048e32
--- /dev/null
+++ b/modules/pam_pwhistory/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_pwhistory.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_pwhistory.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_pwhistory-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_pwhistory.8.xml" xpointer='xpointer(//refsect1[@id = "pam_pwhistory-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_pwhistory.8.xml" xpointer='xpointer(//refsect1[@id = "pam_pwhistory-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_pwhistory.8.xml" xpointer='xpointer(//refsect1[@id = "pam_pwhistory-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_pwhistory.8.xml" xpointer='xpointer(//refsect1[@id = "pam_pwhistory-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_pwhistory/opasswd.c b/modules/pam_pwhistory/opasswd.c
new file mode 100644
index 0000000..a6cd3d2
--- /dev/null
+++ b/modules/pam_pwhistory/opasswd.c
@@ -0,0 +1,564 @@
+/*
+ * Copyright (c) 2008 Thorsten Kukuk <kukuk@suse.de>
+ * Copyright (c) 2013 Red Hat, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <pwd.h>
+#include <shadow.h>
+#include <time.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <syslog.h>
+#ifdef HELPER_COMPILE
+#include <stdarg.h>
+#endif
+#include <sys/stat.h>
+
+#ifdef HAVE_CRYPT_H
+#include <crypt.h>
+#endif
+
+#ifdef HELPER_COMPILE
+#define pam_modutil_getpwnam(h,n) getpwnam(n)
+#define pam_modutil_getspnam(h,n) getspnam(n)
+#define pam_syslog(h,a,...) helper_log_err(a,__VA_ARGS__)
+#else
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+#endif
+#include <security/pam_modules.h>
+
+#include "opasswd.h"
+
+#ifndef RANDOM_DEVICE
+#define RANDOM_DEVICE "/dev/urandom"
+#endif
+
+#define OLD_PASSWORDS_FILE "/etc/security/opasswd"
+#define TMP_PASSWORDS_FILE OLD_PASSWORDS_FILE".tmpXXXXXX"
+
+#define DEFAULT_BUFLEN 4096
+
+typedef struct {
+ char *user;
+ char *uid;
+ int count;
+ char *old_passwords;
+} opwd;
+
+#ifdef HELPER_COMPILE
+PAM_FORMAT((printf, 2, 3))
+void
+helper_log_err(int err, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ openlog(HELPER_COMPILE, LOG_CONS | LOG_PID, LOG_AUTHPRIV);
+ vsyslog(err, format, args);
+ va_end(args);
+ closelog();
+}
+#endif
+
+static int
+parse_entry (char *line, opwd *data)
+{
+ const char delimiters[] = ":";
+ char *endptr;
+ char *count;
+
+ data->user = strsep (&line, delimiters);
+ data->uid = strsep (&line, delimiters);
+ count = strsep (&line, delimiters);
+ if (count == NULL)
+ return 1;
+
+ data->count = strtol (count, &endptr, 10);
+ if (endptr != NULL && *endptr != '\0')
+ return 1;
+
+ data->old_passwords = strsep (&line, delimiters);
+
+ return 0;
+}
+
+static int
+compare_password(const char *newpass, const char *oldpass)
+{
+ char *outval;
+#ifdef HAVE_CRYPT_R
+ struct crypt_data output;
+
+ output.initialized = 0;
+
+ outval = crypt_r (newpass, oldpass, &output);
+#else
+ outval = crypt (newpass, oldpass);
+#endif
+
+ return outval != NULL && strcmp(outval, oldpass) == 0;
+}
+
+/* Check, if the new password is already in the opasswd file. */
+PAMH_ARG_DECL(int
+check_old_pass, const char *user, const char *newpass, int debug)
+{
+ int retval = PAM_SUCCESS;
+ FILE *oldpf;
+ char *buf = NULL;
+ size_t buflen = 0;
+ opwd entry;
+ int found = 0;
+
+#ifndef HELPER_COMPILE
+ if (SELINUX_ENABLED)
+ return PAM_PWHISTORY_RUN_HELPER;
+#endif
+
+ if ((oldpf = fopen (OLD_PASSWORDS_FILE, "r")) == NULL)
+ {
+ if (errno != ENOENT)
+ pam_syslog (pamh, LOG_ERR, "Cannot open %s: %m", OLD_PASSWORDS_FILE);
+ return PAM_SUCCESS;
+ }
+
+ while (!feof (oldpf))
+ {
+ char *cp, *tmp;
+#if defined(HAVE_GETLINE)
+ ssize_t n = getline (&buf, &buflen, oldpf);
+#elif defined (HAVE_GETDELIM)
+ ssize_t n = getdelim (&buf, &buflen, '\n', oldpf);
+#else
+ ssize_t n;
+
+ if (buf == NULL)
+ {
+ buflen = DEFAULT_BUFLEN;
+ buf = malloc (buflen);
+ if (buf == NULL)
+ return PAM_BUF_ERR;
+ }
+ buf[0] = '\0';
+ fgets (buf, buflen - 1, oldpf);
+ n = strlen (buf);
+#endif /* HAVE_GETLINE / HAVE_GETDELIM */
+ cp = buf;
+
+ if (n < 1)
+ break;
+
+ tmp = strchr (cp, '#'); /* remove comments */
+ if (tmp)
+ *tmp = '\0';
+ while (isspace ((int)*cp)) /* remove spaces and tabs */
+ ++cp;
+ if (*cp == '\0') /* ignore empty lines */
+ continue;
+
+ if (cp[strlen (cp) - 1] == '\n')
+ cp[strlen (cp) - 1] = '\0';
+
+ if (strncmp (cp, user, strlen (user)) == 0 &&
+ cp[strlen (user)] == ':')
+ {
+ /* We found the line we needed */
+ if (parse_entry (cp, &entry) == 0)
+ {
+ found = 1;
+ break;
+ }
+ }
+ }
+
+ fclose (oldpf);
+
+ if (found && entry.old_passwords)
+ {
+ const char delimiters[] = ",";
+ char *running;
+ char *oldpass;
+
+ running = entry.old_passwords;
+
+ do {
+ oldpass = strsep (&running, delimiters);
+ if (oldpass && strlen (oldpass) > 0 &&
+ compare_password(newpass, oldpass) )
+ {
+ if (debug)
+ pam_syslog (pamh, LOG_DEBUG, "New password already used");
+ retval = PAM_AUTHTOK_ERR;
+ break;
+ }
+ } while (oldpass != NULL);
+ }
+
+ if (buf)
+ free (buf);
+
+ return retval;
+}
+
+PAMH_ARG_DECL(int
+save_old_pass, const char *user, int howmany, int debug UNUSED)
+{
+ char opasswd_tmp[] = TMP_PASSWORDS_FILE;
+ struct stat opasswd_stat;
+ FILE *oldpf, *newpf;
+ int newpf_fd;
+ int do_create = 0;
+ int retval = PAM_SUCCESS;
+ char *buf = NULL;
+ size_t buflen = 0;
+ int found = 0;
+ struct passwd *pwd;
+ const char *oldpass;
+
+ pwd = pam_modutil_getpwnam (pamh, user);
+ if (pwd == NULL)
+ return PAM_USER_UNKNOWN;
+
+ if (howmany <= 0)
+ return PAM_SUCCESS;
+
+#ifndef HELPER_COMPILE
+ if (SELINUX_ENABLED)
+ return PAM_PWHISTORY_RUN_HELPER;
+#endif
+
+ if ((strcmp(pwd->pw_passwd, "x") == 0) ||
+ ((pwd->pw_passwd[0] == '#') &&
+ (pwd->pw_passwd[1] == '#') &&
+ (strcmp(pwd->pw_name, pwd->pw_passwd + 2) == 0)))
+ {
+ struct spwd *spw = pam_modutil_getspnam (pamh, user);
+
+ if (spw == NULL)
+ return PAM_USER_UNKNOWN;
+ oldpass = spw->sp_pwdp;
+ }
+ else
+ oldpass = pwd->pw_passwd;
+
+ if (oldpass == NULL || *oldpass == '\0')
+ return PAM_SUCCESS;
+
+ if ((oldpf = fopen (OLD_PASSWORDS_FILE, "r")) == NULL)
+ {
+ if (errno == ENOENT)
+ {
+ pam_syslog (pamh, LOG_NOTICE, "Creating %s",
+ OLD_PASSWORDS_FILE);
+ do_create = 1;
+ }
+ else
+ {
+ pam_syslog (pamh, LOG_ERR, "Cannot open %s: %m",
+ OLD_PASSWORDS_FILE);
+ return PAM_AUTHTOK_ERR;
+ }
+ }
+ else if (fstat (fileno (oldpf), &opasswd_stat) < 0)
+ {
+ pam_syslog (pamh, LOG_ERR, "Cannot stat %s: %m", OLD_PASSWORDS_FILE);
+ fclose (oldpf);
+ return PAM_AUTHTOK_ERR;
+ }
+
+ /* Open a temp passwd file */
+ newpf_fd = mkstemp (opasswd_tmp);
+ if (newpf_fd == -1)
+ {
+ pam_syslog (pamh, LOG_ERR, "Cannot create %s temp file: %m",
+ OLD_PASSWORDS_FILE);
+ if (oldpf)
+ fclose (oldpf);
+ return PAM_AUTHTOK_ERR;
+ }
+ if (do_create)
+ {
+ if (fchmod (newpf_fd, S_IRUSR|S_IWUSR) != 0)
+ pam_syslog (pamh, LOG_ERR,
+ "Cannot set permissions of %s temp file: %m",
+ OLD_PASSWORDS_FILE);
+ if (fchown (newpf_fd, 0, 0) != 0)
+ pam_syslog (pamh, LOG_ERR,
+ "Cannot set owner/group of %s temp file: %m",
+ OLD_PASSWORDS_FILE);
+ }
+ else
+ {
+ if (fchmod (newpf_fd, opasswd_stat.st_mode) != 0)
+ pam_syslog (pamh, LOG_ERR,
+ "Cannot set permissions of %s temp file: %m",
+ OLD_PASSWORDS_FILE);
+ if (fchown (newpf_fd, opasswd_stat.st_uid, opasswd_stat.st_gid) != 0)
+ pam_syslog (pamh, LOG_ERR,
+ "Cannot set owner/group of %s temp file: %m",
+ OLD_PASSWORDS_FILE);
+ }
+ newpf = fdopen (newpf_fd, "w+");
+ if (newpf == NULL)
+ {
+ pam_syslog (pamh, LOG_ERR, "Cannot fdopen %s: %m", opasswd_tmp);
+ if (oldpf)
+ fclose (oldpf);
+ close (newpf_fd);
+ retval = PAM_AUTHTOK_ERR;
+ goto error_opasswd;
+ }
+
+ if (!do_create)
+ while (!feof (oldpf))
+ {
+ char *cp, *tmp, *save;
+#if defined(HAVE_GETLINE)
+ ssize_t n = getline (&buf, &buflen, oldpf);
+#elif defined (HAVE_GETDELIM)
+ ssize_t n = getdelim (&buf, &buflen, '\n', oldpf);
+#else
+ ssize_t n;
+
+ if (buf == NULL)
+ {
+ buflen = DEFAULT_BUFLEN;
+ buf = malloc (buflen);
+ if (buf == NULL)
+ {
+ fclose (oldpf);
+ fclose (newpf);
+ retval = PAM_BUF_ERR;
+ goto error_opasswd;
+ }
+ }
+ buf[0] = '\0';
+ fgets (buf, buflen - 1, oldpf);
+ n = strlen (buf);
+#endif /* HAVE_GETLINE / HAVE_GETDELIM */
+
+ if (n < 1)
+ break;
+
+ cp = buf;
+ save = strdup (buf); /* Copy to write the original data back. */
+ if (save == NULL)
+ {
+ fclose (oldpf);
+ fclose (newpf);
+ retval = PAM_BUF_ERR;
+ goto error_opasswd;
+ }
+
+ tmp = strchr (cp, '#'); /* remove comments */
+ if (tmp)
+ *tmp = '\0';
+ while (isspace ((int)*cp)) /* remove spaces and tabs */
+ ++cp;
+ if (*cp == '\0') /* ignore empty lines */
+ goto write_old_data;
+
+ if (cp[strlen (cp) - 1] == '\n')
+ cp[strlen (cp) - 1] = '\0';
+
+ if (strncmp (cp, user, strlen (user)) == 0 &&
+ cp[strlen (user)] == ':')
+ {
+ /* We found the line we needed */
+ opwd entry;
+
+ if (parse_entry (cp, &entry) == 0)
+ {
+ char *out = NULL;
+
+ found = 1;
+
+ /* Don't save the current password twice */
+ if (entry.old_passwords && entry.old_passwords[0] != '\0')
+ {
+ char *last = entry.old_passwords;
+
+ cp = entry.old_passwords;
+ entry.count = 1; /* Don't believe the count */
+ while ((cp = strchr (cp, ',')) != NULL)
+ {
+ entry.count++;
+ last = ++cp;
+ }
+
+ /* compare the last password */
+ if (strcmp (last, oldpass) == 0)
+ goto write_old_data;
+ }
+ else
+ entry.count = 0;
+
+ /* increase count. */
+ entry.count++;
+
+ /* check that we don't remember to many passwords. */
+ while (entry.count > howmany && entry.count > 1)
+ {
+ char *p = strpbrk (entry.old_passwords, ",");
+ if (p != NULL)
+ entry.old_passwords = ++p;
+ entry.count--;
+ }
+
+ if (entry.count == 1)
+ {
+ if (asprintf (&out, "%s:%s:%d:%s\n",
+ entry.user, entry.uid, entry.count,
+ oldpass) < 0)
+ {
+ free (save);
+ retval = PAM_AUTHTOK_ERR;
+ fclose (oldpf);
+ fclose (newpf);
+ goto error_opasswd;
+ }
+ }
+ else
+ {
+ if (asprintf (&out, "%s:%s:%d:%s,%s\n",
+ entry.user, entry.uid, entry.count,
+ entry.old_passwords, oldpass) < 0)
+ {
+ free (save);
+ retval = PAM_AUTHTOK_ERR;
+ fclose (oldpf);
+ fclose (newpf);
+ goto error_opasswd;
+ }
+ }
+
+ if (fputs (out, newpf) < 0)
+ {
+ free (out);
+ free (save);
+ retval = PAM_AUTHTOK_ERR;
+ fclose (oldpf);
+ fclose (newpf);
+ goto error_opasswd;
+ }
+ free (out);
+ }
+ }
+ else
+ {
+ write_old_data:
+ if (fputs (save, newpf) < 0)
+ {
+ free (save);
+ retval = PAM_AUTHTOK_ERR;
+ fclose (oldpf);
+ fclose (newpf);
+ goto error_opasswd;
+ }
+ }
+ free (save);
+ }
+
+ if (!found)
+ {
+ char *out;
+
+ if (asprintf (&out, "%s:%d:1:%s\n", user, pwd->pw_uid, oldpass) < 0)
+ {
+ retval = PAM_AUTHTOK_ERR;
+ if (oldpf)
+ fclose (oldpf);
+ fclose (newpf);
+ goto error_opasswd;
+ }
+ if (fputs (out, newpf) < 0)
+ {
+ free (out);
+ retval = PAM_AUTHTOK_ERR;
+ if (oldpf)
+ fclose (oldpf);
+ fclose (newpf);
+ goto error_opasswd;
+ }
+ free (out);
+ }
+
+ if (oldpf)
+ if (fclose (oldpf) != 0)
+ {
+ pam_syslog (pamh, LOG_ERR, "Error while closing old opasswd file: %m");
+ retval = PAM_AUTHTOK_ERR;
+ fclose (newpf);
+ goto error_opasswd;
+ }
+
+ if (fflush (newpf) != 0 || fsync (fileno (newpf)) != 0)
+ {
+ pam_syslog (pamh, LOG_ERR,
+ "Error while syncing temporary opasswd file: %m");
+ retval = PAM_AUTHTOK_ERR;
+ fclose (newpf);
+ goto error_opasswd;
+ }
+
+ if (fclose (newpf) != 0)
+ {
+ pam_syslog (pamh, LOG_ERR,
+ "Error while closing temporary opasswd file: %m");
+ retval = PAM_AUTHTOK_ERR;
+ goto error_opasswd;
+ }
+
+ unlink (OLD_PASSWORDS_FILE".old");
+ if (link (OLD_PASSWORDS_FILE, OLD_PASSWORDS_FILE".old") != 0 &&
+ errno != ENOENT)
+ pam_syslog (pamh, LOG_ERR, "Cannot create backup file of %s: %m",
+ OLD_PASSWORDS_FILE);
+ rename (opasswd_tmp, OLD_PASSWORDS_FILE);
+ error_opasswd:
+ unlink (opasswd_tmp);
+ free (buf);
+
+ return retval;
+}
diff --git a/modules/pam_pwhistory/opasswd.h b/modules/pam_pwhistory/opasswd.h
new file mode 100644
index 0000000..3f25728
--- /dev/null
+++ b/modules/pam_pwhistory/opasswd.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2008 Thorsten Kukuk <kukuk@suse.de>
+ * Copyright (c) 2013 Red Hat, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __OPASSWD_H__
+#define __OPASSWD_H__
+
+#define PAM_PWHISTORY_RUN_HELPER PAM_CRED_INSUFFICIENT
+
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#define SELINUX_ENABLED (is_selinux_enabled()>0)
+#else
+#define SELINUX_ENABLED 0
+#endif
+
+#ifdef HELPER_COMPILE
+#define PAMH_ARG_DECL(fname, ...) fname(__VA_ARGS__)
+#else
+#define PAMH_ARG_DECL(fname, ...) fname(pam_handle_t *pamh, __VA_ARGS__)
+#endif
+
+#ifdef HELPER_COMPILE
+void
+helper_log_err(int err, const char *format, ...);
+#endif
+
+PAMH_ARG_DECL(int
+check_old_pass, const char *user, const char *newpass, int debug);
+
+PAMH_ARG_DECL(int
+save_old_pass, const char *user, int howmany, int debug);
+
+#endif /* __OPASSWD_H__ */
diff --git a/modules/pam_pwhistory/pam_pwhistory.8 b/modules/pam_pwhistory/pam_pwhistory.8
new file mode 100644
index 0000000..bdbd6c8
--- /dev/null
+++ b/modules/pam_pwhistory/pam_pwhistory.8
@@ -0,0 +1,163 @@
+'\" t
+.\" Title: pam_pwhistory
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_PWHISTORY" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_pwhistory \- PAM module to remember last passwords
+.SH "SYNOPSIS"
+.HP \w'\fBpam_pwhistory\&.so\fR\ 'u
+\fBpam_pwhistory\&.so\fR [debug] [use_authtok] [enforce_for_root] [remember=\fIN\fR] [retry=\fIN\fR] [authtok_type=\fISTRING\fR]
+.SH "DESCRIPTION"
+.PP
+This module saves the last passwords for each user in order to force password change history and keep the user from alternating between the same password too frequently\&.
+.PP
+This module does not work together with kerberos\&. In general, it does not make much sense to use this module in conjunction with NIS or LDAP, since the old passwords are stored on the local machine and are not available on another machine for password history checking\&.
+.SH "OPTIONS"
+.PP
+\fBdebug\fR
+.RS 4
+Turns on debugging via
+\fBsyslog\fR(3)\&.
+.RE
+.PP
+\fBuse_authtok\fR
+.RS 4
+When password changing enforce the module to use the new password provided by a previously stacked
+\fBpassword\fR
+module (this is used in the example of the stacking of the
+\fBpam_passwdqc\fR
+module documented below)\&.
+.RE
+.PP
+\fBenforce_for_root\fR
+.RS 4
+If this option is set, the check is enforced for root, too\&.
+.RE
+.PP
+\fBremember=\fR\fB\fIN\fR\fR
+.RS 4
+The last
+\fIN\fR
+passwords for each user are saved in
+/etc/security/opasswd\&. The default is
+\fI10\fR\&. Value of
+\fI0\fR
+makes the module to keep the existing contents of the
+opasswd
+file unchanged\&.
+.RE
+.PP
+\fBretry=\fR\fB\fIN\fR\fR
+.RS 4
+Prompt user at most
+\fIN\fR
+times before returning with error\&. The default is
+\fI1\fR\&.
+.RE
+.PP
+\fBauthtok_type=\fR\fB\fISTRING\fR\fR
+.RS 4
+See
+\fBpam_get_authtok\fR(3)
+for more details\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+Only the
+\fBpassword\fR
+module type is provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_AUTHTOK_ERR
+.RS 4
+No new password was entered, the user aborted password change or new password couldn\*(Aqt be set\&.
+.RE
+.PP
+PAM_IGNORE
+.RS 4
+Password history was disabled\&.
+.RE
+.PP
+PAM_MAXTRIES
+.RS 4
+Password was rejected too often\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+User is not known to system\&.
+.RE
+.SH "EXAMPLES"
+.PP
+An example password section would be:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+#%PAM\-1\&.0
+password required pam_pwhistory\&.so
+password required pam_unix\&.so use_authtok
+
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+In combination with
+\fBpam_passwdqc\fR:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+#%PAM\-1\&.0
+password required pam_passwdqc\&.so config=/etc/passwdqc\&.conf
+password required pam_pwhistory\&.so use_authtok
+password required pam_unix\&.so use_authtok
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "FILES"
+.PP
+/etc/security/opasswd
+.RS 4
+File with password history
+.RE
+.SH "SEE ALSO"
+.PP
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+\fBpam_get_authtok\fR(3)
+.SH "AUTHOR"
+.PP
+pam_pwhistory was written by Thorsten Kukuk <kukuk@thkukuk\&.de>
diff --git a/modules/pam_pwhistory/pam_pwhistory.8.xml b/modules/pam_pwhistory/pam_pwhistory.8.xml
new file mode 100644
index 0000000..d88115c
--- /dev/null
+++ b/modules/pam_pwhistory/pam_pwhistory.8.xml
@@ -0,0 +1,247 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_pwhistory">
+
+ <refmeta>
+ <refentrytitle>pam_pwhistory</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_pwhistory-name">
+ <refname>pam_pwhistory</refname>
+ <refpurpose>PAM module to remember last passwords</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_pwhistory-cmdsynopsis">
+ <command>pam_pwhistory.so</command>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ use_authtok
+ </arg>
+ <arg choice="opt">
+ enforce_for_root
+ </arg>
+ <arg choice="opt">
+ remember=<replaceable>N</replaceable>
+ </arg>
+ <arg choice="opt">
+ retry=<replaceable>N</replaceable>
+ </arg>
+ <arg choice="opt">
+ authtok_type=<replaceable>STRING</replaceable>
+ </arg>
+
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_pwhistory-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ This module saves the last passwords for each user in order
+ to force password change history and keep the user from
+ alternating between the same password too frequently.
+ </para>
+ <para>
+ This module does not work together with kerberos. In general,
+ it does not make much sense to use this module in conjunction
+ with NIS or LDAP, since the old passwords are stored on the
+ local machine and are not available on another machine for
+ password history checking.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_pwhistory-options">
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Turns on debugging via
+ <citerefentry>
+ <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>use_authtok</option>
+ </term>
+ <listitem>
+ <para>
+ When password changing enforce the module to use the new password
+ provided by a previously stacked <option>password</option>
+ module (this is used in the example of the stacking of the
+ <command>pam_passwdqc</command> module documented below).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>enforce_for_root</option>
+ </term>
+ <listitem>
+ <para>
+ If this option is set, the check is enforced for root, too.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>remember=<replaceable>N</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The last <replaceable>N</replaceable> passwords for each
+ user are saved in <filename>/etc/security/opasswd</filename>.
+ The default is <emphasis>10</emphasis>. Value of
+ <emphasis>0</emphasis> makes the module to keep the existing
+ contents of the <filename>opasswd</filename> file unchanged.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>retry=<replaceable>N</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Prompt user at most <replaceable>N</replaceable> times
+ before returning with error. The default is
+ <emphasis>1</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>authtok_type=<replaceable>STRING</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ See <citerefentry>
+ <refentrytitle>pam_get_authtok</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry> for more details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_pwhistory-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ Only the <option>password</option> module type is provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_pwhistory-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_AUTHTOK_ERR</term>
+ <listitem>
+ <para>
+ No new password was entered, the user aborted password
+ change or new password couldn't be set.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ Password history was disabled.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_MAXTRIES</term>
+ <listitem>
+ <para>
+ Password was rejected too often.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ User is not known to system.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_pwhistory-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ An example password section would be:
+ <programlisting>
+#%PAM-1.0
+password required pam_pwhistory.so
+password required pam_unix.so use_authtok
+ </programlisting>
+ </para>
+ <para>
+ In combination with <command>pam_passwdqc</command>:
+ <programlisting>
+#%PAM-1.0
+password required pam_passwdqc.so config=/etc/passwdqc.conf
+password required pam_pwhistory.so use_authtok
+password required pam_unix.so use_authtok
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_pwhistory-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/security/opasswd</filename></term>
+ <listitem>
+ <para>File with password history</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_pwhistory-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ <citerefentry>
+ <refentrytitle>pam_get_authtok</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_pwhistory-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_pwhistory was written by Thorsten Kukuk &lt;kukuk@thkukuk.de&gt;
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_pwhistory/pam_pwhistory.c b/modules/pam_pwhistory/pam_pwhistory.c
new file mode 100644
index 0000000..ce2c21f
--- /dev/null
+++ b/modules/pam_pwhistory/pam_pwhistory.c
@@ -0,0 +1,390 @@
+/*
+ * pam_pwhistory module
+ *
+ * Copyright (c) 2008, 2012 Thorsten Kukuk
+ * Author: Thorsten Kukuk <kukuk@thkukuk.de>
+ * Copyright (c) 2013 Red Hat, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(HAVE_CONFIG_H)
+#include <config.h>
+#endif
+
+#include <pwd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <fcntl.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+#include <security/_pam_macros.h>
+
+#include "opasswd.h"
+#include "pam_inline.h"
+
+struct options_t {
+ int debug;
+ int enforce_for_root;
+ int remember;
+ int tries;
+};
+typedef struct options_t options_t;
+
+
+static void
+parse_option (pam_handle_t *pamh, const char *argv, options_t *options)
+{
+ const char *str;
+
+ if (strcasecmp (argv, "try_first_pass") == 0)
+ /* ignore */;
+ else if (strcasecmp (argv, "use_first_pass") == 0)
+ /* ignore */;
+ else if (strcasecmp (argv, "use_authtok") == 0)
+ /* ignore, handled by pam_get_authtok */;
+ else if (strcasecmp (argv, "debug") == 0)
+ options->debug = 1;
+ else if ((str = pam_str_skip_icase_prefix(argv, "remember=")) != NULL)
+ {
+ options->remember = strtol(str, NULL, 10);
+ if (options->remember < 0)
+ options->remember = 0;
+ if (options->remember > 400)
+ options->remember = 400;
+ }
+ else if ((str = pam_str_skip_icase_prefix(argv, "retry=")) != NULL)
+ {
+ options->tries = strtol(str, NULL, 10);
+ if (options->tries < 0)
+ options->tries = 1;
+ }
+ else if (strcasecmp (argv, "enforce_for_root") == 0)
+ options->enforce_for_root = 1;
+ else if (pam_str_skip_icase_prefix(argv, "authtok_type=") != NULL)
+ { /* ignore, for pam_get_authtok */; }
+ else
+ pam_syslog (pamh, LOG_ERR, "pam_pwhistory: unknown option: %s", argv);
+}
+
+static int
+run_save_helper(pam_handle_t *pamh, const char *user,
+ int howmany, int debug)
+{
+ int retval, child;
+ struct sigaction newsa, oldsa;
+
+ memset(&newsa, '\0', sizeof(newsa));
+ newsa.sa_handler = SIG_DFL;
+ sigaction(SIGCHLD, &newsa, &oldsa);
+
+ child = fork();
+ if (child == 0)
+ {
+ static char *envp[] = { NULL };
+ char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL };
+
+ if (pam_modutil_sanitize_helper_fds(pamh, PAM_MODUTIL_PIPE_FD,
+ PAM_MODUTIL_PIPE_FD,
+ PAM_MODUTIL_PIPE_FD) < 0)
+ {
+ _exit(PAM_SYSTEM_ERR);
+ }
+
+ /* exec binary helper */
+ DIAG_PUSH_IGNORE_CAST_QUAL;
+ args[0] = (char *)PWHISTORY_HELPER;
+ args[1] = (char *)"save";
+ args[2] = (char *)user;
+ DIAG_POP_IGNORE_CAST_QUAL;
+ if (asprintf(&args[3], "%d", howmany) < 0 ||
+ asprintf(&args[4], "%d", debug) < 0)
+ {
+ pam_syslog(pamh, LOG_ERR, "asprintf: %m");
+ _exit(PAM_SYSTEM_ERR);
+ }
+
+ execve(args[0], args, envp);
+
+ pam_syslog(pamh, LOG_ERR, "helper binary execve failed: %s: %m", args[0]);
+
+ _exit(PAM_SYSTEM_ERR);
+ }
+ else if (child > 0)
+ {
+ /* wait for child */
+ int rc = 0;
+ while ((rc = waitpid (child, &retval, 0)) == -1 &&
+ errno == EINTR);
+ if (rc < 0)
+ {
+ pam_syslog(pamh, LOG_ERR, "pwhistory_helper save: waitpid: %m");
+ retval = PAM_SYSTEM_ERR;
+ }
+ else if (!WIFEXITED(retval))
+ {
+ pam_syslog(pamh, LOG_ERR, "pwhistory_helper save abnormal exit: %d", retval);
+ retval = PAM_SYSTEM_ERR;
+ }
+ else
+ {
+ retval = WEXITSTATUS(retval);
+ }
+ }
+ else
+ {
+ pam_syslog(pamh, LOG_ERR, "fork failed: %m");
+ retval = PAM_SYSTEM_ERR;
+ }
+
+ sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */
+
+ return retval;
+}
+
+static int
+run_check_helper(pam_handle_t *pamh, const char *user,
+ const char *newpass, int debug)
+{
+ int retval, child, fds[2];
+ struct sigaction newsa, oldsa;
+
+ /* create a pipe for the password */
+ if (pipe(fds) != 0)
+ return PAM_SYSTEM_ERR;
+
+ memset(&newsa, '\0', sizeof(newsa));
+ newsa.sa_handler = SIG_DFL;
+ sigaction(SIGCHLD, &newsa, &oldsa);
+
+ child = fork();
+ if (child == 0)
+ {
+ static char *envp[] = { NULL };
+ char *args[] = { NULL, NULL, NULL, NULL, NULL };
+
+ /* reopen stdin as pipe */
+ if (dup2(fds[0], STDIN_FILENO) != STDIN_FILENO)
+ {
+ pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", "stdin");
+ _exit(PAM_SYSTEM_ERR);
+ }
+
+ if (pam_modutil_sanitize_helper_fds(pamh, PAM_MODUTIL_IGNORE_FD,
+ PAM_MODUTIL_PIPE_FD,
+ PAM_MODUTIL_PIPE_FD) < 0)
+ {
+ _exit(PAM_SYSTEM_ERR);
+ }
+
+ /* exec binary helper */
+ DIAG_PUSH_IGNORE_CAST_QUAL;
+ args[0] = (char *)PWHISTORY_HELPER;
+ args[1] = (char *)"check";
+ args[2] = (char *)user;
+ DIAG_POP_IGNORE_CAST_QUAL;
+ if (asprintf(&args[3], "%d", debug) < 0)
+ {
+ pam_syslog(pamh, LOG_ERR, "asprintf: %m");
+ _exit(PAM_SYSTEM_ERR);
+ }
+
+ execve(args[0], args, envp);
+
+ pam_syslog(pamh, LOG_ERR, "helper binary execve failed: %s: %m", args[0]);
+
+ _exit(PAM_SYSTEM_ERR);
+ }
+ else if (child > 0)
+ {
+ /* wait for child */
+ int rc = 0;
+ if (newpass == NULL)
+ newpass = "";
+
+ /* send the password to the child */
+ if (write(fds[1], newpass, strlen(newpass)+1) == -1)
+ {
+ pam_syslog(pamh, LOG_ERR, "Cannot send password to helper: %m");
+ retval = PAM_SYSTEM_ERR;
+ }
+ newpass = NULL;
+ close(fds[0]); /* close here to avoid possible SIGPIPE above */
+ close(fds[1]);
+ while ((rc = waitpid (child, &retval, 0)) == -1 &&
+ errno == EINTR);
+ if (rc < 0)
+ {
+ pam_syslog(pamh, LOG_ERR, "pwhistory_helper check: waitpid: %m");
+ retval = PAM_SYSTEM_ERR;
+ }
+ else if (!WIFEXITED(retval))
+ {
+ pam_syslog(pamh, LOG_ERR, "pwhistory_helper check abnormal exit: %d", retval);
+ retval = PAM_SYSTEM_ERR;
+ }
+ else
+ {
+ retval = WEXITSTATUS(retval);
+ }
+ }
+ else
+ {
+ pam_syslog(pamh, LOG_ERR, "fork failed: %m");
+ close(fds[0]);
+ close(fds[1]);
+ retval = PAM_SYSTEM_ERR;
+ }
+
+ sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */
+
+ return retval;
+}
+
+/* This module saves the current hashed password in /etc/security/opasswd
+ and then compares the new password with all entries in this file. */
+
+int
+pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ const char *newpass;
+ const char *user;
+ int retval, tries;
+ options_t options;
+
+ memset (&options, 0, sizeof (options));
+
+ /* Set some default values, which could be overwritten later. */
+ options.remember = 10;
+ options.tries = 1;
+
+ /* Parse parameters for module */
+ for ( ; argc-- > 0; argv++)
+ parse_option (pamh, *argv, &options);
+
+ if (options.debug)
+ pam_syslog (pamh, LOG_DEBUG, "pam_sm_chauthtok entered");
+
+
+ if (options.remember == 0)
+ return PAM_IGNORE;
+
+ retval = pam_get_user (pamh, &user, NULL);
+ if (retval != PAM_SUCCESS)
+ return retval;
+
+ if (flags & PAM_PRELIM_CHECK)
+ {
+ if (options.debug)
+ pam_syslog (pamh, LOG_DEBUG,
+ "pam_sm_chauthtok(PAM_PRELIM_CHECK)");
+
+ return PAM_SUCCESS;
+ }
+
+ retval = save_old_pass (pamh, user, options.remember, options.debug);
+
+ if (retval == PAM_PWHISTORY_RUN_HELPER)
+ retval = run_save_helper(pamh, user, options.remember, options.debug);
+
+ if (retval != PAM_SUCCESS)
+ return retval;
+
+ newpass = NULL;
+ tries = 0;
+ while ((newpass == NULL) && (tries < options.tries))
+ {
+ retval = pam_get_authtok (pamh, PAM_AUTHTOK, &newpass, NULL);
+ if (retval != PAM_SUCCESS && retval != PAM_TRY_AGAIN)
+ {
+ if (retval == PAM_CONV_AGAIN)
+ retval = PAM_INCOMPLETE;
+ return retval;
+ }
+ tries++;
+
+ if (options.debug)
+ {
+ if (newpass)
+ pam_syslog (pamh, LOG_DEBUG, "got new auth token");
+ else
+ pam_syslog (pamh, LOG_DEBUG, "got no auth token");
+ }
+
+ if (newpass == NULL || retval == PAM_TRY_AGAIN)
+ continue;
+
+ if (options.debug)
+ pam_syslog (pamh, LOG_DEBUG, "check against old password file");
+
+ retval = check_old_pass (pamh, user, newpass, options.debug);
+ if (retval == PAM_PWHISTORY_RUN_HELPER)
+ retval = run_check_helper(pamh, user, newpass, options.debug);
+
+ if (retval != PAM_SUCCESS)
+ {
+ if (getuid() || options.enforce_for_root ||
+ (flags & PAM_CHANGE_EXPIRED_AUTHTOK))
+ {
+ pam_error (pamh,
+ _("Password has been already used. Choose another."));
+ newpass = NULL;
+ /* Remove password item, else following module will use it */
+ pam_set_item (pamh, PAM_AUTHTOK, (void *) NULL);
+ }
+ else
+ pam_info (pamh,
+ _("Password has been already used."));
+ }
+ }
+
+ if (newpass == NULL && tries >= options.tries)
+ {
+ if (options.debug)
+ pam_syslog (pamh, LOG_DEBUG, "Aborted, too many tries");
+ return PAM_MAXTRIES;
+ }
+
+ return PAM_SUCCESS;
+}
diff --git a/modules/pam_pwhistory/pwhistory_helper.8 b/modules/pam_pwhistory/pwhistory_helper.8
new file mode 100644
index 0000000..684b5b0
--- /dev/null
+++ b/modules/pam_pwhistory/pwhistory_helper.8
@@ -0,0 +1,54 @@
+'\" t
+.\" Title: pwhistory_helper
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PWHISTORY_HELPER" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pwhistory_helper \- Helper binary that transfers password hashes from passwd or shadow to opasswd
+.SH "SYNOPSIS"
+.HP \w'\fBpwhistory_helper\fR\ 'u
+\fBpwhistory_helper\fR [\&.\&.\&.]
+.SH "DESCRIPTION"
+.PP
+\fIpwhistory_helper\fR
+is a helper program for the
+\fIpam_pwhistory\fR
+module that transfers password hashes from passwd or shadow file to the opasswd file and checks a password supplied by user against the existing hashes in the opasswd file\&.
+.PP
+The purpose of the helper is to enable tighter confinement of login and password changing services\&. The helper is thus called only when SELinux is enabled on the system\&.
+.PP
+The interface of the helper \- command line options, and input/output data format are internal to the
+\fIpam_pwhistory\fR
+module and it should not be called directly from applications\&.
+.SH "SEE ALSO"
+.PP
+\fBpam_pwhistory\fR(8)
+.SH "AUTHOR"
+.PP
+Written by Tomas Mraz based on the code originally in
+\fIpam_pwhistory and pam_unix\fR
+modules\&.
diff --git a/modules/pam_pwhistory/pwhistory_helper.8.xml b/modules/pam_pwhistory/pwhistory_helper.8.xml
new file mode 100644
index 0000000..a030176
--- /dev/null
+++ b/modules/pam_pwhistory/pwhistory_helper.8.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pwhistory_helper">
+
+ <refmeta>
+ <refentrytitle>pwhistory_helper</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pwhistory_helper-name">
+ <refname>pwhistory_helper</refname>
+ <refpurpose>Helper binary that transfers password hashes from passwd or shadow to opasswd</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pwhistory_helper-cmdsynopsis">
+ <command>pwhistory_helper</command>
+ <arg choice="opt">
+ ...
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pwhistory_helper-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ <emphasis>pwhistory_helper</emphasis> is a helper program for the
+ <emphasis>pam_pwhistory</emphasis> module that transfers password hashes
+ from passwd or shadow file to the opasswd file and checks a password
+ supplied by user against the existing hashes in the opasswd file.
+ </para>
+
+ <para>
+ The purpose of the helper is to enable tighter confinement of
+ login and password changing services. The helper is thus called only
+ when SELinux is enabled on the system.
+ </para>
+
+ <para>
+ The interface of the helper - command line options, and input/output
+ data format are internal to the <emphasis>pam_pwhistory</emphasis>
+ module and it should not be called directly from applications.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pwhistory_helper-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam_pwhistory</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pwhistory_helper-author'>
+ <title>AUTHOR</title>
+ <para>
+ Written by Tomas Mraz based on the code originally in
+ <emphasis>pam_pwhistory and pam_unix</emphasis> modules.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_pwhistory/pwhistory_helper.c b/modules/pam_pwhistory/pwhistory_helper.c
new file mode 100644
index 0000000..b08a14a
--- /dev/null
+++ b/modules/pam_pwhistory/pwhistory_helper.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2013 Red Hat, Inc.
+ * Author: Tomas Mraz <tmraz@redhat.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
+#include <security/_pam_types.h>
+#include <security/_pam_macros.h>
+#include <security/pam_modutil.h>
+#include "opasswd.h"
+#include "pam_inline.h"
+
+
+static int
+check_history(const char *user, const char *debug)
+{
+ char pass[PAM_MAX_RESP_SIZE + 1];
+ char *passwords[] = { pass };
+ int npass;
+ int dbg = atoi(debug); /* no need to be too fancy here */
+ int retval;
+
+ /* read the password from stdin (a pipe from the pam_pwhistory module) */
+ npass = pam_read_passwords(STDIN_FILENO, 1, passwords);
+
+ if (npass != 1)
+ { /* is it a valid password? */
+ helper_log_err(LOG_DEBUG, "no password supplied");
+ return PAM_AUTHTOK_ERR;
+ }
+
+ retval = check_old_pass(user, pass, dbg);
+
+ memset(pass, '\0', PAM_MAX_RESP_SIZE); /* clear memory of the password */
+
+ return retval;
+}
+
+static int
+save_history(const char *user, const char *howmany, const char *debug)
+{
+ int num = atoi(howmany);
+ int dbg = atoi(debug); /* no need to be too fancy here */
+ int retval;
+
+ retval = save_old_pass(user, num, dbg);
+
+ return retval;
+}
+
+int
+main(int argc, char *argv[])
+{
+ const char *option;
+ const char *user;
+
+ /*
+ * we establish that this program is running with non-tty stdin.
+ * this is to discourage casual use.
+ */
+
+ if (isatty(STDIN_FILENO) || argc < 4)
+ {
+ fprintf(stderr,
+ "This binary is not designed for running in this way.\n");
+ return PAM_SYSTEM_ERR;
+ }
+
+ option = argv[1];
+ user = argv[2];
+
+ if (strcmp(option, "check") == 0 && argc == 4)
+ return check_history(user, argv[3]);
+ else if (strcmp(option, "save") == 0 && argc == 5)
+ return save_history(user, argv[3], argv[4]);
+
+ fprintf(stderr, "This binary is not designed for running in this way.\n");
+
+ return PAM_SYSTEM_ERR;
+}
diff --git a/modules/pam_pwhistory/tst-pam_pwhistory b/modules/pam_pwhistory/tst-pam_pwhistory
new file mode 100755
index 0000000..3531a88
--- /dev/null
+++ b/modules/pam_pwhistory/tst-pam_pwhistory
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_pwhistory.so
diff --git a/modules/pam_rhosts/Makefile.am b/modules/pam_rhosts/Makefile.am
new file mode 100644
index 0000000..cc3f2f2
--- /dev/null
+++ b/modules/pam_rhosts/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2005, 2006, 2008, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_rhosts.8
+endif
+XMLS = README.xml pam_rhosts.8.xml
+dist_check_SCRIPTS = tst-pam_rhosts
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_rhosts.la
+pam_rhosts_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_rhosts/Makefile.in b/modules/pam_rhosts/Makefile.in
new file mode 100644
index 0000000..6cfb1ff
--- /dev/null
+++ b/modules/pam_rhosts/Makefile.in
@@ -0,0 +1,1150 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2008, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_rhosts
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_rhosts_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_rhosts_la_SOURCES = pam_rhosts.c
+pam_rhosts_la_OBJECTS = pam_rhosts.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_rhosts.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_rhosts.c
+DIST_SOURCES = pam_rhosts.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_rhosts.8
+XMLS = README.xml pam_rhosts.8.xml
+dist_check_SCRIPTS = tst-pam_rhosts
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_rhosts.la
+pam_rhosts_la_LIBADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_rhosts/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_rhosts/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_rhosts.la: $(pam_rhosts_la_OBJECTS) $(pam_rhosts_la_DEPENDENCIES) $(EXTRA_pam_rhosts_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_rhosts_la_OBJECTS) $(pam_rhosts_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_rhosts.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_rhosts.log: tst-pam_rhosts
+ @p='tst-pam_rhosts'; \
+ b='tst-pam_rhosts'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_rhosts.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_rhosts.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_rhosts/README b/modules/pam_rhosts/README
new file mode 100644
index 0000000..aedc0f5
--- /dev/null
+++ b/modules/pam_rhosts/README
@@ -0,0 +1,56 @@
+pam_rhosts — The rhosts PAM module
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+This module performs the standard network authentication for services, as used
+by traditional implementations of rlogin and rsh etc.
+
+The authentication mechanism of this module is based on the contents of two
+files; /etc/hosts.equiv (or and ~/.rhosts. Firstly, hosts listed in the former
+file are treated as equivalent to the localhost. Secondly, entries in the
+user's own copy of the latter file is used to map "remote-host remote-user"
+pairs to that user's account on the current host. Access is granted to the user
+if their host is present in /etc/hosts.equiv and their remote account is
+identical to their local one, or if their remote account has an entry in their
+personal configuration file.
+
+The module authenticates a remote user (internally specified by the item
+PAM_RUSER connecting from the remote host (internally specified by the item
+PAM_RHOST). Accordingly, for applications to be compatible this authentication
+module they must set these items prior to calling pam_authenticate(). The
+module is not capable of independently probing the network connection for such
+information.
+
+OPTIONS
+
+debug
+
+ Print debug information.
+
+silent
+
+ Don't print informative messages.
+
+superuser=account
+
+ Handle account as root.
+
+EXAMPLES
+
+To grant a remote user access by /etc/hosts.equiv or .rhosts for rsh add the
+following lines to /etc/pam.d/rsh:
+
+#%PAM-1.0
+#
+auth required pam_rhosts.so
+auth required pam_nologin.so
+auth required pam_env.so
+auth required pam_unix.so
+
+
+AUTHOR
+
+pam_rhosts was written by Thorsten Kukuk <kukuk@thkukuk.de>
+
diff --git a/modules/pam_rhosts/README.xml b/modules/pam_rhosts/README.xml
new file mode 100644
index 0000000..5d3307e
--- /dev/null
+++ b/modules/pam_rhosts/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_rhosts.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_rhosts.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_rhosts-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_rhosts.8.xml" xpointer='xpointer(//refsect1[@id = "pam_rhosts-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_rhosts.8.xml" xpointer='xpointer(//refsect1[@id = "pam_rhosts-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_rhosts.8.xml" xpointer='xpointer(//refsect1[@id = "pam_rhosts-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_rhosts.8.xml" xpointer='xpointer(//refsect1[@id = "pam_rhosts-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_rhosts/pam_rhosts.8 b/modules/pam_rhosts/pam_rhosts.8
new file mode 100644
index 0000000..61e9a44
--- /dev/null
+++ b/modules/pam_rhosts/pam_rhosts.8
@@ -0,0 +1,128 @@
+'\" t
+.\" Title: pam_rhosts
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_RHOSTS" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_rhosts \- The rhosts PAM module
+.SH "SYNOPSIS"
+.HP \w'\fBpam_rhosts\&.so\fR\ 'u
+\fBpam_rhosts\&.so\fR
+.SH "DESCRIPTION"
+.PP
+This module performs the standard network authentication for services, as used by traditional implementations of
+\fBrlogin\fR
+and
+\fBrsh\fR
+etc\&.
+.PP
+The authentication mechanism of this module is based on the contents of two files;
+/etc/hosts\&.equiv
+(or and
+~/\&.rhosts\&. Firstly, hosts listed in the former file are treated as equivalent to the localhost\&. Secondly, entries in the user\*(Aqs own copy of the latter file is used to map "\fIremote\-host remote\-user\fR" pairs to that user\*(Aqs account on the current host\&. Access is granted to the user if their host is present in
+/etc/hosts\&.equiv
+and their remote account is identical to their local one, or if their remote account has an entry in their personal configuration file\&.
+.PP
+The module authenticates a remote user (internally specified by the item
+\fIPAM_RUSER\fR
+connecting from the remote host (internally specified by the item
+\fBPAM_RHOST\fR)\&. Accordingly, for applications to be compatible this authentication module they must set these items prior to calling
+\fBpam_authenticate()\fR\&. The module is not capable of independently probing the network connection for such information\&.
+.SH "OPTIONS"
+.PP
+\fBdebug\fR
+.RS 4
+Print debug information\&.
+.RE
+.PP
+\fBsilent\fR
+.RS 4
+Don\*(Aqt print informative messages\&.
+.RE
+.PP
+\fBsuperuser=\fR\fB\fIaccount\fR\fR
+.RS 4
+Handle
+\fIaccount\fR
+as root\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+Only the
+\fBauth\fR
+module type is provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_AUTH_ERR
+.RS 4
+The remote host, remote user name or the local user name couldn\*(Aqt be determined or access was denied by
+\&.rhosts
+file\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+User is not known to system\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To grant a remote user access by
+/etc/hosts\&.equiv
+or
+\&.rhosts
+for
+\fBrsh\fR
+add the following lines to
+/etc/pam\&.d/rsh:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+#%PAM\-1\&.0
+#
+auth required pam_rhosts\&.so
+auth required pam_nologin\&.so
+auth required pam_env\&.so
+auth required pam_unix\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.PP
+\fBrootok\fR(3),
+\fBhosts.equiv\fR(5),
+\fBrhosts\fR(5),
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_rhosts was written by Thorsten Kukuk <kukuk@thkukuk\&.de>
diff --git a/modules/pam_rhosts/pam_rhosts.8.xml b/modules/pam_rhosts/pam_rhosts.8.xml
new file mode 100644
index 0000000..eb96371
--- /dev/null
+++ b/modules/pam_rhosts/pam_rhosts.8.xml
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_rhosts">
+
+ <refmeta>
+ <refentrytitle>pam_rhosts</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_rhosts-name">
+ <refname>pam_rhosts</refname>
+ <refpurpose>The rhosts PAM module</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_rhosts-cmdsynopsis">
+ <command>pam_rhosts.so</command>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_rhosts-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ This module performs the standard network authentication for services,
+ as used by traditional implementations of <command>rlogin</command>
+ and <command>rsh</command> etc.
+ </para>
+ <para>
+ The authentication mechanism of this module is based on the contents
+ of two files; <filename>/etc/hosts.equiv</filename> (or
+ and <filename>~/.rhosts</filename>. Firstly, hosts listed in the
+ former file are treated as equivalent to the localhost. Secondly,
+ entries in the user's own copy of the latter file is used to map
+ "<emphasis>remote-host remote-user</emphasis>" pairs to that user's
+ account on the current host. Access is granted to the user if their
+ host is present in <filename>/etc/hosts.equiv</filename> and their
+ remote account is identical to their local one, or if their remote
+ account has an entry in their personal configuration file.
+ </para>
+ <para>
+ The module authenticates a remote user (internally specified by the
+ item <parameter>PAM_RUSER</parameter> connecting from the remote
+ host (internally specified by the item <command>PAM_RHOST</command>).
+ Accordingly, for applications to be compatible this authentication
+ module they must set these items prior to calling
+ <function>pam_authenticate()</function>. The module is not capable
+ of independently probing the network connection for such information.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_rhosts-options">
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Print debug information.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>silent</option>
+ </term>
+ <listitem>
+ <para>
+ Don't print informative messages.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>superuser=<replaceable>account</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Handle <replaceable>account</replaceable> as root.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_rhosts-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ Only the <option>auth</option> module type is provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_rhosts-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_AUTH_ERR</term>
+ <listitem>
+ <para>
+ The remote host, remote user name or the local user name
+ couldn't be determined or access was denied by
+ <filename>.rhosts</filename> file.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ User is not known to system.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_rhosts-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ To grant a remote user access by <filename>/etc/hosts.equiv</filename>
+ or <filename>.rhosts</filename> for <command>rsh</command> add the
+ following lines to <filename>/etc/pam.d/rsh</filename>:
+ <programlisting>
+#%PAM-1.0
+#
+auth required pam_rhosts.so
+auth required pam_nologin.so
+auth required pam_env.so
+auth required pam_unix.so
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_rhosts-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>rootok</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>hosts.equiv</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>rhosts</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_rhosts-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_rhosts was written by Thorsten Kukuk &lt;kukuk@thkukuk.de&gt;
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_rhosts/pam_rhosts.c b/modules/pam_rhosts/pam_rhosts.c
new file mode 100644
index 0000000..a1b394d
--- /dev/null
+++ b/modules/pam_rhosts/pam_rhosts.c
@@ -0,0 +1,142 @@
+/*
+ * pam_rhosts module
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "config.h"
+
+#include <pwd.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <syslog.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+#include "pam_inline.h"
+
+int pam_sm_authenticate (pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ const char *luser = NULL;
+ const char *ruser = NULL, *rhost = NULL;
+ const char *opt_superuser = NULL;
+ const void *c_void;
+ int opt_debug = 0;
+ int opt_silent;
+ int as_root;
+ int retval;
+
+ opt_silent = flags & PAM_SILENT;
+
+ while (argc-- > 0) {
+ const char *str;
+
+ if (strcmp(*argv, "debug") == 0)
+ opt_debug = 1;
+ else if (strcmp (*argv, "silent") == 0 || strcmp(*argv, "suppress") == 0)
+ opt_silent = 1;
+ else if ((str = pam_str_skip_prefix(*argv, "superuser=")) != NULL)
+ opt_superuser = str;
+ else
+ pam_syslog(pamh, LOG_WARNING, "unrecognized option '%s'", *argv);
+
+ ++argv;
+ }
+
+ retval = pam_get_item (pamh, PAM_RHOST, &c_void);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR, "could not get the remote host name");
+ return retval;
+ }
+ rhost = c_void;
+
+ retval = pam_get_item(pamh, PAM_RUSER, &c_void);
+ ruser = c_void;
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR, "could not get the remote username");
+ return retval;
+ }
+
+ retval = pam_get_user(pamh, &luser, NULL);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE, "cannot determine local user name: %s",
+ pam_strerror(pamh, retval));
+ return retval;
+ }
+
+ if (rhost == NULL || ruser == NULL)
+ return PAM_AUTH_ERR;
+
+ if (opt_superuser && strcmp(opt_superuser, luser) == 0)
+ as_root = 1;
+ else {
+ struct passwd *lpwd;
+
+ lpwd = pam_modutil_getpwnam(pamh, luser);
+ if (lpwd == NULL) {
+ if (opt_debug)
+ /* don't print by default, could be the user's password */
+ pam_syslog(pamh, LOG_DEBUG,
+ "user '%s' unknown to this system", luser);
+ return PAM_USER_UNKNOWN;
+
+ }
+ as_root = (lpwd->pw_uid == 0);
+ }
+
+#ifdef HAVE_RUSEROK_AF
+ retval = ruserok_af (rhost, as_root, ruser, luser, PF_UNSPEC);
+#else
+ retval = ruserok (rhost, as_root, ruser, luser);
+#endif
+ if (retval != 0) {
+ if (!opt_silent || opt_debug)
+ pam_syslog(pamh, LOG_WARNING, "denied access to %s@%s as %s",
+ ruser, rhost, luser);
+ return PAM_AUTH_ERR;
+ } else {
+ if (!opt_silent || opt_debug)
+ pam_syslog(pamh, LOG_NOTICE, "allowed access to %s@%s as %s",
+ ruser, rhost, luser);
+ return PAM_SUCCESS;
+ }
+}
+
+
+int
+pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
diff --git a/modules/pam_rhosts/tst-pam_rhosts b/modules/pam_rhosts/tst-pam_rhosts
new file mode 100755
index 0000000..65e85a9
--- /dev/null
+++ b/modules/pam_rhosts/tst-pam_rhosts
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_rhosts.so
diff --git a/modules/pam_rootok/Makefile.am b/modules/pam_rootok/Makefile.am
new file mode 100644
index 0000000..787218b
--- /dev/null
+++ b/modules/pam_rootok/Makefile.am
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_rootok.8
+endif
+XMLS = README.xml pam_rootok.8.xml
+dist_check_SCRIPTS = tst-pam_rootok
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_rootok.la
+pam_rootok_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBSELINUX@ @LIBAUDIT@
+
+check_PROGRAMS = tst-pam_rootok-retval
+tst_pam_rootok_retval_LDADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_rootok/Makefile.in b/modules/pam_rootok/Makefile.in
new file mode 100644
index 0000000..d4422af
--- /dev/null
+++ b/modules/pam_rootok/Makefile.in
@@ -0,0 +1,1180 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+check_PROGRAMS = tst-pam_rootok-retval$(EXEEXT)
+subdir = modules/pam_rootok
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_rootok_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_rootok_la_SOURCES = pam_rootok.c
+pam_rootok_la_OBJECTS = pam_rootok.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+tst_pam_rootok_retval_SOURCES = tst-pam_rootok-retval.c
+tst_pam_rootok_retval_OBJECTS = tst-pam_rootok-retval.$(OBJEXT)
+tst_pam_rootok_retval_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_rootok.Plo \
+ ./$(DEPDIR)/tst-pam_rootok-retval.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_rootok.c tst-pam_rootok-retval.c
+DIST_SOURCES = pam_rootok.c tst-pam_rootok-retval.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_rootok.8
+XMLS = README.xml pam_rootok.8.xml
+dist_check_SCRIPTS = tst-pam_rootok
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_rootok.la
+pam_rootok_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBSELINUX@ @LIBAUDIT@
+tst_pam_rootok_retval_LDADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_rootok/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_rootok/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_rootok.la: $(pam_rootok_la_OBJECTS) $(pam_rootok_la_DEPENDENCIES) $(EXTRA_pam_rootok_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_rootok_la_OBJECTS) $(pam_rootok_la_LIBADD) $(LIBS)
+
+tst-pam_rootok-retval$(EXEEXT): $(tst_pam_rootok_retval_OBJECTS) $(tst_pam_rootok_retval_DEPENDENCIES) $(EXTRA_tst_pam_rootok_retval_DEPENDENCIES)
+ @rm -f tst-pam_rootok-retval$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tst_pam_rootok_retval_OBJECTS) $(tst_pam_rootok_retval_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_rootok.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-pam_rootok-retval.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_rootok.log: tst-pam_rootok
+ @p='tst-pam_rootok'; \
+ b='tst-pam_rootok'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+tst-pam_rootok-retval.log: tst-pam_rootok-retval$(EXEEXT)
+ @p='tst-pam_rootok-retval$(EXEEXT)'; \
+ b='tst-pam_rootok-retval'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) \
+ $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_rootok.Plo
+ -rm -f ./$(DEPDIR)/tst-pam_rootok-retval.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_rootok.Plo
+ -rm -f ./$(DEPDIR)/tst-pam_rootok-retval.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_rootok/README b/modules/pam_rootok/README
new file mode 100644
index 0000000..55a4475
--- /dev/null
+++ b/modules/pam_rootok/README
@@ -0,0 +1,33 @@
+pam_rootok — Gain only root access
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+pam_rootok is a PAM module that authenticates the user if their UID is 0.
+Applications that are created setuid-root generally retain the UID of the user
+but run with the authority of an enhanced effective-UID. It is the real UID
+that is checked.
+
+OPTIONS
+
+debug
+
+ Print debug information.
+
+EXAMPLES
+
+In the case of the su(1) application the historical usage is to permit the
+superuser to adopt the identity of a lesser user without the use of a password.
+To obtain this behavior with PAM the following pair of lines are needed for the
+corresponding entry in the /etc/pam.d/su configuration file:
+
+# su authentication. Root is granted access by default.
+auth sufficient pam_rootok.so
+auth required pam_unix.so
+
+
+AUTHOR
+
+pam_rootok was written by Andrew G. Morgan, <morgan@kernel.org>.
+
diff --git a/modules/pam_rootok/README.xml b/modules/pam_rootok/README.xml
new file mode 100644
index 0000000..6fb58cd
--- /dev/null
+++ b/modules/pam_rootok/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_rootok.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_rootok.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_rootok-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_rootok.8.xml" xpointer='xpointer(//refsect1[@id = "pam_rootok-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_rootok.8.xml" xpointer='xpointer(//refsect1[@id = "pam_rootok-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_rootok.8.xml" xpointer='xpointer(//refsect1[@id = "pam_rootok-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_rootok.8.xml" xpointer='xpointer(//refsect1[@id = "pam_rootok-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_rootok/pam_rootok.8 b/modules/pam_rootok/pam_rootok.8
new file mode 100644
index 0000000..861a6a6
--- /dev/null
+++ b/modules/pam_rootok/pam_rootok.8
@@ -0,0 +1,106 @@
+'\" t
+.\" Title: pam_rootok
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_ROOTOK" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_rootok \- Gain only root access
+.SH "SYNOPSIS"
+.HP \w'\fBpam_rootok\&.so\fR\ 'u
+\fBpam_rootok\&.so\fR [debug]
+.SH "DESCRIPTION"
+.PP
+pam_rootok is a PAM module that authenticates the user if their
+\fIUID\fR
+is
+\fI0\fR\&. Applications that are created setuid\-root generally retain the
+\fIUID\fR
+of the user but run with the authority of an enhanced effective\-UID\&. It is the real
+\fIUID\fR
+that is checked\&.
+.SH "OPTIONS"
+.PP
+\fBdebug\fR
+.RS 4
+Print debug information\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+The
+\fBauth\fR,
+\fBaccount\fR
+and
+\fBpassword\fR
+module types are provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_SUCCESS
+.RS 4
+The
+\fIUID\fR
+is
+\fI0\fR\&.
+.RE
+.PP
+PAM_AUTH_ERR
+.RS 4
+The
+\fIUID\fR
+is
+\fBnot\fR
+\fI0\fR\&.
+.RE
+.SH "EXAMPLES"
+.PP
+In the case of the
+\fBsu\fR(1)
+application the historical usage is to permit the superuser to adopt the identity of a lesser user without the use of a password\&. To obtain this behavior with PAM the following pair of lines are needed for the corresponding entry in the
+/etc/pam\&.d/su
+configuration file:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# su authentication\&. Root is granted access by default\&.
+auth sufficient pam_rootok\&.so
+auth required pam_unix\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.PP
+\fBsu\fR(1),
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_rootok was written by Andrew G\&. Morgan, <morgan@kernel\&.org>\&.
diff --git a/modules/pam_rootok/pam_rootok.8.xml b/modules/pam_rootok/pam_rootok.8.xml
new file mode 100644
index 0000000..06457bf
--- /dev/null
+++ b/modules/pam_rootok/pam_rootok.8.xml
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_rootok">
+
+ <refmeta>
+ <refentrytitle>pam_rootok</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_rootok-name">
+ <refname>pam_rootok</refname>
+ <refpurpose>Gain only root access</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_rootok-cmdsynopsis">
+ <command>pam_rootok.so</command>
+ <arg choice="opt">
+ debug
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_rootok-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ pam_rootok is a PAM module that authenticates the user if their
+ <emphasis>UID</emphasis> is <emphasis>0</emphasis>.
+ Applications that are created setuid-root generally retain the
+ <emphasis>UID</emphasis> of the user but run with the authority
+ of an enhanced effective-UID. It is the real <emphasis>UID</emphasis>
+ that is checked.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_rootok-options">
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Print debug information.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_rootok-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ The <option>auth</option>, <option>account</option> and
+ <option>password</option> module types are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_rootok-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ The <emphasis>UID</emphasis> is <emphasis>0</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_AUTH_ERR</term>
+ <listitem>
+ <para>
+ The <emphasis>UID</emphasis> is <emphasis remap='B'>not</emphasis>
+ <emphasis>0</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_rootok-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ In the case of the <citerefentry>
+ <refentrytitle>su</refentrytitle><manvolnum>1</manvolnum>
+ </citerefentry> application the historical usage is to
+ permit the superuser to adopt the identity of a lesser user
+ without the use of a password. To obtain this behavior with PAM
+ the following pair of lines are needed for the corresponding entry
+ in the <filename>/etc/pam.d/su</filename> configuration file:
+ <programlisting>
+# su authentication. Root is granted access by default.
+auth sufficient pam_rootok.so
+auth required pam_unix.so
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_rootok-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>su</refentrytitle><manvolnum>1</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_rootok-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_rootok was written by Andrew G. Morgan, &lt;morgan@kernel.org&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_rootok/pam_rootok.c b/modules/pam_rootok/pam_rootok.c
new file mode 100644
index 0000000..dd374c5
--- /dev/null
+++ b/modules/pam_rootok/pam_rootok.c
@@ -0,0 +1,174 @@
+/*
+ * pam_rootok module
+ *
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_ext.h>
+
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#include <selinux/avc.h>
+#endif
+
+#ifdef HAVE_LIBAUDIT
+#include <libaudit.h>
+#endif
+
+/* argument parsing */
+
+#define PAM_DEBUG_ARG 01
+
+static int
+_pam_parse (const pam_handle_t *pamh, int argc, const char **argv)
+{
+ int ctrl=0;
+
+ /* step through arguments */
+ for (ctrl=0; argc-- > 0; ++argv) {
+
+ /* generic options */
+
+ if (!strcmp(*argv,"debug"))
+ ctrl |= PAM_DEBUG_ARG;
+ else {
+ pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
+ }
+ }
+
+ return ctrl;
+}
+
+#ifdef WITH_SELINUX
+static int
+PAM_FORMAT((printf, 2, 3))
+log_callback (int type UNUSED, const char *fmt, ...)
+{
+ int audit_fd;
+ va_list ap;
+
+#ifdef HAVE_LIBAUDIT
+ audit_fd = audit_open();
+
+ if (audit_fd >= 0) {
+ char *buf;
+ int ret;
+
+ va_start(ap, fmt);
+ ret = vasprintf (&buf, fmt, ap);
+ va_end(ap);
+ if (ret < 0) {
+ return 0;
+ }
+ audit_log_user_avc_message(audit_fd, AUDIT_USER_AVC, buf, NULL, NULL,
+ NULL, 0);
+ audit_close(audit_fd);
+ free(buf);
+ va_end(ap);
+ return 0;
+ }
+
+#endif
+ va_start(ap, fmt);
+ vsyslog (LOG_USER | LOG_INFO, fmt, ap);
+ va_end(ap);
+ return 0;
+}
+
+static int
+selinux_check_root (void)
+{
+ int status = -1;
+ char *user_context_raw;
+ union selinux_callback old_callback;
+
+ if (is_selinux_enabled() < 1)
+ return 0;
+
+ old_callback = selinux_get_callback(SELINUX_CB_LOG);
+ /* setup callbacks */
+ selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback) &log_callback);
+ if ((status = getprevcon_raw(&user_context_raw)) < 0) {
+ selinux_set_callback(SELINUX_CB_LOG, old_callback);
+ return status;
+ }
+
+ status = selinux_check_access(user_context_raw, user_context_raw, "passwd", "rootok", NULL);
+
+ selinux_set_callback(SELINUX_CB_LOG, old_callback);
+ freecon(user_context_raw);
+ return status;
+}
+#endif
+
+static int
+check_for_root (pam_handle_t *pamh, int ctrl)
+{
+ int retval = PAM_AUTH_ERR;
+
+ if (getuid() == 0)
+#ifdef WITH_SELINUX
+ if (selinux_check_root() == 0 || security_getenforce() == 0)
+#endif
+ retval = PAM_SUCCESS;
+
+ if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_DEBUG, "root check %s",
+ (retval==PAM_SUCCESS) ? "succeeded" : "failed");
+ }
+
+ return retval;
+}
+
+/* --- management functions --- */
+
+int
+pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ int ctrl;
+
+ ctrl = _pam_parse(pamh, argc, argv);
+
+ return check_for_root (pamh, ctrl);
+}
+
+int
+pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
+
+int
+pam_sm_acct_mgmt (pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ int ctrl;
+
+ ctrl = _pam_parse(pamh, argc, argv);
+
+ return check_for_root (pamh, ctrl);
+}
+
+int
+pam_sm_chauthtok (pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ int ctrl;
+
+ ctrl = _pam_parse(pamh, argc, argv);
+
+ return check_for_root (pamh, ctrl);
+}
+
+/* end of module definition */
diff --git a/modules/pam_rootok/tst-pam_rootok b/modules/pam_rootok/tst-pam_rootok
new file mode 100755
index 0000000..385ef76
--- /dev/null
+++ b/modules/pam_rootok/tst-pam_rootok
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_rootok.so
diff --git a/modules/pam_rootok/tst-pam_rootok-retval.c b/modules/pam_rootok/tst-pam_rootok-retval.c
new file mode 100644
index 0000000..b179701
--- /dev/null
+++ b/modules/pam_rootok/tst-pam_rootok-retval.c
@@ -0,0 +1,72 @@
+/*
+ * Check pam_rootok return values.
+ *
+ * Copyright (c) 2020 Dmitry V. Levin <ldv@altlinux.org>
+ */
+
+#include "test_assert.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <security/pam_appl.h>
+
+#define MODULE_NAME "pam_rootok"
+#define TEST_NAME "tst-" MODULE_NAME "-retval"
+
+static const char service_file[] = TEST_NAME ".service";
+static const char user_name[] = "";
+static struct pam_conv conv;
+
+int
+main(void)
+{
+ pam_handle_t *pamh = NULL;
+ FILE *fp;
+ char cwd[PATH_MAX];
+
+ ASSERT_NE(NULL, getcwd(cwd, sizeof(cwd)));
+
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so\n"
+ "account required %s/.libs/%s.so\n"
+ "password required %s/.libs/%s.so\n"
+ "session required %s/.libs/%s.so\n",
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, user_name, &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_SUCCESS, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, user_name, &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ if (getuid() == 0) {
+ ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_chauthtok(pamh, 0));
+ } else {
+ ASSERT_EQ(PAM_AUTH_ERR, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_AUTH_ERR, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_AUTH_ERR, pam_chauthtok(pamh, 0));
+ }
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ ASSERT_EQ(0, unlink(service_file));
+
+ return 0;
+}
diff --git a/modules/pam_securetty/Makefile.am b/modules/pam_securetty/Makefile.am
new file mode 100644
index 0000000..8ea02d8
--- /dev/null
+++ b/modules/pam_securetty/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_securetty.8
+endif
+XMLS = README.xml pam_securetty.8.xml
+dist_check_SCRIPTS = tst-pam_securetty
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_securetty.la
+pam_securetty_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_securetty/Makefile.in b/modules/pam_securetty/Makefile.in
new file mode 100644
index 0000000..0763989
--- /dev/null
+++ b/modules/pam_securetty/Makefile.in
@@ -0,0 +1,1150 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_securetty
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_securetty_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_securetty_la_SOURCES = pam_securetty.c
+pam_securetty_la_OBJECTS = pam_securetty.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_securetty.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_securetty.c
+DIST_SOURCES = pam_securetty.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_securetty.8
+XMLS = README.xml pam_securetty.8.xml
+dist_check_SCRIPTS = tst-pam_securetty
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_securetty.la
+pam_securetty_la_LIBADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_securetty/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_securetty/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_securetty.la: $(pam_securetty_la_OBJECTS) $(pam_securetty_la_DEPENDENCIES) $(EXTRA_pam_securetty_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_securetty_la_OBJECTS) $(pam_securetty_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_securetty.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_securetty.log: tst-pam_securetty
+ @p='tst-pam_securetty'; \
+ b='tst-pam_securetty'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_securetty.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_securetty.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_securetty/README b/modules/pam_securetty/README
new file mode 100644
index 0000000..21764e4
--- /dev/null
+++ b/modules/pam_securetty/README
@@ -0,0 +1,42 @@
+pam_securetty — Limit root login to special devices
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+pam_securetty is a PAM module that allows root logins only if the user is
+logging in on a "secure" tty, as defined by the listing in the securetty file.
+pam_securetty checks at first, if /etc/securetty exists. If not and it was
+built with vendordir support, it will use <vendordir>/securetty. pam_securetty
+also checks that the securetty files are plain files and not world writable. It
+will also allow root logins on the tty specified with console= switch on the
+kernel command line and on ttys from the /sys/class/tty/console/active.
+
+This module has no effect on non-root users and requires that the application
+fills in the PAM_TTY item correctly.
+
+For canonical usage, should be listed as a required authentication method
+before any sufficient authentication methods.
+
+OPTIONS
+
+debug
+
+ Print debug information.
+
+noconsole
+
+ Do not automatically allow root logins on the kernel console device, as
+ specified on the kernel command line or by the sys file, if it is not also
+ specified in the securetty file.
+
+EXAMPLES
+
+auth required pam_securetty.so
+auth required pam_unix.so
+
+
+AUTHOR
+
+pam_securetty was written by Elliot Lee <sopwith@cuc.edu>.
+
diff --git a/modules/pam_securetty/README.xml b/modules/pam_securetty/README.xml
new file mode 100644
index 0000000..a8c098a
--- /dev/null
+++ b/modules/pam_securetty/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_securetty.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_securetty.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_securetty-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_securetty.8.xml" xpointer='xpointer(//refsect1[@id = "pam_securetty-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_securetty.8.xml" xpointer='xpointer(//refsect1[@id = "pam_securetty-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_securetty.8.xml" xpointer='xpointer(//refsect1[@id = "pam_securetty-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_securetty.8.xml" xpointer='xpointer(//refsect1[@id = "pam_securetty-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_securetty/pam_securetty.8 b/modules/pam_securetty/pam_securetty.8
new file mode 100644
index 0000000..a808aea
--- /dev/null
+++ b/modules/pam_securetty/pam_securetty.8
@@ -0,0 +1,140 @@
+'\" t
+.\" Title: pam_securetty
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_SECURETTY" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_securetty \- Limit root login to special devices
+.SH "SYNOPSIS"
+.HP \w'\fBpam_securetty\&.so\fR\ 'u
+\fBpam_securetty\&.so\fR [debug]
+.SH "DESCRIPTION"
+.PP
+pam_securetty is a PAM module that allows root logins only if the user is logging in on a "secure" tty, as defined by the listing in the
+securetty
+file\&. pam_securetty checks at first, if
+/etc/securetty
+exists\&. If not and it was built with vendordir support, it will use
+<vendordir>/securetty\&. pam_securetty also checks that the
+securetty
+files are plain files and not world writable\&. It will also allow root logins on the tty specified with
+\fBconsole=\fR
+switch on the kernel command line and on ttys from the
+/sys/class/tty/console/active\&.
+.PP
+This module has no effect on non\-root users and requires that the application fills in the
+\fBPAM_TTY\fR
+item correctly\&.
+.PP
+For canonical usage, should be listed as a
+\fBrequired\fR
+authentication method before any
+\fBsufficient\fR
+authentication methods\&.
+.SH "OPTIONS"
+.PP
+\fBdebug\fR
+.RS 4
+Print debug information\&.
+.RE
+.PP
+\fBnoconsole\fR
+.RS 4
+Do not automatically allow root logins on the kernel console device, as specified on the kernel command line or by the sys file, if it is not also specified in the
+securetty
+file\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+Only the
+\fBauth\fR
+module type is provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_SUCCESS
+.RS 4
+The user is allowed to continue authentication\&. Either the user is not root, or the root user is trying to log in on an acceptable device\&.
+.RE
+.PP
+PAM_AUTH_ERR
+.RS 4
+Authentication is rejected\&. Either root is attempting to log in via an unacceptable device, or the
+securetty
+file is world writable or not a normal file\&.
+.RE
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_CONV_ERR
+.RS 4
+The conversation method supplied by the application failed to obtain the username\&.
+.RE
+.PP
+PAM_INCOMPLETE
+.RS 4
+The conversation method supplied by the application returned PAM_CONV_AGAIN\&.
+.RE
+.PP
+PAM_SERVICE_ERR
+.RS 4
+An error occurred while the module was determining the user\*(Aqs name or tty, or the module could not open the
+securetty
+file\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+The module could not find the user name in the
+/etc/passwd
+file to verify whether the user had a UID of 0\&. Therefore, the results of running this module are ignored\&.
+.RE
+.SH "EXAMPLES"
+.PP
+.if n \{\
+.RS 4
+.\}
+.nf
+auth required pam_securetty\&.so
+auth required pam_unix\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.PP
+\fBsecuretty\fR(5),
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_securetty was written by Elliot Lee <sopwith@cuc\&.edu>\&.
diff --git a/modules/pam_securetty/pam_securetty.8.xml b/modules/pam_securetty/pam_securetty.8.xml
new file mode 100644
index 0000000..e49d572
--- /dev/null
+++ b/modules/pam_securetty/pam_securetty.8.xml
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_securetty">
+
+ <refmeta>
+ <refentrytitle>pam_securetty</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_securetty-name">
+ <refname>pam_securetty</refname>
+ <refpurpose>Limit root login to special devices</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_securetty-cmdsynopsis">
+ <command>pam_securetty.so</command>
+ <arg choice="opt">
+ debug
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_securetty-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ pam_securetty is a PAM module that allows root logins only if the
+ user is logging in on a "secure" tty, as defined by the listing
+ in the <filename>securetty</filename> file. pam_securetty checks at
+ first, if <filename>/etc/securetty</filename> exists. If not and
+ it was built with vendordir support, it will use
+ <filename>%vendordir%/securetty</filename>. pam_securetty also
+ checks that the <filename>securetty</filename> files are plain
+ files and not world writable. It will also allow root logins on
+ the tty specified with <option>console=</option> switch on the
+ kernel command line and on ttys from the
+ <filename>/sys/class/tty/console/active</filename>.
+ </para>
+ <para>
+ This module has no effect on non-root users and requires that the
+ application fills in the <emphasis remap='B'>PAM_TTY</emphasis>
+ item correctly.
+ </para>
+ <para>
+ For canonical usage, should be listed as a
+ <emphasis remap='B'>required</emphasis> authentication method
+ before any <emphasis remap='B'>sufficient</emphasis>
+ authentication methods.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_securetty-options">
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Print debug information.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>noconsole</option>
+ </term>
+ <listitem>
+ <para>
+ Do not automatically allow root logins on the kernel console
+ device, as specified on the kernel command line or by the sys file,
+ if it is not also specified in the
+ <filename>securetty</filename> file.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_securetty-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ Only the <option>auth</option> module type is provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_securetty-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ The user is allowed to continue authentication.
+ Either the user is not root, or the root user is
+ trying to log in on an acceptable device.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_AUTH_ERR</term>
+ <listitem>
+ <para>
+ Authentication is rejected. Either root is attempting to
+ log in via an unacceptable device, or the
+ <filename>securetty</filename> file is world writable or
+ not a normal file.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory buffer error.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_CONV_ERR</term>
+ <listitem>
+ <para>
+ The conversation method supplied by the application
+ failed to obtain the username.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_INCOMPLETE</term>
+ <listitem>
+ <para>
+ The conversation method supplied by the application
+ returned PAM_CONV_AGAIN.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ An error occurred while the module was determining the
+ user's name or tty, or the module could not open
+ the <filename>securetty</filename> file.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ The module could not find the user name in the
+ <filename>/etc/passwd</filename> file to verify whether
+ the user had a UID of 0. Therefore, the results of running
+ this module are ignored.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_securetty-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ <programlisting>
+auth required pam_securetty.so
+auth required pam_unix.so
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_securetty-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>securetty</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_securetty-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_securetty was written by Elliot Lee &lt;sopwith@cuc.edu&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_securetty/pam_securetty.c b/modules/pam_securetty/pam_securetty.c
new file mode 100644
index 0000000..47a5cd9
--- /dev/null
+++ b/modules/pam_securetty/pam_securetty.c
@@ -0,0 +1,286 @@
+/*
+ * pam_securetty module
+ *
+ * by Elliot Lee <sopwith@redhat.com>, Red Hat Software.
+ * July 25, 1996.
+ * This code shamelessly ripped from the pam_rootok module.
+ * Slight modifications AGM. 1996/12/3
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <pwd.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+#include <errno.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+#include "pam_inline.h"
+
+#define PAM_DEBUG_ARG 0x0001
+#define PAM_NOCONSOLE_ARG 0x0002
+
+#define SECURETTY_FILE "/etc/securetty"
+#ifdef VENDORDIR
+#define SECURETTY2_FILE VENDORDIR"/securetty"
+#endif
+#define TTY_PREFIX "/dev/"
+#define CMDLINE_FILE "/proc/cmdline"
+#define CONSOLEACTIVE_FILE "/sys/class/tty/console/active"
+
+static int
+_pam_parse (const pam_handle_t *pamh, int argc, const char **argv)
+{
+ int ctrl=0;
+
+ /* step through arguments */
+ for (ctrl=0; argc-- > 0; ++argv) {
+
+ /* generic options */
+
+ if (!strcmp(*argv,"debug"))
+ ctrl |= PAM_DEBUG_ARG;
+ else if (!strcmp(*argv, "noconsole"))
+ ctrl |= PAM_NOCONSOLE_ARG;
+ else {
+ pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
+ }
+ }
+
+ return ctrl;
+}
+
+static int
+securetty_perform_check (pam_handle_t *pamh, int ctrl,
+ const char *function_name)
+{
+ int retval = PAM_AUTH_ERR;
+ const char *securettyfile;
+ const char *username;
+ const char *uttyname;
+ const char *str;
+ const void *void_uttyname;
+ char ttyfileline[256];
+ char ptname[256];
+ struct stat ttyfileinfo;
+ struct passwd *user_pwd;
+ FILE *ttyfile;
+
+ /* log a trail for debugging */
+ if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_DEBUG, "pam_securetty called via %s function",
+ function_name);
+ }
+
+ retval = pam_get_user(pamh, &username, NULL);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE, "cannot determine user name: %s",
+ pam_strerror(pamh, retval));
+ return (retval == PAM_CONV_AGAIN ? PAM_INCOMPLETE : retval);
+ }
+
+ user_pwd = pam_modutil_getpwnam(pamh, username);
+ if (user_pwd != NULL && user_pwd->pw_uid != 0) {
+ /* If the user is not root, securetty's does not apply to them */
+ return PAM_SUCCESS;
+ }
+ /* The user is now either root or an invalid / mistyped username */
+
+ retval = pam_get_item(pamh, PAM_TTY, &void_uttyname);
+ uttyname = void_uttyname;
+ if (retval != PAM_SUCCESS || uttyname == NULL) {
+ pam_syslog (pamh, LOG_ERR, "cannot determine user's tty");
+ return PAM_SERVICE_ERR;
+ }
+
+ /* The PAM_TTY item may be prefixed with "/dev/" - skip that */
+ if ((str = pam_str_skip_prefix(uttyname, TTY_PREFIX)) != NULL)
+ uttyname = str;
+
+ if (stat(SECURETTY_FILE, &ttyfileinfo)) {
+#ifdef VENDORDIR
+ if (errno == ENOENT) {
+ if (stat(SECURETTY2_FILE, &ttyfileinfo)) {
+ if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh, LOG_DEBUG,
+ "Couldn't open %s: %m", SECURETTY2_FILE);
+ return PAM_SUCCESS; /* for compatibility with old securetty handling,
+ this needs to succeed. But we still log the
+ error. */
+ }
+ securettyfile = SECURETTY2_FILE;
+ } else {
+#endif
+ if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh, LOG_DEBUG, "Couldn't open %s: %m", SECURETTY_FILE);
+ return PAM_SUCCESS; /* for compatibility with old securetty handling,
+ this needs to succeed. But we still log the
+ error. */
+#ifdef VENDORDIR
+ }
+#endif
+ } else {
+ securettyfile = SECURETTY_FILE;
+ }
+
+ if ((ttyfileinfo.st_mode & S_IWOTH) || !S_ISREG(ttyfileinfo.st_mode)) {
+ /* If the file is world writable or is not a
+ normal file, return error */
+ pam_syslog(pamh, LOG_ERR,
+ "%s is either world writable or not a normal file",
+ securettyfile);
+ return PAM_AUTH_ERR;
+ }
+
+ ttyfile = fopen(securettyfile,"r");
+ if (ttyfile == NULL) { /* Check that we opened it successfully */
+ pam_syslog(pamh, LOG_ERR, "Error opening %s: %m", securettyfile);
+ return PAM_SERVICE_ERR;
+ }
+
+ if (isdigit(uttyname[0])) {
+ snprintf(ptname, sizeof(ptname), "pts/%s", uttyname);
+ } else {
+ ptname[0] = '\0';
+ }
+
+ retval = 1;
+
+ while ((fgets(ttyfileline, sizeof(ttyfileline)-1, ttyfile) != NULL)
+ && retval) {
+ if (ttyfileline[strlen(ttyfileline) - 1] == '\n')
+ ttyfileline[strlen(ttyfileline) - 1] = '\0';
+
+ retval = ( strcmp(ttyfileline, uttyname)
+ && (!ptname[0] || strcmp(ptname, uttyname)) );
+ }
+ fclose(ttyfile);
+
+ if (retval && !(ctrl & PAM_NOCONSOLE_ARG)) {
+ FILE *cmdlinefile;
+
+ /* Allow access from the kernel console, if enabled */
+ cmdlinefile = fopen(CMDLINE_FILE, "r");
+
+ if (cmdlinefile != NULL) {
+ char line[LINE_MAX], *p;
+
+ p = fgets(line, sizeof(line), cmdlinefile);
+ fclose(cmdlinefile);
+
+ for (; p; p = strstr(p+1, "console=")) {
+ const char *e;
+
+ /* Test whether this is a beginning of a word? */
+ if (p > line && p[-1] != ' ')
+ continue;
+
+ /* Is this our console? */
+ if ((e = pam_str_skip_prefix_len(p + 8, uttyname, strlen(uttyname))) == NULL)
+ continue;
+
+ /* Is there any garbage after the TTY name? */
+ if (*e == ',' || *e == ' ' || *e == '\n' || *e == 0) {
+ retval = 0;
+ break;
+ }
+ }
+ }
+ }
+ if (retval && !(ctrl & PAM_NOCONSOLE_ARG)) {
+ FILE *consoleactivefile;
+
+ /* Allow access from the active console */
+ consoleactivefile = fopen(CONSOLEACTIVE_FILE, "r");
+
+ if (consoleactivefile != NULL) {
+ char line[LINE_MAX], *p, *n;
+
+ line[0] = 0;
+ p = fgets(line, sizeof(line), consoleactivefile);
+ fclose(consoleactivefile);
+
+ if (p) {
+ /* remove the newline character at end */
+ if (line[strlen(line)-1] == '\n')
+ line[strlen(line)-1] = 0;
+
+ for (n = p; n != NULL; p = n+1) {
+ if ((n = strchr(p, ' ')) != NULL)
+ *n = '\0';
+
+ if (strcmp(p, uttyname) == 0) {
+ retval = 0;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (retval) {
+ pam_syslog(pamh, LOG_NOTICE, "access denied: tty '%s' is not secure !",
+ uttyname);
+
+ retval = PAM_AUTH_ERR;
+ if (user_pwd == NULL) {
+ retval = PAM_USER_UNKNOWN;
+ }
+ } else {
+ if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_DEBUG, "access allowed for '%s' on '%s'",
+ username, uttyname);
+ }
+ retval = PAM_SUCCESS;
+
+ }
+
+ return retval;
+}
+
+/* --- authentication management functions --- */
+
+int pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, int argc,
+ const char **argv)
+{
+ int ctrl;
+
+ /* parse the arguments */
+ ctrl = _pam_parse (pamh, argc, argv);
+
+ return securetty_perform_check(pamh, ctrl, __FUNCTION__);
+}
+
+int
+pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
+
+/* --- account management functions --- */
+
+int
+pam_sm_acct_mgmt (pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ int ctrl;
+
+ /* parse the arguments */
+ ctrl = _pam_parse (pamh, argc, argv);
+
+ /* take the easy route */
+ return securetty_perform_check(pamh, ctrl, __FUNCTION__);
+}
+
+/* end of module definition */
diff --git a/modules/pam_securetty/tst-pam_securetty b/modules/pam_securetty/tst-pam_securetty
new file mode 100755
index 0000000..1252f79
--- /dev/null
+++ b/modules/pam_securetty/tst-pam_securetty
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_securetty.so
diff --git a/modules/pam_selinux/Makefile.am b/modules/pam_selinux/Makefile.am
new file mode 100644
index 0000000..9476ab3
--- /dev/null
+++ b/modules/pam_selinux/Makefile.am
@@ -0,0 +1,37 @@
+#
+# Copyright (c) 2005, 2006, 2007 Thorsten Kukuk <kukuk@thkukuk.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS) pam_selinux_check.8
+
+if HAVE_DOC
+dist_man_MANS = pam_selinux.8
+endif
+XMLS = README.xml pam_selinux.8.xml
+dist_check_SCRIPTS = tst-pam_selinux
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -I$(top_srcdir)/libpam_misc/include $(WARN_CFLAGS)
+
+pam_selinux_la_LDFLAGS = -no-undefined -avoid-version -module
+pam_selinux_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBSELINUX@ @LIBAUDIT@
+if HAVE_VERSIONING
+ pam_selinux_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_selinux.la
+noinst_PROGRAMS = pam_selinux_check
+pam_selinux_check_LDADD = $(top_builddir)/libpam/libpam.la \
+ $(top_builddir)/libpam_misc/libpam_misc.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_selinux/Makefile.in b/modules/pam_selinux/Makefile.in
new file mode 100644
index 0000000..c58ce8e
--- /dev/null
+++ b/modules/pam_selinux/Makefile.in
@@ -0,0 +1,1182 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2007 Thorsten Kukuk <kukuk@thkukuk.de>
+#
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+noinst_PROGRAMS = pam_selinux_check$(EXEEXT)
+subdir = modules/pam_selinux
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+PROGRAMS = $(noinst_PROGRAMS)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_selinux_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_selinux_la_SOURCES = pam_selinux.c
+pam_selinux_la_OBJECTS = pam_selinux.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+pam_selinux_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(pam_selinux_la_LDFLAGS) $(LDFLAGS) -o \
+ $@
+pam_selinux_check_SOURCES = pam_selinux_check.c
+pam_selinux_check_OBJECTS = pam_selinux_check.$(OBJEXT)
+pam_selinux_check_DEPENDENCIES = $(top_builddir)/libpam/libpam.la \
+ $(top_builddir)/libpam_misc/libpam_misc.la
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_selinux.Plo \
+ ./$(DEPDIR)/pam_selinux_check.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_selinux.c pam_selinux_check.c
+DIST_SOURCES = pam_selinux.c pam_selinux_check.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS) pam_selinux_check.8
+@HAVE_DOC_TRUE@dist_man_MANS = pam_selinux.8
+XMLS = README.xml pam_selinux.8.xml
+dist_check_SCRIPTS = tst-pam_selinux
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -I$(top_srcdir)/libpam_misc/include $(WARN_CFLAGS)
+
+pam_selinux_la_LDFLAGS = -no-undefined -avoid-version -module \
+ $(am__append_1)
+pam_selinux_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBSELINUX@ @LIBAUDIT@
+securelib_LTLIBRARIES = pam_selinux.la
+pam_selinux_check_LDADD = $(top_builddir)/libpam/libpam.la \
+ $(top_builddir)/libpam_misc/libpam_misc.la
+
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_selinux/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_selinux/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_selinux.la: $(pam_selinux_la_OBJECTS) $(pam_selinux_la_DEPENDENCIES) $(EXTRA_pam_selinux_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(pam_selinux_la_LINK) -rpath $(securelibdir) $(pam_selinux_la_OBJECTS) $(pam_selinux_la_LIBADD) $(LIBS)
+
+pam_selinux_check$(EXEEXT): $(pam_selinux_check_OBJECTS) $(pam_selinux_check_DEPENDENCIES) $(EXTRA_pam_selinux_check_DEPENDENCIES)
+ @rm -f pam_selinux_check$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(pam_selinux_check_OBJECTS) $(pam_selinux_check_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_selinux.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_selinux_check.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_selinux.log: tst-pam_selinux
+ @p='tst-pam_selinux'; \
+ b='tst-pam_selinux'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+ clean-securelibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_selinux.Plo
+ -rm -f ./$(DEPDIR)/pam_selinux_check.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_selinux.Plo
+ -rm -f ./$(DEPDIR)/pam_selinux_check.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-noinstPROGRAMS clean-securelibLTLIBRARIES cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_selinux/README b/modules/pam_selinux/README
new file mode 100644
index 0000000..fb4d449
--- /dev/null
+++ b/modules/pam_selinux/README
@@ -0,0 +1,85 @@
+pam_selinux — PAM module to set the default security context
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+pam_selinux is a PAM module that sets up the default SELinux security context
+for the next executed process.
+
+When a new session is started, the open_session part of the module computes and
+sets up the execution security context used for the next execve(2) call, the
+file security context for the controlling terminal, and the security context
+used for creating a new kernel keyring.
+
+When the session is ended, the close_session part of the module restores old
+security contexts that were in effect before the change made by the
+open_session part of the module.
+
+Adding pam_selinux into the PAM stack might disrupt behavior of other PAM
+modules which execute applications. To avoid that, pam_selinux.so open should
+be placed after such modules in the PAM stack, and pam_selinux.so close should
+be placed before them. When such a placement is not feasible, pam_selinux.so
+restore could be used to temporary restore original security contexts.
+
+OPTIONS
+
+open
+
+ Only execute the open_session part of the module.
+
+close
+
+ Only execute the close_session part of the module.
+
+restore
+
+ In open_session part of the module, temporarily restore the security
+ contexts as they were before the previous call of the module. Another call
+ of this module without the restore option will set up the new security
+ contexts again.
+
+nottys
+
+ Do not setup security context of the controlling terminal.
+
+debug
+
+ Turn on debug messages via syslog(3).
+
+verbose
+
+ Attempt to inform the user when security context is set.
+
+select_context
+
+ Attempt to ask the user for a custom security context role. If MLS is on,
+ ask also for sensitivity level.
+
+env_params
+
+ Attempt to obtain a custom security context role from PAM environment. If
+ MLS is on, obtain also sensitivity level. This option and the
+ select_context option are mutually exclusive. The respective PAM
+ environment variables are SELINUX_ROLE_REQUESTED, SELINUX_LEVEL_REQUESTED,
+ and SELINUX_USE_CURRENT_RANGE. The first two variables are self describing
+ and the last one if set to 1 makes the PAM module behave as if the
+ use_current_range was specified on the command line of the module.
+
+use_current_range
+
+ Use the sensitivity level of the current process for the user context
+ instead of the default level. Also suppresses asking of the sensitivity
+ level from the user or obtaining it from PAM environment.
+
+EXAMPLES
+
+auth required pam_unix.so
+session required pam_permit.so
+session optional pam_selinux.so
+
+
+AUTHOR
+
+pam_selinux was written by Dan Walsh <dwalsh@redhat.com>.
+
diff --git a/modules/pam_selinux/README.xml b/modules/pam_selinux/README.xml
new file mode 100644
index 0000000..7e1baf5
--- /dev/null
+++ b/modules/pam_selinux/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_selinux.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_selinux.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_selinux-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_selinux.8.xml" xpointer='xpointer(//refsect1[@id = "pam_selinux-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_selinux.8.xml" xpointer='xpointer(//refsect1[@id = "pam_selinux-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_selinux.8.xml" xpointer='xpointer(//refsect1[@id = "pam_selinux-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_selinux.8.xml" xpointer='xpointer(//refsect1[@id = "pam_selinux-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_selinux/pam_selinux.8 b/modules/pam_selinux/pam_selinux.8
new file mode 100644
index 0000000..22a3d0a
--- /dev/null
+++ b/modules/pam_selinux/pam_selinux.8
@@ -0,0 +1,151 @@
+'\" t
+.\" Title: pam_selinux
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_SELINUX" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_selinux \- PAM module to set the default security context
+.SH "SYNOPSIS"
+.HP \w'\fBpam_selinux\&.so\fR\ 'u
+\fBpam_selinux\&.so\fR [open] [close] [restore] [nottys] [debug] [verbose] [select_context] [env_params] [use_current_range]
+.SH "DESCRIPTION"
+.PP
+pam_selinux is a PAM module that sets up the default SELinux security context for the next executed process\&.
+.PP
+When a new session is started, the open_session part of the module computes and sets up the execution security context used for the next
+\fBexecve\fR(2)
+call, the file security context for the controlling terminal, and the security context used for creating a new kernel keyring\&.
+.PP
+When the session is ended, the close_session part of the module restores old security contexts that were in effect before the change made by the open_session part of the module\&.
+.PP
+Adding pam_selinux into the PAM stack might disrupt behavior of other PAM modules which execute applications\&. To avoid that,
+\fIpam_selinux\&.so open\fR
+should be placed after such modules in the PAM stack, and
+\fIpam_selinux\&.so close\fR
+should be placed before them\&. When such a placement is not feasible,
+\fIpam_selinux\&.so restore\fR
+could be used to temporary restore original security contexts\&.
+.SH "OPTIONS"
+.PP
+\fBopen\fR
+.RS 4
+Only execute the open_session part of the module\&.
+.RE
+.PP
+\fBclose\fR
+.RS 4
+Only execute the close_session part of the module\&.
+.RE
+.PP
+\fBrestore\fR
+.RS 4
+In open_session part of the module, temporarily restore the security contexts as they were before the previous call of the module\&. Another call of this module without the restore option will set up the new security contexts again\&.
+.RE
+.PP
+\fBnottys\fR
+.RS 4
+Do not setup security context of the controlling terminal\&.
+.RE
+.PP
+\fBdebug\fR
+.RS 4
+Turn on debug messages via
+\fBsyslog\fR(3)\&.
+.RE
+.PP
+\fBverbose\fR
+.RS 4
+Attempt to inform the user when security context is set\&.
+.RE
+.PP
+\fBselect_context\fR
+.RS 4
+Attempt to ask the user for a custom security context role\&. If MLS is on, ask also for sensitivity level\&.
+.RE
+.PP
+\fBenv_params\fR
+.RS 4
+Attempt to obtain a custom security context role from PAM environment\&. If MLS is on, obtain also sensitivity level\&. This option and the select_context option are mutually exclusive\&. The respective PAM environment variables are
+\fISELINUX_ROLE_REQUESTED\fR,
+\fISELINUX_LEVEL_REQUESTED\fR, and
+\fISELINUX_USE_CURRENT_RANGE\fR\&. The first two variables are self describing and the last one if set to 1 makes the PAM module behave as if the use_current_range was specified on the command line of the module\&.
+.RE
+.PP
+\fBuse_current_range\fR
+.RS 4
+Use the sensitivity level of the current process for the user context instead of the default level\&. Also suppresses asking of the sensitivity level from the user or obtaining it from PAM environment\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+Only the
+\fBsession\fR
+module type is provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_SUCCESS
+.RS 4
+The security context was set successfully\&.
+.RE
+.PP
+PAM_SESSION_ERR
+.RS 4
+Unable to get or set a valid context\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+The user is not known to the system\&.
+.RE
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory allocation error\&.
+.RE
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+auth required pam_unix\&.so
+session required pam_permit\&.so
+session optional pam_selinux\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+.PP
+\fBexecve\fR(2),
+\fBtty\fR(4),
+\fBpam.d\fR(5),
+\fBpam\fR(8),
+\fBselinux\fR(8)
+.SH "AUTHOR"
+.PP
+pam_selinux was written by Dan Walsh <dwalsh@redhat\&.com>\&.
diff --git a/modules/pam_selinux/pam_selinux.8.xml b/modules/pam_selinux/pam_selinux.8.xml
new file mode 100644
index 0000000..28d465f
--- /dev/null
+++ b/modules/pam_selinux/pam_selinux.8.xml
@@ -0,0 +1,276 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_selinux">
+
+ <refmeta>
+ <refentrytitle>pam_selinux</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_selinux-name">
+ <refname>pam_selinux</refname>
+ <refpurpose>PAM module to set the default security context</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_selinux-cmdsynopsis">
+ <command>pam_selinux.so</command>
+ <arg choice="opt">
+ open
+ </arg>
+ <arg choice="opt">
+ close
+ </arg>
+ <arg choice="opt">
+ restore
+ </arg>
+ <arg choice="opt">
+ nottys
+ </arg>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ verbose
+ </arg>
+ <arg choice="opt">
+ select_context
+ </arg>
+ <arg choice="opt">
+ env_params
+ </arg>
+ <arg choice="opt">
+ use_current_range
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_selinux-description">
+ <title>DESCRIPTION</title>
+ <para>
+ pam_selinux is a PAM module that sets up the default SELinux security
+ context for the next executed process.
+ </para>
+ <para>
+ When a new session is started, the open_session part of the module
+ computes and sets up the execution security context used for the next
+ <citerefentry>
+ <refentrytitle>execve</refentrytitle><manvolnum>2</manvolnum>
+ </citerefentry>
+ call, the file security context for the controlling terminal, and
+ the security context used for creating a new kernel keyring.
+ </para>
+ <para>
+ When the session is ended, the close_session part of the module restores
+ old security contexts that were in effect before the change made
+ by the open_session part of the module.
+ </para>
+ <para>
+ Adding pam_selinux into the PAM stack might disrupt behavior of other
+ PAM modules which execute applications. To avoid that,
+ <emphasis>pam_selinux.so open</emphasis> should be placed after such
+ modules in the PAM stack, and <emphasis>pam_selinux.so close</emphasis>
+ should be placed before them. When such a placement is not feasible,
+ <emphasis>pam_selinux.so restore</emphasis> could be used to temporary
+ restore original security contexts.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_selinux-options">
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>open</option>
+ </term>
+ <listitem>
+ <para>
+ Only execute the open_session part of the module.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>close</option>
+ </term>
+ <listitem>
+ <para>
+ Only execute the close_session part of the module.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>restore</option>
+ </term>
+ <listitem>
+ <para>
+ In open_session part of the module, temporarily restore the
+ security contexts as they were before the previous call of
+ the module. Another call of this module without the restore
+ option will set up the new security contexts again.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>nottys</option>
+ </term>
+ <listitem>
+ <para>
+ Do not setup security context of the controlling terminal.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Turn on debug messages via
+ <citerefentry>
+ <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>verbose</option>
+ </term>
+ <listitem>
+ <para>
+ Attempt to inform the user when security context is set.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>select_context</option>
+ </term>
+ <listitem>
+ <para>
+ Attempt to ask the user for a custom security context role.
+ If MLS is on, ask also for sensitivity level.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>env_params</option>
+ </term>
+ <listitem>
+ <para>
+ Attempt to obtain a custom security context role from PAM environment.
+ If MLS is on, obtain also sensitivity level. This option and the
+ select_context option are mutually exclusive. The respective PAM
+ environment variables are <emphasis>SELINUX_ROLE_REQUESTED</emphasis>,
+ <emphasis>SELINUX_LEVEL_REQUESTED</emphasis>, and
+ <emphasis>SELINUX_USE_CURRENT_RANGE</emphasis>. The first two variables
+ are self describing and the last one if set to 1 makes the PAM module behave as
+ if the use_current_range was specified on the command line of the module.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>use_current_range</option>
+ </term>
+ <listitem>
+ <para>
+ Use the sensitivity level of the current process for the user context
+ instead of the default level. Also suppresses asking of the
+ sensitivity level from the user or obtaining it from PAM environment.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_selinux-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ Only the <option>session</option> module type is provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_selinux-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ The security context was set successfully.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SESSION_ERR</term>
+ <listitem>
+ <para>
+ Unable to get or set a valid context.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ The user is not known to the system.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory allocation error.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_selinux-examples'>
+ <title>EXAMPLES</title>
+ <programlisting>
+auth required pam_unix.so
+session required pam_permit.so
+session optional pam_selinux.so
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id='pam_selinux-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>execve</refentrytitle><manvolnum>2</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>tty</refentrytitle><manvolnum>4</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>selinux</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_selinux-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_selinux was written by Dan Walsh &lt;dwalsh@redhat.com&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_selinux/pam_selinux.c b/modules/pam_selinux/pam_selinux.c
new file mode 100644
index 0000000..d8e10d8
--- /dev/null
+++ b/modules/pam_selinux/pam_selinux.c
@@ -0,0 +1,818 @@
+/******************************************************************************
+ * A module for Linux-PAM that will set the default security context after login
+ * via PAM.
+ *
+ * Copyright (c) 2003-2008 Red Hat, Inc.
+ * Written by Dan Walsh <dwalsh@redhat.com>
+ * Additional improvements by Tomas Mraz <tmraz@redhat.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <limits.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <syslog.h>
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+#include "pam_inline.h"
+
+#include <selinux/selinux.h>
+#include <selinux/get_context_list.h>
+#include <selinux/context.h>
+#include <selinux/get_default_type.h>
+
+#ifdef HAVE_LIBAUDIT
+#include <libaudit.h>
+#include <sys/select.h>
+#endif
+
+/* Send audit message */
+static void
+send_audit_message(const pam_handle_t *pamh, int success, const char *default_context,
+ const char *selected_context)
+{
+#ifdef HAVE_LIBAUDIT
+ char *msg = NULL;
+ int audit_fd = audit_open();
+ char *default_raw = NULL;
+ char *selected_raw = NULL;
+ const void *tty = NULL, *rhost = NULL;
+ if (audit_fd < 0) {
+ if (errno == EINVAL || errno == EPROTONOSUPPORT ||
+ errno == EAFNOSUPPORT) {
+ goto fallback; /* No audit support in kernel */
+ }
+ pam_syslog(pamh, LOG_ERR, "Error connecting to audit system: %m");
+ goto fallback;
+ }
+ (void)pam_get_item(pamh, PAM_TTY, &tty);
+ (void)pam_get_item(pamh, PAM_RHOST, &rhost);
+ if (selinux_trans_to_raw_context(default_context, &default_raw) < 0) {
+ pam_syslog(pamh, LOG_ERR, "Error translating default context '%s'.", default_context);
+ default_raw = NULL;
+ }
+ if (selinux_trans_to_raw_context(selected_context, &selected_raw) < 0) {
+ pam_syslog(pamh, LOG_ERR, "Error translating selected context '%s'.", selected_context);
+ selected_raw = NULL;
+ }
+ if (asprintf(&msg, "pam: default-context=%s selected-context=%s",
+ default_raw ? default_raw : (default_context ? default_context : "?"),
+ selected_raw ? selected_raw : (selected_context ? selected_context : "?")) < 0) {
+ msg = NULL; /* asprintf leaves msg in undefined state on failure */
+ pam_syslog(pamh, LOG_ERR, "Error allocating memory.");
+ goto fallback;
+ }
+ if (audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE,
+ msg, rhost, NULL, tty, success) <= 0) {
+ pam_syslog(pamh, LOG_ERR, "Error sending audit message: %m");
+ goto fallback;
+ }
+ goto cleanup;
+
+ fallback:
+#endif /* HAVE_LIBAUDIT */
+ pam_syslog(pamh, LOG_NOTICE, "pam: default-context=%s selected-context=%s success %d",
+ default_context, selected_context, success);
+
+#ifdef HAVE_LIBAUDIT
+ cleanup:
+ free(msg);
+ freecon(default_raw);
+ freecon(selected_raw);
+ if (audit_fd >= 0)
+ close(audit_fd);
+#endif /* HAVE_LIBAUDIT */
+}
+
+static int
+send_text (pam_handle_t *pamh, const char *text, int debug)
+{
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "%s", text);
+ return pam_info (pamh, "%s", text);
+}
+
+/*
+ * This function sends a message to the user and gets the response. The caller
+ * is responsible for freeing the responses.
+ */
+static int
+query_response (pam_handle_t *pamh, const char *text, const char *def,
+ char **response, int debug)
+{
+ int rc;
+ if (def)
+ rc = pam_prompt (pamh, PAM_PROMPT_ECHO_ON, response, "%s [%s] ", text, def);
+ else
+ rc = pam_prompt (pamh, PAM_PROMPT_ECHO_ON, response, "%s ", text);
+
+ if (*response == NULL) {
+ rc = PAM_CONV_ERR;
+ }
+
+ if (rc != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_WARNING, "No response to query: %s", text);
+ } else if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "%s %s", text, *response);
+ return rc;
+}
+
+static char *
+config_context (pam_handle_t *pamh, const char *defaultcon, int use_current_range, int debug)
+{
+ char *newcon = NULL;
+ context_t new_context;
+ int mls_enabled = is_selinux_mls_enabled();
+ char *response=NULL;
+ char *type=NULL;
+ char resp_val = 0;
+
+ pam_prompt (pamh, PAM_TEXT_INFO, NULL, _("The default security context is %s."), defaultcon);
+
+ while (1) {
+ if (query_response(pamh,
+ _("Would you like to enter a different role or level?"), "n",
+ &response, debug) == PAM_SUCCESS) {
+ resp_val = response[0];
+ _pam_drop(response);
+ } else {
+ resp_val = 'N';
+ }
+ if ((resp_val == 'y') || (resp_val == 'Y'))
+ {
+ if ((new_context = context_new(defaultcon)) == NULL)
+ goto fail_set;
+
+ /* Allow the user to enter role and level individually */
+ if (query_response(pamh, _("role:"), context_role_get(new_context),
+ &response, debug) == PAM_SUCCESS && response[0]) {
+ if (get_default_type(response, &type)) {
+ pam_prompt(pamh, PAM_ERROR_MSG, NULL,
+ _("There is no default type for role %s."), response);
+ _pam_drop(response);
+ continue;
+ } else {
+ if (context_role_set(new_context, response))
+ goto fail_set;
+ if (context_type_set (new_context, type))
+ goto fail_set;
+ _pam_drop(type);
+ }
+ }
+ _pam_drop(response);
+
+ if (mls_enabled)
+ {
+ if (use_current_range) {
+ char *mycon = NULL;
+ context_t my_context;
+
+ if (getcon(&mycon) != 0)
+ goto fail_set;
+ my_context = context_new(mycon);
+ if (my_context == NULL) {
+ freecon(mycon);
+ goto fail_set;
+ }
+ freecon(mycon);
+ if (context_range_set(new_context, context_range_get(my_context))) {
+ context_free(my_context);
+ goto fail_set;
+ }
+ context_free(my_context);
+ } else if (query_response(pamh, _("level:"), context_range_get(new_context),
+ &response, debug) == PAM_SUCCESS && response[0]) {
+ if (context_range_set(new_context, response))
+ goto fail_set;
+ }
+ _pam_drop(response);
+ }
+
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "Selected Security Context %s", context_str(new_context));
+
+ /* Get the string value of the context and see if it is valid. */
+ if (!security_check_context(context_str(new_context))) {
+ newcon = strdup(context_str(new_context));
+ if (newcon == NULL)
+ goto fail_set;
+ context_free(new_context);
+
+ /* we have to check that this user is allowed to go into the
+ range they have specified ... role is tied to an seuser, so that'll
+ be checked at setexeccon time */
+ if (mls_enabled &&
+ selinux_check_access(defaultcon, newcon, "context", "contains", NULL) != 0) {
+ pam_syslog(pamh, LOG_NOTICE, "Security context %s is not allowed for %s", defaultcon, newcon);
+
+ send_audit_message(pamh, 0, defaultcon, newcon);
+
+ free(newcon);
+ goto fail_range;
+ }
+ return newcon;
+ }
+ else {
+ send_audit_message(pamh, 0, defaultcon, context_str(new_context));
+ send_text(pamh,_("This is not a valid security context."),debug);
+ }
+ context_free(new_context); /* next time around allocates another */
+ }
+ else
+ return strdup(defaultcon);
+ } /* end while */
+
+ return NULL;
+
+ fail_set:
+ free(type);
+ _pam_drop(response);
+ context_free (new_context);
+ send_audit_message(pamh, 0, defaultcon, NULL);
+ fail_range:
+ return NULL;
+}
+
+static char *
+context_from_env (pam_handle_t *pamh, const char *defaultcon, int env_params, int use_current_range, int debug)
+{
+ char *newcon = NULL;
+ context_t new_context;
+ context_t my_context = NULL;
+ int mls_enabled = is_selinux_mls_enabled();
+ const char *env = NULL;
+ char *type = NULL;
+ int fail = 1;
+
+ if ((new_context = context_new(defaultcon)) == NULL)
+ goto fail_set;
+
+ if (env_params && (env = pam_getenv(pamh, "SELINUX_ROLE_REQUESTED")) != NULL && env[0] != '\0') {
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "Requested role: %s", env);
+
+ if (get_default_type(env, &type)) {
+ pam_syslog(pamh, LOG_NOTICE, "No default type for role %s", env);
+ goto fail_set;
+ } else {
+ if (context_role_set(new_context, env))
+ goto fail_set;
+ if (context_type_set(new_context, type))
+ goto fail_set;
+ }
+ }
+
+ if (mls_enabled) {
+ if ((env = pam_getenv(pamh, "SELINUX_USE_CURRENT_RANGE")) != NULL && env[0] == '1') {
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "SELINUX_USE_CURRENT_RANGE is set");
+ use_current_range = 1;
+ }
+
+ if (use_current_range) {
+ char *mycon = NULL;
+
+ if (getcon(&mycon) != 0)
+ goto fail_set;
+ my_context = context_new(mycon);
+ if (my_context == NULL) {
+ freecon(mycon);
+ goto fail_set;
+ }
+ freecon(mycon);
+ env = context_range_get(my_context);
+ } else {
+ env = pam_getenv(pamh, "SELINUX_LEVEL_REQUESTED");
+ }
+
+ if (env != NULL && env[0] != '\0') {
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "Requested level: %s", env);
+ if (context_range_set(new_context, env))
+ goto fail_set;
+ }
+ }
+
+ newcon = strdup(context_str(new_context));
+ if (newcon == NULL)
+ goto fail_set;
+
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "Selected Security Context %s", newcon);
+
+ /* Get the string value of the context and see if it is valid. */
+ if (security_check_context(newcon)) {
+ pam_syslog(pamh, LOG_NOTICE, "Not a valid security context %s", newcon);
+
+ goto fail_set;
+ }
+
+ /* we have to check that this user is allowed to go into the
+ range they have specified ... role is tied to an seuser, so that'll
+ be checked at setexeccon time */
+ if (mls_enabled &&
+ selinux_check_access(defaultcon, newcon, "context", "contains", NULL) != 0) {
+ pam_syslog(pamh, LOG_NOTICE, "Security context %s is not allowed for %s", defaultcon, newcon);
+
+ goto fail_set;
+ }
+
+ fail = 0;
+
+ fail_set:
+ free(type);
+ context_free(my_context);
+ context_free(new_context);
+ if (fail) {
+ send_audit_message(pamh, 0, defaultcon, newcon);
+ freecon(newcon);
+ newcon = NULL;
+ }
+ return newcon;
+}
+
+#define DATANAME "pam_selinux_context"
+typedef struct {
+ char *exec_context;
+ char *prev_exec_context;
+ char *default_user_context;
+ char *tty_context;
+ char *prev_tty_context;
+ char *tty_path;
+} module_data_t;
+
+static void
+free_module_data(module_data_t *data)
+{
+ free(data->tty_path);
+ freecon(data->prev_tty_context);
+ freecon(data->tty_context);
+ freecon(data->default_user_context);
+ freecon(data->prev_exec_context);
+ if (data->exec_context != data->default_user_context)
+ freecon(data->exec_context);
+ memset(data, 0, sizeof(*data));
+ free(data);
+}
+
+static void
+cleanup(pam_handle_t *pamh UNUSED, void *data, int err UNUSED)
+{
+ free_module_data(data);
+}
+
+static const module_data_t *
+get_module_data(const pam_handle_t *pamh)
+{
+ const void *data;
+
+ return (pam_get_data(pamh, DATANAME, &data) == PAM_SUCCESS) ? data : NULL;
+}
+
+static const char *
+get_item(const pam_handle_t *pamh, int item_type)
+{
+ const void *item;
+
+ return (pam_get_item(pamh, item_type, &item) == PAM_SUCCESS) ? item : NULL;
+}
+
+static int
+set_exec_context(const pam_handle_t *pamh, const char *context)
+{
+ if (setexeccon(context) == 0)
+ return 0;
+ pam_syslog(pamh, LOG_ERR, "Setting executable context \"%s\" failed: %m",
+ context ? context : "");
+ return -1;
+}
+
+static int
+set_file_context(const pam_handle_t *pamh, const char *context,
+ const char *file)
+{
+ if (!file)
+ return 0;
+ if (setfilecon(file, context) == 0 || errno == ENOENT)
+ return 0;
+ pam_syslog(pamh, LOG_ERR, "Setting file context \"%s\" failed for %s: %m",
+ context ? context : "", file);
+ return -1;
+}
+
+static int
+compute_exec_context(pam_handle_t *pamh, module_data_t *data,
+ int select_context, int use_current_range,
+ int env_params, int debug)
+{
+ const char *username;
+
+#ifdef HAVE_GETSEUSER
+ const char *service;
+#endif
+ char *seuser = NULL;
+ char *level = NULL;
+ char **contextlist = NULL;
+ int num_contexts = 0;
+ const struct passwd *pwd;
+
+ if (!(username = get_item(pamh, PAM_USER))) {
+ pam_syslog(pamh, LOG_ERR, "Cannot obtain the user name");
+ return PAM_USER_UNKNOWN;
+ }
+
+ if ((pwd = pam_modutil_getpwnam(pamh, username)) != NULL) {
+ username = pwd->pw_name;
+ } /* ignore error and keep using original username */
+
+ /* compute execute context */
+#ifdef HAVE_GETSEUSER
+ if (!(service = get_item(pamh, PAM_SERVICE))) {
+ pam_syslog(pamh, LOG_ERR, "Cannot obtain the service name");
+ return PAM_SESSION_ERR;
+ }
+ if (getseuser(username, service, &seuser, &level) == 0) {
+#else
+ if (getseuserbyname(username, &seuser, &level) == 0) {
+#endif
+ num_contexts = get_ordered_context_list_with_level(seuser, level, NULL,
+ &contextlist);
+ if (debug)
+ pam_syslog(pamh, LOG_DEBUG, "Username= %s SELinux User= %s Level= %s",
+ username, seuser, level);
+ free(level);
+ }
+ if (num_contexts > 0) {
+ free(seuser);
+ data->default_user_context = strdup(contextlist[0]);
+ freeconary(contextlist);
+ if (!data->default_user_context) {
+ pam_syslog(pamh, LOG_CRIT, "Out of memory");
+ return PAM_BUF_ERR;
+ }
+
+ data->exec_context = data->default_user_context;
+ if (select_context)
+ data->exec_context = config_context(pamh, data->default_user_context,
+ use_current_range, debug);
+ else if (env_params || use_current_range)
+ data->exec_context = context_from_env(pamh, data->default_user_context,
+ env_params, use_current_range,
+ debug);
+ }
+
+ if (!data->exec_context) {
+ pam_syslog(pamh, LOG_ERR, "Unable to get valid context for %s", username);
+ pam_prompt(pamh, PAM_ERROR_MSG, NULL,
+ _("A valid context for %s could not be obtained."), username);
+ }
+
+ if (getexeccon(&data->prev_exec_context) < 0)
+ data->prev_exec_context = NULL;
+
+ return PAM_SUCCESS;
+}
+
+static int
+compute_tty_context(const pam_handle_t *pamh, module_data_t *data)
+{
+ const char *tty = get_item(pamh, PAM_TTY);
+ security_class_t tclass;
+
+ if (!tty || !*tty || !strcmp(tty, "ssh")
+ || pam_str_skip_prefix(tty, "NODEV") != NULL) {
+ tty = ttyname(STDIN_FILENO);
+ if (!tty || !*tty)
+ tty = ttyname(STDOUT_FILENO);
+ if (!tty || !*tty)
+ tty = ttyname(STDERR_FILENO);
+ if (!tty || !*tty)
+ return PAM_SUCCESS;
+ }
+
+ if (pam_str_skip_prefix(tty, "/dev/") == NULL) {
+ if (asprintf(&data->tty_path, "%s%s", "/dev/", tty) < 0)
+ data->tty_path = NULL;
+ } else {
+ data->tty_path = strdup(tty);
+ }
+
+ if (!data->tty_path) {
+ pam_syslog(pamh, LOG_CRIT, "Out of memory");
+ return PAM_BUF_ERR;
+ }
+
+ if (getfilecon(data->tty_path, &data->prev_tty_context) < 0) {
+ data->prev_tty_context = NULL;
+ if (errno == ENOENT) {
+ free(data->tty_path);
+ data->tty_path = NULL;
+ return PAM_SUCCESS;
+ }
+ pam_syslog(pamh, LOG_ERR, "Failed to get current context for %s: %m",
+ data->tty_path);
+ return (security_getenforce() == 1) ? PAM_SESSION_ERR : PAM_SUCCESS;
+ }
+
+ tclass = string_to_security_class("chr_file");
+ if (tclass == 0) {
+ pam_syslog(pamh, LOG_ERR, "Failed to get chr_file security class");
+ freecon(data->prev_tty_context);
+ data->prev_tty_context = NULL;
+ free(data->tty_path);
+ data->tty_path = NULL;
+ return (security_getenforce() == 1) ? PAM_SESSION_ERR : PAM_SUCCESS;
+ }
+
+ if (security_compute_relabel(data->exec_context, data->prev_tty_context,
+ tclass, &data->tty_context)) {
+ data->tty_context = NULL;
+ pam_syslog(pamh, LOG_ERR, "Failed to compute new context for %s: %m",
+ data->tty_path);
+ freecon(data->prev_tty_context);
+ data->prev_tty_context = NULL;
+ free(data->tty_path);
+ data->tty_path = NULL;
+ return (security_getenforce() == 1) ? PAM_SESSION_ERR : PAM_SUCCESS;
+ }
+
+ return PAM_SUCCESS;
+}
+
+static int
+restore_context(const pam_handle_t *pamh, const module_data_t *data, int debug)
+{
+ int err;
+
+ if (!data) {
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "No context to restore");
+ return PAM_SUCCESS;
+ }
+
+ if (debug && data->tty_path)
+ pam_syslog(pamh, LOG_NOTICE,
+ "Restore file context of tty %s: [%s] -> [%s]",
+ data->tty_path,
+ data->tty_context ? data->tty_context : "",
+ data->prev_tty_context ? data->prev_tty_context : "");
+ err = set_file_context(pamh, data->prev_tty_context, data->tty_path);
+
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "Restore executable context: [%s] -> [%s]",
+ data->exec_context,
+ data->prev_exec_context ? data->prev_exec_context : "");
+ err |= set_exec_context(pamh, data->prev_exec_context);
+
+ if (err && security_getenforce() == 1)
+ return PAM_SESSION_ERR;
+
+ return PAM_SUCCESS;
+}
+
+static int
+set_context(pam_handle_t *pamh, const module_data_t *data,
+ int debug, int verbose)
+{
+ int rc, err;
+
+ if (debug && data->tty_path)
+ pam_syslog(pamh, LOG_NOTICE, "Set file context of tty %s: [%s] -> [%s]",
+ data->tty_path,
+ data->prev_tty_context ? data->prev_tty_context : "",
+ data->tty_context ? data->tty_context : "");
+ err = set_file_context(pamh, data->tty_context, data->tty_path);
+
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "Set executable context: [%s] -> [%s]",
+ data->prev_exec_context ? data->prev_exec_context : "",
+ data->exec_context);
+ rc = set_exec_context(pamh, data->exec_context);
+ err |= rc;
+
+ send_audit_message(pamh, !rc, data->default_user_context, data->exec_context);
+ if (verbose && !rc) {
+ char msg[PATH_MAX];
+
+ snprintf(msg, sizeof(msg),
+ _("Security context %s has been assigned."), data->exec_context);
+ send_text(pamh, msg, debug);
+ }
+#ifdef HAVE_SETKEYCREATECON
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "Set key creation context to %s",
+ data->exec_context ? data->exec_context : "");
+ rc = setkeycreatecon(data->exec_context);
+ err |= rc;
+ if (rc)
+ pam_syslog(pamh, LOG_ERR, "Setting key creation context %s failed: %m",
+ data->exec_context ? data->exec_context : "");
+ if (verbose && !rc) {
+ char msg[PATH_MAX];
+
+ snprintf(msg, sizeof(msg),
+ _("Key creation context %s has been assigned."), data->exec_context);
+ send_text(pamh, msg, debug);
+ }
+#endif
+
+ if (err && security_getenforce() == 1)
+ return PAM_SESSION_ERR;
+
+ return PAM_SUCCESS;
+}
+
+static int
+create_context(pam_handle_t *pamh, int argc, const char **argv,
+ int debug, int verbose)
+{
+ int i;
+ int ttys = 1;
+ int select_context = 0;
+ int use_current_range = 0;
+ int env_params = 0;
+ module_data_t *data;
+
+ /* Parse arguments. */
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "nottys") == 0) {
+ ttys = 0;
+ }
+ if (strcmp(argv[i], "select_context") == 0) {
+ select_context = 1;
+ }
+ if (strcmp(argv[i], "use_current_range") == 0) {
+ use_current_range = 1;
+ }
+ if (strcmp(argv[i], "env_params") == 0) {
+ env_params = 1;
+ }
+ }
+
+ if (is_selinux_enabled() <= 0) {
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "SELinux is not enabled");
+ return PAM_SUCCESS;
+ }
+
+ if (select_context && env_params) {
+ pam_syslog(pamh, LOG_ERR,
+ "select_context cannot be used with env_params");
+ select_context = 0;
+ }
+
+ if (!(data = calloc(1, sizeof(*data)))) {
+ pam_syslog(pamh, LOG_CRIT, "Out of memory");
+ return PAM_BUF_ERR;
+ }
+
+ i = compute_exec_context(pamh, data, select_context, use_current_range,
+ env_params, debug);
+ if (i != PAM_SUCCESS) {
+ free_module_data(data);
+ return i;
+ }
+
+ if (!data->exec_context) {
+ free_module_data(data);
+ return (security_getenforce() == 1) ? PAM_SESSION_ERR : PAM_SUCCESS;
+ }
+
+ if (ttys && (i = compute_tty_context(pamh, data)) != PAM_SUCCESS) {
+ free_module_data(data);
+ return i;
+ }
+
+ if ((i = pam_set_data(pamh, DATANAME, data, cleanup)) != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR, "Error saving context: %m");
+ free_module_data(data);
+ return i;
+ }
+
+ return set_context(pamh, data, debug, verbose);
+}
+
+int
+pam_sm_authenticate(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ /* Fail by default. */
+ return PAM_AUTH_ERR;
+}
+
+int
+pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
+
+int
+pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ const module_data_t *data;
+ int i, debug = 0, verbose = 0, close_session = 0, restore = 0;
+
+ /* Parse arguments. */
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "debug") == 0) {
+ debug = 1;
+ }
+ if (strcmp(argv[i], "verbose") == 0) {
+ verbose = 1;
+ }
+ if (strcmp(argv[i], "close") == 0) {
+ close_session = 1;
+ }
+ if (strcmp(argv[i], "restore") == 0) {
+ restore = 1;
+ }
+ }
+
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "Open Session");
+
+ /* Is this module supposed to execute close_session only? */
+ if (close_session)
+ return PAM_SUCCESS;
+
+ data = get_module_data(pamh);
+
+ /* Is this module supposed only to restore original context? */
+ if (restore)
+ return restore_context(pamh, data, debug);
+
+ /* If there is a saved context, this module is supposed to set it again. */
+ return data ? set_context(pamh, data, debug, verbose) :
+ create_context(pamh, argc, argv, debug, verbose);
+}
+
+int
+pam_sm_close_session(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ int i, debug = 0, open_session = 0;
+
+ /* Parse arguments. */
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "debug") == 0) {
+ debug = 1;
+ }
+ if (strcmp(argv[i], "open") == 0) {
+ open_session = 1;
+ }
+ }
+
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "Close Session");
+
+ /* Is this module supposed to execute open_session only? */
+ if (open_session)
+ return PAM_SUCCESS;
+
+ /* Restore original context. */
+ return restore_context(pamh, get_module_data(pamh), debug);
+}
diff --git a/modules/pam_selinux/pam_selinux_check.8 b/modules/pam_selinux/pam_selinux_check.8
new file mode 100644
index 0000000..34f578d
--- /dev/null
+++ b/modules/pam_selinux/pam_selinux_check.8
@@ -0,0 +1,35 @@
+.TH pam_selinux_check 8 2002/05/23 "Red Hat Linux" "System Administrator's Manual"
+.SH NAME
+pam_selinux_check \- login program to test pam_selinux.so
+.SH SYNOPSIS
+.B pam_selinux_check [user]
+.br
+
+.SH DESCRIPTION
+With no arguments,
+.B pam_selinux_check
+will prompt for user
+
+.SH OPTIONS
+.IP target_user
+The user to login as.
+
+.SH DIAGNOSTICS
+You must setup a /etc/pam.d/pam_selinux_check file, in order for the check to work.
+
+When checking if a selinux is valid,
+.B pam_selinux_check
+returns an exit code of 0 for success and > 0 on error:
+
+.nf
+1: Authentication failure
+.fi
+
+.SH SEE ALSO
+pam_selinux(8)
+
+.SH BUGS
+Let's hope not, but if you find any, please email the author.
+
+.SH AUTHOR
+Dan Walsh <dwalsh@redhat.com>
diff --git a/modules/pam_selinux/pam_selinux_check.c b/modules/pam_selinux/pam_selinux_check.c
new file mode 100644
index 0000000..30526d3
--- /dev/null
+++ b/modules/pam_selinux/pam_selinux_check.c
@@ -0,0 +1,161 @@
+/******************************************************************************
+ * A module for Linux-PAM that will set the default security context after login
+ * via PAM.
+ *
+ * Copyright (c) 2003 Red Hat, Inc.
+ * Written by Dan Walsh <dwalsh@redhat.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/************************************************************************
+ *
+ * All PAM code goes in this section.
+ *
+ ************************************************************************/
+
+#include "config.h"
+
+#include <errno.h>
+#include <syslog.h>
+#include <unistd.h> /* for getuid(), exit(), getopt() */
+#include <signal.h>
+#include <sys/wait.h> /* for wait() */
+
+#include <security/pam_appl.h> /* for PAM functions */
+#include <security/pam_misc.h> /* for misc_conv PAM utility function */
+
+#define SERVICE_NAME "pam_selinux_check" /* the name of this program for PAM */
+ /* The file containing the context to run
+ * the scripts under. */
+int authenticate_via_pam( const char *user , pam_handle_t **pamh);
+
+/* authenticate_via_pam()
+ *
+ * in: user
+ * out: nothing
+ * return: value condition
+ * ----- ---------
+ * 1 pam thinks that the user authenticated themselves properly
+ * 0 otherwise
+ *
+ * this function uses pam to authenticate the user running this
+ * program. this is the only function in this program that makes pam
+ * calls.
+ *
+ */
+
+int authenticate_via_pam( const char *user , pam_handle_t **pamh) {
+
+ struct pam_conv *conv;
+ int result = 0; /* our result, set to 0 (not authenticated) by default */
+
+ /* this is a jump table of functions for pam to use when it wants to *
+ * communicate with the user. we'll be using misc_conv(), which is *
+ * provided for us via pam_misc.h. */
+ struct pam_conv pam_conversation = {
+ misc_conv,
+ NULL
+ };
+ conv = &pam_conversation;
+
+
+ /* make `p_pam_handle' a valid pam handle so we can use it when *
+ * calling pam functions. */
+ if( PAM_SUCCESS != pam_start( SERVICE_NAME,
+ user,
+ conv,
+ pamh ) ) {
+ fprintf( stderr, _("failed to initialize PAM\n") );
+ exit( -1 );
+ }
+
+ if( PAM_SUCCESS != pam_set_item(*pamh, PAM_RUSER, user))
+ {
+ fprintf( stderr, _("failed to pam_set_item()\n") );
+ exit( -1 );
+ }
+
+ /* Ask PAM to authenticate the user running this program */
+ if( PAM_SUCCESS == pam_authenticate(*pamh,0) ) {
+ if ( PAM_SUCCESS == pam_open_session(*pamh, 0) )
+ result = 1; /* user authenticated OK! */
+ }
+ return( result );
+
+} /* authenticate_via_pam() */
+
+int
+main (int argc, char **argv)
+{
+ pam_handle_t *pamh;
+ int childPid;
+
+ if (argc < 1)
+ exit (-1);
+
+ if (!authenticate_via_pam(argv[1],&pamh))
+ exit(-1);
+
+ childPid = fork();
+ if (childPid < 0) {
+ /* error in fork() */
+ fprintf(stderr, _("login: failure forking: %m"));
+ pam_close_session(pamh, 0);
+ /* We're done with PAM. Free `pam_handle'. */
+ pam_end( pamh, PAM_SUCCESS );
+ exit(0);
+ }
+ if (childPid) {
+ close(0); close(1); close(2);
+ struct sigaction sa;
+ memset(&sa,0,sizeof(sa));
+ sa.sa_handler = SIG_IGN;
+ sigaction(SIGQUIT, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+ while(wait(NULL) == -1 && errno == EINTR) /**/ ;
+ openlog("login", LOG_ODELAY, LOG_AUTHPRIV);
+ pam_close_session(pamh, 0);
+ /* We're done with PAM. Free `pam_handle'. */
+ pam_end( pamh, PAM_SUCCESS );
+ exit(0);
+ }
+ argv[0]=strdup ("/bin/sh");
+ argv[1]=NULL;
+
+ /* NOTE: The environment has not been sanitized. LD_PRELOAD and other fun
+ * things could be set. */
+ execv("/bin/sh",argv);
+ fprintf(stderr,"Failure\n");
+ return 0;
+}
diff --git a/modules/pam_selinux/tst-pam_selinux b/modules/pam_selinux/tst-pam_selinux
new file mode 100755
index 0000000..14c3d82
--- /dev/null
+++ b/modules/pam_selinux/tst-pam_selinux
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_selinux.so
diff --git a/modules/pam_sepermit/Makefile.am b/modules/pam_sepermit/Makefile.am
new file mode 100644
index 0000000..18a89b6
--- /dev/null
+++ b/modules/pam_sepermit/Makefile.am
@@ -0,0 +1,42 @@
+#
+# Copyright (c) 2005, 2006, 2007 Thorsten Kukuk <kukuk@thkukuk.de>
+# Copyright (c) 2008, 2009 Red Hat, Inc.
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_sepermit.8 sepermit.conf.5
+endif
+XMLS = README.xml pam_sepermit.8.xml sepermit.conf.5.xml
+dist_check_SCRIPTS = tst-pam_sepermit
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+sepermitlockdir = ${localstatedir}/run/sepermit
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -I$(top_srcdir)/libpam_misc/include \
+ -D SEPERMIT_CONF_FILE=\"$(SCONFIGDIR)/sepermit.conf\" \
+ -D SEPERMIT_LOCKDIR=\"$(sepermitlockdir)\" $(WARN_CFLAGS)
+
+pam_sepermit_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBSELINUX@
+pam_sepermit_la_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ pam_sepermit_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+dist_secureconf_DATA = sepermit.conf
+securelib_LTLIBRARIES = pam_sepermit.la
+
+install-data-local:
+ mkdir -p $(DESTDIR)$(sepermitlockdir)
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_sepermit/Makefile.in b/modules/pam_sepermit/Makefile.in
new file mode 100644
index 0000000..3d2ba12
--- /dev/null
+++ b/modules/pam_sepermit/Makefile.in
@@ -0,0 +1,1234 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2007 Thorsten Kukuk <kukuk@thkukuk.de>
+# Copyright (c) 2008, 2009 Red Hat, Inc.
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_sepermit
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(dist_secureconf_DATA) \
+ $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man5dir)" \
+ "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(secureconfdir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_sepermit_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_sepermit_la_SOURCES = pam_sepermit.c
+pam_sepermit_la_OBJECTS = pam_sepermit.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+pam_sepermit_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(pam_sepermit_la_LDFLAGS) $(LDFLAGS) \
+ -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_sepermit.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_sepermit.c
+DIST_SOURCES = pam_sepermit.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man5dir = $(mandir)/man5
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA) $(dist_secureconf_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_sepermit.8 sepermit.conf.5
+XMLS = README.xml pam_sepermit.8.xml sepermit.conf.5.xml
+dist_check_SCRIPTS = tst-pam_sepermit
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+sepermitlockdir = ${localstatedir}/run/sepermit
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -I$(top_srcdir)/libpam_misc/include \
+ -D SEPERMIT_CONF_FILE=\"$(SCONFIGDIR)/sepermit.conf\" \
+ -D SEPERMIT_LOCKDIR=\"$(sepermitlockdir)\" $(WARN_CFLAGS)
+
+pam_sepermit_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBSELINUX@
+pam_sepermit_la_LDFLAGS = -no-undefined -avoid-version -module \
+ $(am__append_1)
+dist_secureconf_DATA = sepermit.conf
+securelib_LTLIBRARIES = pam_sepermit.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_sepermit/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_sepermit/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_sepermit.la: $(pam_sepermit_la_OBJECTS) $(pam_sepermit_la_DEPENDENCIES) $(EXTRA_pam_sepermit_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(pam_sepermit_la_LINK) -rpath $(securelibdir) $(pam_sepermit_la_OBJECTS) $(pam_sepermit_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_sepermit.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man5: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man5dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.5[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man5:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man5dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.5[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir)
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+install-dist_secureconfDATA: $(dist_secureconf_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_secureconf_DATA)'; test -n "$(secureconfdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(secureconfdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(secureconfdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(secureconfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(secureconfdir)" || exit $$?; \
+ done
+
+uninstall-dist_secureconfDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_secureconf_DATA)'; test -n "$(secureconfdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(secureconfdir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_sepermit.log: tst-pam_sepermit
+ @p='tst-pam_sepermit'; \
+ b='tst-pam_sepermit'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(secureconfdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_sepermit.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-data-local install-dist_secureconfDATA \
+ install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man5 install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_sepermit.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-dist_secureconfDATA uninstall-man \
+ uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man5 uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-data-local install-dist_secureconfDATA \
+ install-dvi install-dvi-am install-exec install-exec-am \
+ install-html install-html-am install-info install-info-am \
+ install-man install-man5 install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am \
+ uninstall-dist_secureconfDATA uninstall-man uninstall-man5 \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+
+install-data-local:
+ mkdir -p $(DESTDIR)$(sepermitlockdir)
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_sepermit/README b/modules/pam_sepermit/README
new file mode 100644
index 0000000..cd697bb
--- /dev/null
+++ b/modules/pam_sepermit/README
@@ -0,0 +1,48 @@
+pam_sepermit — PAM module to allow/deny login depending on SELinux enforcement
+state
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+The pam_sepermit module allows or denies login depending on SELinux enforcement
+state.
+
+When the user which is logging in matches an entry in the config file he is
+allowed access only when the SELinux is in enforcing mode. Otherwise he is
+denied access. For users not matching any entry in the config file the
+pam_sepermit module returns PAM_IGNORE return value.
+
+The config file contains a list of user names one per line with optional
+arguments. If the name is prefixed with @ character it means that all users in
+the group name match. If it is prefixed with a % character the SELinux user is
+used to match against the name instead of the account name. Note that when
+SELinux is disabled the SELinux user assigned to the account cannot be
+determined. This means that such entries are never matched when SELinux is
+disabled and pam_sepermit will return PAM_IGNORE.
+
+See sepermit.conf(5) for details.
+
+OPTIONS
+
+debug
+
+ Turns on debugging via syslog(3).
+
+conf=/path/to/config/file
+
+ Path to alternative config file overriding the default.
+
+EXAMPLES
+
+auth [success=done ignore=ignore default=bad] pam_sepermit.so
+auth required pam_unix.so
+account required pam_unix.so
+session required pam_permit.so
+
+
+AUTHOR
+
+pam_sepermit and this manual page were written by Tomas Mraz
+<tmraz@redhat.com>.
+
diff --git a/modules/pam_sepermit/README.xml b/modules/pam_sepermit/README.xml
new file mode 100644
index 0000000..bb65951
--- /dev/null
+++ b/modules/pam_sepermit/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_sepermit.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_sepermit.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_sepermit-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_sepermit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_sepermit-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_sepermit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_sepermit-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_sepermit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_sepermit-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_sepermit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_sepermit-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_sepermit/pam_sepermit.8 b/modules/pam_sepermit/pam_sepermit.8
new file mode 100644
index 0000000..fb82cb9
--- /dev/null
+++ b/modules/pam_sepermit/pam_sepermit.8
@@ -0,0 +1,131 @@
+'\" t
+.\" Title: pam_sepermit
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_SEPERMIT" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_sepermit \- PAM module to allow/deny login depending on SELinux enforcement state
+.SH "SYNOPSIS"
+.HP \w'\fBpam_sepermit\&.so\fR\ 'u
+\fBpam_sepermit\&.so\fR [debug] [conf=\fI/path/to/config/file\fR]
+.SH "DESCRIPTION"
+.PP
+The pam_sepermit module allows or denies login depending on SELinux enforcement state\&.
+.PP
+When the user which is logging in matches an entry in the config file he is allowed access only when the SELinux is in enforcing mode\&. Otherwise he is denied access\&. For users not matching any entry in the config file the pam_sepermit module returns PAM_IGNORE return value\&.
+.PP
+The config file contains a list of user names one per line with optional arguments\&. If the
+\fIname\fR
+is prefixed with
+\fI@\fR
+character it means that all users in the group
+\fIname\fR
+match\&. If it is prefixed with a
+\fI%\fR
+character the SELinux user is used to match against the
+\fIname\fR
+instead of the account name\&. Note that when SELinux is disabled the SELinux user assigned to the account cannot be determined\&. This means that such entries are never matched when SELinux is disabled and pam_sepermit will return PAM_IGNORE\&.
+.PP
+See
+\fBsepermit.conf\fR(5)
+for details\&.
+.SH "OPTIONS"
+.PP
+\fBdebug\fR
+.RS 4
+Turns on debugging via
+\fBsyslog\fR(3)\&.
+.RE
+.PP
+\fBconf=\fR\fB\fI/path/to/config/file\fR\fR
+.RS 4
+Path to alternative config file overriding the default\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+The
+\fBauth\fR
+and
+\fBaccount\fR
+module types are provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_AUTH_ERR
+.RS 4
+SELinux is disabled or in the permissive mode and the user matches\&.
+.RE
+.PP
+PAM_SUCCESS
+.RS 4
+SELinux is in the enforcing mode and the user matches\&.
+.RE
+.PP
+PAM_IGNORE
+.RS 4
+The user does not match any entry in the config file\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+The module was unable to determine the user\*(Aqs name\&.
+.RE
+.PP
+PAM_SERVICE_ERR
+.RS 4
+Error during reading or parsing the config file\&.
+.RE
+.SH "FILES"
+.PP
+/etc/security/sepermit\&.conf
+.RS 4
+Default configuration file
+.RE
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+auth [success=done ignore=ignore default=bad] pam_sepermit\&.so
+auth required pam_unix\&.so
+account required pam_unix\&.so
+session required pam_permit\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+.PP
+\fBsepermit.conf\fR(5),
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+\fBselinux\fR(8)
+.SH "AUTHOR"
+.PP
+pam_sepermit and this manual page were written by Tomas Mraz <tmraz@redhat\&.com>\&.
diff --git a/modules/pam_sepermit/pam_sepermit.8.xml b/modules/pam_sepermit/pam_sepermit.8.xml
new file mode 100644
index 0000000..30d9cc5
--- /dev/null
+++ b/modules/pam_sepermit/pam_sepermit.8.xml
@@ -0,0 +1,194 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_sepermit">
+
+ <refmeta>
+ <refentrytitle>pam_sepermit</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_sepermit-name">
+ <refname>pam_sepermit</refname>
+ <refpurpose>PAM module to allow/deny login depending on SELinux enforcement state</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_sepermit-cmdsynopsis">
+ <command>pam_sepermit.so</command>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ conf=<replaceable>/path/to/config/file</replaceable>
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_sepermit-description">
+ <title>DESCRIPTION</title>
+ <para>
+ The pam_sepermit module allows or denies login depending on SELinux
+ enforcement state.
+ </para>
+ <para>
+ When the user which is logging in matches an entry in the config file
+ he is allowed access only when the SELinux is in enforcing mode. Otherwise
+ he is denied access. For users not matching any entry in the config file
+ the pam_sepermit module returns PAM_IGNORE return value.
+ </para>
+ <para>
+ The config file contains a list of user names one per line with optional arguments. If the
+ <replaceable>name</replaceable> is prefixed with <emphasis>@</emphasis> character it means that all
+ users in the group <replaceable>name</replaceable> match. If it is prefixed
+ with a <emphasis>%</emphasis> character the SELinux user is used to match against the <replaceable>name</replaceable>
+ instead of the account name. Note that when SELinux is disabled the
+ SELinux user assigned to the account cannot be determined. This means that
+ such entries are never matched when SELinux is disabled and pam_sepermit
+ will return PAM_IGNORE.
+ </para>
+ <para>
+ See <citerefentry>
+ <refentrytitle>sepermit.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry> for details.
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="pam_sepermit-options">
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Turns on debugging via
+ <citerefentry>
+ <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>conf=<replaceable>/path/to/config/file</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Path to alternative config file overriding the default.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_sepermit-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ The <option>auth</option> and <option>account</option>
+ module types are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_sepermit-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_AUTH_ERR</term>
+ <listitem>
+ <para>
+ SELinux is disabled or in the permissive mode and the user
+ matches.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ SELinux is in the enforcing mode and the user matches.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ The user does not match any entry in the config file.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ The module was unable to determine the user's name.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ Error during reading or parsing the config file.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_sepermit-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/security/sepermit.conf</filename></term>
+ <listitem>
+ <para>Default configuration file</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_sepermit-examples'>
+ <title>EXAMPLES</title>
+ <programlisting>
+auth [success=done ignore=ignore default=bad] pam_sepermit.so
+auth required pam_unix.so
+account required pam_unix.so
+session required pam_permit.so
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id='pam_sepermit-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>sepermit.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ <citerefentry>
+ <refentrytitle>selinux</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_sepermit-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_sepermit and this manual page were written by Tomas Mraz &lt;tmraz@redhat.com&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_sepermit/pam_sepermit.c b/modules/pam_sepermit/pam_sepermit.c
new file mode 100644
index 0000000..f7d98d5
--- /dev/null
+++ b/modules/pam_sepermit/pam_sepermit.c
@@ -0,0 +1,440 @@
+/******************************************************************************
+ * A module for Linux-PAM that allows/denies access based on SELinux state.
+ *
+ * Copyright (c) 2007, 2008, 2009 Red Hat, Inc.
+ * Originally written by Tomas Mraz <tmraz@redhat.com>
+ * Contributions by Dan Walsh <dwalsh@redhat.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <ctype.h>
+#include <signal.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+
+#include <selinux/selinux.h>
+
+#define MODULE "pam_sepermit"
+#define OPT_DELIM ":"
+
+struct lockfd {
+ uid_t uid;
+ int fd;
+ int debug;
+};
+
+#define PROC_BASE "/proc"
+#define MAX_NAMES (int)(sizeof(unsigned long)*8)
+
+static int
+match_process_uid(pid_t pid, uid_t uid)
+{
+ char buf[128];
+ uid_t puid;
+ FILE *f;
+ int re = 0;
+
+ snprintf (buf, sizeof buf, PROC_BASE "/%d/status", pid);
+ if (!(f = fopen (buf, "r")))
+ return 0;
+
+ while (fgets(buf, sizeof buf, f)) {
+ if (sscanf (buf, "Uid:\t%d", &puid)) {
+ re = uid == puid;
+ break;
+ }
+ }
+ fclose(f);
+ return re;
+}
+
+static int
+check_running (pam_handle_t *pamh, uid_t uid, int killall, int debug)
+{
+ DIR *dir;
+ struct dirent *de;
+ pid_t *pid_table, pid, self;
+ int i;
+ int pids, max_pids;
+ int running = 0;
+ self = getpid();
+ if (!(dir = opendir(PROC_BASE))) {
+ pam_syslog(pamh, LOG_ERR, "Failed to open proc directory file %s:", PROC_BASE);
+ return -1;
+ }
+ max_pids = 256;
+ pid_table = malloc(max_pids * sizeof (pid_t));
+ if (!pid_table) {
+ (void)closedir(dir);
+ pam_syslog(pamh, LOG_CRIT, "Memory allocation error");
+ return -1;
+ }
+ pids = 0;
+ while ((de = readdir (dir)) != NULL) {
+ if (!(pid = (pid_t)atoi(de->d_name)) || pid == self)
+ continue;
+
+ if (pids == max_pids) {
+ pid_t *npt;
+
+ if (!(npt = realloc(pid_table, 2*pids*sizeof(pid_t)))) {
+ free(pid_table);
+ (void)closedir(dir);
+ pam_syslog(pamh, LOG_CRIT, "Memory allocation error");
+ return -1;
+ }
+ pid_table = npt;
+ max_pids *= 2;
+ }
+ pid_table[pids++] = pid;
+ }
+
+ (void)closedir(dir);
+
+ for (i = 0; i < pids; i++) {
+ pid_t id;
+
+ if (match_process_uid(pid_table[i], uid) == 0)
+ continue;
+ id = pid_table[i];
+
+ if (killall) {
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "Attempting to kill %d", id);
+ kill(id, SIGKILL);
+ }
+ running++;
+ }
+
+ free(pid_table);
+ return running;
+}
+
+/*
+ * This function reads the loginuid from the /proc system. It returns
+ * (uid_t)-1 on failure.
+ */
+static uid_t get_loginuid(pam_handle_t *pamh)
+{
+ int fd, count;
+ char loginuid[24];
+ char *eptr;
+ uid_t rv = (uid_t)-1;
+
+ fd = open("/proc/self/loginuid", O_NOFOLLOW|O_RDONLY);
+ if (fd < 0) {
+ if (errno != ENOENT) {
+ pam_syslog(pamh, LOG_ERR,
+ "Cannot open /proc/self/loginuid: %m");
+ }
+ return rv;
+ }
+ if ((count = pam_modutil_read(fd, loginuid, sizeof(loginuid)-1)) < 1) {
+ close(fd);
+ return rv;
+ }
+ loginuid[count] = '\0';
+ close(fd);
+
+ errno = 0;
+ rv = strtoul(loginuid, &eptr, 10);
+ if (errno != 0 || eptr == loginuid)
+ rv = (uid_t) -1;
+
+ return rv;
+}
+
+static void
+sepermit_unlock(pam_handle_t *pamh, void *plockfd, int error_status UNUSED)
+{
+ struct lockfd *lockfd = plockfd;
+ struct flock fl;
+
+ memset(&fl, 0, sizeof(fl));
+ fl.l_type = F_UNLCK;
+ fl.l_whence = SEEK_SET;
+
+ if (lockfd->debug)
+ pam_syslog(pamh, LOG_ERR, "Unlocking fd: %d uid: %d", lockfd->fd, lockfd->uid);
+
+ /* Don't kill uid==0 */
+ if (lockfd->uid)
+ /* This is a DOS but it prevents an app from forking to prevent killing */
+ while(check_running(pamh, lockfd->uid, 1, lockfd->debug) > 0)
+ continue;
+
+ (void)fcntl(lockfd->fd, F_SETLK, &fl);
+ (void)close(lockfd->fd);
+ free(lockfd);
+}
+
+static int
+sepermit_lock(pam_handle_t *pamh, const char *user, int debug)
+{
+ char buf[PATH_MAX];
+ struct flock fl;
+
+ memset(&fl, 0, sizeof(fl));
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+
+ struct passwd *pw = pam_modutil_getpwnam( pamh, user );
+ if (!pw) {
+ pam_syslog(pamh, LOG_NOTICE, "Unable to find uid for user %s",
+ user);
+ return -1;
+ }
+ if (check_running(pamh, pw->pw_uid, 0, debug) > 0) {
+ pam_syslog(pamh, LOG_ERR, "User %s processes are running. Exclusive login not allowed", user);
+ return -1;
+ }
+
+ snprintf(buf, sizeof(buf), "%s/%d.lock", SEPERMIT_LOCKDIR, pw->pw_uid);
+ int fd = open(buf, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
+ if (fd < 0) {
+ pam_syslog(pamh, LOG_ERR, "Unable to open lock file %s/%d.lock", SEPERMIT_LOCKDIR, pw->pw_uid);
+ return -1;
+ }
+
+ /* Need to close on exec */
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
+
+ if (fcntl(fd, F_SETLK, &fl) == -1) {
+ pam_syslog(pamh, LOG_ERR, "User %s with exclusive login already logged in", user);
+ close(fd);
+ return -1;
+ }
+ struct lockfd *lockfd=calloc(1, sizeof(struct lockfd));
+ if (!lockfd) {
+ close(fd);
+ pam_syslog(pamh, LOG_CRIT, "Memory allocation error");
+ return -1;
+ }
+ lockfd->uid = pw->pw_uid;
+ lockfd->debug = debug;
+ lockfd->fd=fd;
+ pam_set_data(pamh, MODULE, lockfd, sepermit_unlock);
+ return 0;
+}
+
+/* return 0 when matched, -1 when unmatched, pam error otherwise */
+static int
+sepermit_match(pam_handle_t *pamh, const char *cfgfile, const char *user,
+ const char *seuser, int debug, int *sense)
+{
+ FILE *f;
+ char *line = NULL;
+ char *start;
+ size_t len = 0;
+ int matched = 0;
+ int exclusive = 0;
+ int ignore = 0;
+
+ f = fopen(cfgfile, "r");
+
+ if (!f) {
+ pam_syslog(pamh, LOG_ERR, "Failed to open config file %s: %m", cfgfile);
+ return PAM_SERVICE_ERR;
+ }
+
+ while (!matched && getline(&line, &len, f) != -1) {
+ size_t n;
+ char *sptr;
+ char *opt;
+
+ if (line[0] == '#')
+ continue;
+
+ start = line;
+ while (isspace(*start))
+ ++start;
+ n = strlen(start);
+ while (n > 0 && isspace(start[n-1])) {
+ --n;
+ }
+ if (n == 0)
+ continue;
+
+ start[n] = '\0';
+ start = strtok_r(start, OPT_DELIM, &sptr);
+
+ switch (start[0]) {
+ case '@':
+ ++start;
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "Matching user %s against group %s", user, start);
+ if (pam_modutil_user_in_group_nam_nam(pamh, user, start)) {
+ matched = 1;
+ }
+ break;
+ case '%':
+ if (seuser == NULL)
+ break;
+ ++start;
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "Matching seuser %s against seuser %s", seuser, start);
+ if (strcmp(seuser, start) == 0) {
+ matched = 1;
+ }
+ break;
+ default:
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "Matching user %s against user %s", user, start);
+ if (strcmp(user, start) == 0) {
+ matched = 1;
+ }
+ }
+ if (matched)
+ while ((opt=strtok_r(NULL, OPT_DELIM, &sptr)) != NULL) {
+ if (strcmp(opt, "exclusive") == 0)
+ exclusive = 1;
+ else if (strcmp(opt, "ignore") == 0)
+ ignore = 1;
+ else if (debug) {
+ pam_syslog(pamh, LOG_NOTICE, "Unknown user option: %s", opt);
+ }
+ }
+ }
+
+ free(line);
+ fclose(f);
+ if (matched) {
+ if (*sense == PAM_SUCCESS) {
+ if (ignore)
+ *sense = PAM_IGNORE;
+ if (geteuid() == 0 && exclusive && get_loginuid(pamh) == (uid_t)-1)
+ if (sepermit_lock(pamh, user, debug) < 0)
+ *sense = PAM_AUTH_ERR;
+ }
+ return 0;
+ }
+ else
+ return -1;
+}
+
+int
+pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ int i;
+ int rv;
+ int debug = 0;
+ int sense = PAM_AUTH_ERR;
+ const char *user = NULL;
+ char *seuser = NULL;
+ char *level = NULL;
+ const char *cfgfile = SEPERMIT_CONF_FILE;
+
+ /* Parse arguments. */
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "debug") == 0) {
+ debug = 1;
+ }
+ if (strcmp(argv[i], "conf=") == 0) {
+ cfgfile = argv[i] + 5;
+ }
+ }
+
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "Parsing config file: %s", cfgfile);
+
+ if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS || *user == '\0') {
+ pam_syslog(pamh, LOG_NOTICE, "cannot determine user name");
+ return PAM_USER_UNKNOWN;
+ }
+
+ if (is_selinux_enabled() > 0) {
+ if (security_getenforce() == 1) {
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "Enforcing mode, access will be allowed on match");
+ sense = PAM_SUCCESS;
+ }
+ }
+
+ if (getseuserbyname(user, &seuser, &level) != 0) {
+ seuser = NULL;
+ level = NULL;
+ pam_syslog(pamh, LOG_ERR, "getseuserbyname failed: %m");
+ }
+
+ if (debug && sense != PAM_SUCCESS)
+ pam_syslog(pamh, LOG_NOTICE, "Access will not be allowed on match");
+
+ rv = sepermit_match(pamh, cfgfile, user, seuser, debug, &sense);
+
+ if (debug)
+ pam_syslog(pamh, LOG_NOTICE, "sepermit_match returned: %d", rv);
+
+ free(seuser);
+ free(level);
+
+ switch (rv) {
+ case -1:
+ return PAM_IGNORE;
+ case 0:
+ return sense;
+ }
+
+ return rv;
+}
+
+int
+pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_IGNORE;
+}
+
+int
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
diff --git a/modules/pam_sepermit/sepermit.conf b/modules/pam_sepermit/sepermit.conf
new file mode 100644
index 0000000..0a12cd8
--- /dev/null
+++ b/modules/pam_sepermit/sepermit.conf
@@ -0,0 +1,11 @@
+# /etc/security/sepermit.conf
+#
+# Each line contains either:
+# - a user name
+# - a group name, with @group syntax
+# - a SELinux user name, with %seuser syntax
+# Each line can contain optional arguments separated by :
+# The possible arguments are:
+# - exclusive - only single login session will
+# be allowed for the user and the user's processes
+# will be killed on logout
diff --git a/modules/pam_sepermit/sepermit.conf.5 b/modules/pam_sepermit/sepermit.conf.5
new file mode 100644
index 0000000..b4b91c8
--- /dev/null
+++ b/modules/pam_sepermit/sepermit.conf.5
@@ -0,0 +1,117 @@
+'\" t
+.\" Title: sepermit.conf
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "SEPERMIT\&.CONF" "5" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+sepermit.conf \- configuration file for the pam_sepermit module
+.SH "DESCRIPTION"
+.PP
+The lines of the configuration file have the following syntax:
+.PP
+\fI<user>\fR[:\fI<option>\fR:\fI<option>\fR\&.\&.\&.]
+.PP
+The
+\fBuser\fR
+can be specified in the following manner:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+a username
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+a groupname, with
+\fB@group\fR
+syntax\&. This should not be confused with netgroups\&.
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+a SELinux user name with
+\fB%seuser\fR
+syntax\&.
+.RE
+.PP
+The recognized options are:
+.PP
+\fBexclusive\fR
+.RS 4
+Only single login session will be allowed for the user and the user\*(Aqs processes will be killed on logout\&.
+.RE
+.PP
+\fBignore\fR
+.RS 4
+The module will never return PAM_SUCCESS status for the user\&. It will return PAM_IGNORE if SELinux is in the enforcing mode, and PAM_AUTH_ERR otherwise\&. It is useful if you want to support passwordless guest users and other confined users with passwords simultaneously\&.
+.RE
+.PP
+The lines which start with # character are comments and are ignored\&.
+.SH "EXAMPLES"
+.PP
+These are some example lines which might be specified in
+/etc/security/sepermit\&.conf\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+%guest_u:exclusive
+%staff_u:ignore
+%user_u:ignore
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+.PP
+\fBpam_sepermit\fR(8),
+\fBpam.d\fR(5),
+\fBpam\fR(8),
+\fBselinux\fR(8),
+.SH "AUTHOR"
+.PP
+pam_sepermit and this manual page were written by Tomas Mraz <tmraz@redhat\&.com>
diff --git a/modules/pam_sepermit/sepermit.conf.5.xml b/modules/pam_sepermit/sepermit.conf.5.xml
new file mode 100644
index 0000000..511480f
--- /dev/null
+++ b/modules/pam_sepermit/sepermit.conf.5.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="sepermit.conf">
+
+ <refmeta>
+ <refentrytitle>sepermit.conf</refentrytitle>
+ <manvolnum>5</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>sepermit.conf</refname>
+ <refpurpose>configuration file for the pam_sepermit module</refpurpose>
+ </refnamediv>
+
+ <refsect1 id='sepermit.conf-description'>
+ <title>DESCRIPTION</title>
+ <para>
+ The lines of the configuration file have the following syntax:
+ </para>
+ <para>
+ <replaceable>&lt;user&gt;</replaceable>[:<replaceable>&lt;option&gt;</replaceable>:<replaceable>&lt;option&gt;</replaceable>...]
+ </para>
+ <para>
+ The <emphasis remap='B'>user</emphasis> can be specified in the following manner:
+ </para>
+ <itemizedlist>
+ <listitem>
+ <para>
+ a username
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ a groupname, with <emphasis remap='B'>@group</emphasis> syntax.
+ This should not be confused with netgroups.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ a SELinux user name with <emphasis remap='B'>%seuser</emphasis> syntax.
+ </para>
+ </listitem>
+ </itemizedlist>
+
+ <para>
+ The recognized options are:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>exclusive</option></term>
+ <listitem>
+ <para>
+ Only single login session will be allowed for the user
+ and the user's processes will be killed on logout.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>ignore</option></term>
+ <listitem>
+ <para>
+ The module will never return PAM_SUCCESS status for the user.
+ It will return PAM_IGNORE if SELinux is in the enforcing mode,
+ and PAM_AUTH_ERR otherwise. It is useful if you want to support
+ passwordless guest users and other confined users with passwords
+ simultaneously.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ The lines which start with # character are comments and are ignored.
+ </para>
+ </refsect1>
+
+ <refsect1 id="sepermit.conf-examples">
+ <title>EXAMPLES</title>
+ <para>
+ These are some example lines which might be specified in
+ <filename>/etc/security/sepermit.conf</filename>.
+ </para>
+ <programlisting>
+%guest_u:exclusive
+%staff_u:ignore
+%user_u:ignore
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id="sepermit.conf-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry><refentrytitle>pam_sepermit</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>selinux</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ </para>
+ </refsect1>
+
+ <refsect1 id="sepermit.conf-author">
+ <title>AUTHOR</title>
+ <para>
+ pam_sepermit and this manual page were written by Tomas Mraz &lt;tmraz@redhat.com&gt;
+ </para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_sepermit/tst-pam_sepermit b/modules/pam_sepermit/tst-pam_sepermit
new file mode 100755
index 0000000..6e6d236
--- /dev/null
+++ b/modules/pam_sepermit/tst-pam_sepermit
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_sepermit.so
diff --git a/modules/pam_setquota/Makefile.am b/modules/pam_setquota/Makefile.am
new file mode 100644
index 0000000..b01a328
--- /dev/null
+++ b/modules/pam_setquota/Makefile.am
@@ -0,0 +1,29 @@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_setquota.8
+endif
+XMLS = README.xml pam_setquota.8.xml
+dist_check_SCRIPTS = tst-pam_setquota
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_setquota.la
+pam_setquota_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_setquota/Makefile.in b/modules/pam_setquota/Makefile.in
new file mode 100644
index 0000000..f4f49f0
--- /dev/null
+++ b/modules/pam_setquota/Makefile.in
@@ -0,0 +1,1146 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_setquota
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_setquota_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_setquota_la_SOURCES = pam_setquota.c
+pam_setquota_la_OBJECTS = pam_setquota.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_setquota.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_setquota.c
+DIST_SOURCES = pam_setquota.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_setquota.8
+XMLS = README.xml pam_setquota.8.xml
+dist_check_SCRIPTS = tst-pam_setquota
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_setquota.la
+pam_setquota_la_LIBADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_setquota/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_setquota/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_setquota.la: $(pam_setquota_la_OBJECTS) $(pam_setquota_la_DEPENDENCIES) $(EXTRA_pam_setquota_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_setquota_la_OBJECTS) $(pam_setquota_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_setquota.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_setquota.log: tst-pam_setquota
+ @p='tst-pam_setquota'; \
+ b='tst-pam_setquota'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_setquota.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_setquota.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_setquota/README b/modules/pam_setquota/README
new file mode 100644
index 0000000..fd00da7
--- /dev/null
+++ b/modules/pam_setquota/README
@@ -0,0 +1,80 @@
+pam_setquota — PAM module to set or modify disk quotas on session start
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+pam_setquota is a PAM module to set or modify a disk quota at session start
+
+This makes quotas usable with central user databases, such as MySQL or LDAP.
+
+OPTIONS
+
+fs=/home
+
+ The device file or mountpoint the policy applies to. Defaults to the
+ filesystem containing the users home directory.
+
+overwrite=0
+
+ Overwrite an existing quota. Note: Enabling this will remove the ability
+ for the admin to manually configure different quotas for users for a
+ filesystem with edquota(8). (Defaults to 0)
+
+debug=0
+
+ Enable debugging. A value of 1 outputs the old and new quota on a device. A
+ value of 2 also prints out the matched and found filesystems should fs be
+ unset. (Defaults to 0)
+
+startuid=1000
+
+ Describe the start of the UID range the policy is applied to. (Defaults to
+ UID_MIN from login.defs or the uidmin value defined at compile-time if
+ UID_MIN is undefined.)
+
+enduid=0
+
+ Describe the end of the UID range the policy is applied to. Setting enduid=
+ 0 results in an open-ended UID range (i.e. all uids greater than startuid
+ are included). (Defaults to 0)
+
+bsoftlimit=19000
+
+ Soft limit for disk quota blocks, as defined by quotactl(2). Note:
+ bsoftlimit and bhardlimit must be set at the same time!
+
+bhardlimit=20000
+
+ Hard limit for disk quota blocks, as defined by quotactl(2). Note:
+ bsoftlimit and bhardlimit must be set at the same time!
+
+isoftlimit=3000
+
+ Soft limit for inodes, as defined by quotactl(2). Note: isoftlimit and
+ ihardlimit must be set at the same time!
+
+ihardlimit=4000
+
+ Hard limit for inodes, as defined by quotactl(2). Note: isoftlimit and
+ ihardlimit must be set at the same time!
+
+EXAMPLES
+
+A single invocation of `pam_setquota` applies a specific policy to a UID range.
+Applying different policies to specific UID ranges is done by invoking
+pam_setquota more than once. The last matching entry defines the resulting
+quota.
+
+ session required pam_setquota.so bsoftlimit=1000 bhardlimit=2000 isoftlimit=1000 ihardlimit=2000 startuid=1000 enduid=0 fs=/home
+ session required pam_setquota.so bsoftlimit=19000 bhardlimit=20000 isoftlimit=3000 ihardlimit=4000 startuid=2001 enduid=3000 fs=/dev/sda1
+ session required pam_setquota.so bsoftlimit=19000 bhardlimit=20000 isoftlimit=3000 ihardlimit=4000 startuid=3001 enduid=4000 fs=/dev/sda1 overwrite=1
+
+
+AUTHOR
+
+pam_setquota was originally written by Ruslan Savchenko <savrus@mexmat.net>.
+
+Further modifications were made by Shane Tzen <shane@ict.usc.edu>, Sven Hartge
+<sven@svenhartge.de> and Keller Fuchs <kellerfuchs@hashbang.sh>.
+
diff --git a/modules/pam_setquota/README.xml b/modules/pam_setquota/README.xml
new file mode 100644
index 0000000..4eeddec
--- /dev/null
+++ b/modules/pam_setquota/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_setquota.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_setquota.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_setquota-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_setquota.8.xml" xpointer='xpointer(//refsect1[@id = "pam_setquota-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_setquota.8.xml" xpointer='xpointer(//refsect1[@id = "pam_setquota-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_setquota.8.xml" xpointer='xpointer(//refsect1[@id = "pam_setquota-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_setquota.8.xml" xpointer='xpointer(//refsect1[@id = "pam_setquota-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_setquota/pam_setquota.8 b/modules/pam_setquota/pam_setquota.8
new file mode 100644
index 0000000..f09ba96
--- /dev/null
+++ b/modules/pam_setquota/pam_setquota.8
@@ -0,0 +1,186 @@
+'\" t
+.\" Title: pam_setquota
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_SETQUOTA" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_setquota \- PAM module to set or modify disk quotas on session start
+.SH "SYNOPSIS"
+.HP \w'\fBpam_setquota\&.so\fR\ 'u
+\fBpam_setquota\&.so\fR [fs=\fI/home\fR] [overwrite=\fI0\fR] [debug=\fI0\fR] [startuid=\fI1000\fR] [enduid=\fI0\fR] [bsoftlimit=\fI19000\fR] [bhardlimit=\fI20000\fR] [isoftlimit=\fI3000\fR] [ihardlimit=\fI4000\fR]
+.SH "DESCRIPTION"
+.PP
+pam_setquota is a PAM module to set or modify a disk quota at session start
+.PP
+This makes quotas usable with central user databases, such as MySQL or LDAP\&.
+.SH "OPTIONS"
+.PP
+.PP
+\fBfs=\fR\fB\fI/home\fR\fR
+.RS 4
+The device file or mountpoint the policy applies to\&. Defaults to the filesystem containing the users home directory\&.
+.RE
+.PP
+\fBoverwrite=\fR\fB\fI0\fR\fR
+.RS 4
+Overwrite an existing quota\&. Note: Enabling this will remove the ability for the admin to manually configure different quotas for users for a filesystem with
+\fBedquota\fR(8)\&. (Defaults to 0)
+.RE
+.PP
+\fBdebug=\fR\fB\fI0\fR\fR
+.RS 4
+Enable debugging\&. A value of 1 outputs the old and new quota on a device\&. A value of 2 also prints out the matched and found filesystems should
+\fBfs\fR
+be unset\&. (Defaults to 0)
+.RE
+.PP
+\fBstartuid=\fR\fB\fI1000\fR\fR
+.RS 4
+Describe the start of the UID range the policy is applied to\&. (Defaults to UID_MIN from login\&.defs or the uidmin value defined at compile\-time if UID_MIN is undefined\&.)
+.RE
+.PP
+\fBenduid=\fR\fB\fI0\fR\fR
+.RS 4
+Describe the end of the UID range the policy is applied to\&. Setting
+\fIenduid=0\fR
+results in an open\-ended UID range (i\&.e\&. all uids greater than
+\fBstartuid\fR
+are included)\&. (Defaults to 0)
+.RE
+.PP
+\fBbsoftlimit=\fR\fB\fI19000\fR\fR
+.RS 4
+Soft limit for disk quota blocks, as defined by
+\fBquotactl\fR(2)\&. Note:
+\fBbsoftlimit\fR
+and
+\fBbhardlimit\fR
+\fImust\fR
+be set at the same time!
+.RE
+.PP
+\fBbhardlimit=\fR\fB\fI20000\fR\fR
+.RS 4
+Hard limit for disk quota blocks, as defined by
+\fBquotactl\fR(2)\&. Note:
+\fBbsoftlimit\fR
+and
+\fBbhardlimit\fR
+\fImust\fR
+be set at the same time!
+.RE
+.PP
+\fBisoftlimit=\fR\fB\fI3000\fR\fR
+.RS 4
+Soft limit for inodes, as defined by
+\fB quotactl\fR(2)\&. Note:
+\fBisoftlimit\fR
+and
+\fBihardlimit\fR
+\fImust\fR
+be set at the same time!
+.RE
+.PP
+\fBihardlimit=\fR\fB\fI4000\fR\fR
+.RS 4
+Hard limit for inodes, as defined by
+\fB quotactl\fR(2)\&. Note:
+\fBisoftlimit\fR
+and
+\fBihardlimit\fR
+\fImust\fR
+be set at the same time!
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+Only the
+\fBsession\fR
+module type is provided\&.
+.SH "RETURN VALUES"
+.PP
+.PP
+PAM_SUCCESS
+.RS 4
+The quota was set successfully\&.
+.RE
+.PP
+PAM_IGNORE
+.RS 4
+No action was taken because either the UID of the user was outside of the specified range, a quota already existed and
+\fBoverwrite=1\fR
+was not configured or no limits were configured at all\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+The user was not found\&.
+.RE
+.PP
+PAM_PERM_DENIED
+.RS 4
+/proc/mounts
+could not be opened\&.
+.sp
+The filesystem or device specified was not found\&.
+.sp
+The limits for the user could not be retrieved\&. See syslog for more information\&.
+.sp
+The limits for the user could not be set\&. See syslog for more information\&.
+.sp
+Either
+\fBisoftlimit\fR/\fBihardlimit\fR
+or
+\fBbsoftlimit\fR/\fBbhardlimit\fR
+were not set at the same time\&.
+.RE
+.SH "EXAMPLES"
+.PP
+A single invocation of `pam_setquota` applies a specific policy to a UID range\&. Applying different policies to specific UID ranges is done by invoking pam_setquota more than once\&. The last matching entry defines the resulting quota\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ session required pam_setquota\&.so bsoftlimit=1000 bhardlimit=2000 isoftlimit=1000 ihardlimit=2000 startuid=1000 enduid=0 fs=/home
+ session required pam_setquota\&.so bsoftlimit=19000 bhardlimit=20000 isoftlimit=3000 ihardlimit=4000 startuid=2001 enduid=3000 fs=/dev/sda1
+ session required pam_setquota\&.so bsoftlimit=19000 bhardlimit=20000 isoftlimit=3000 ihardlimit=4000 startuid=3001 enduid=4000 fs=/dev/sda1 overwrite=1
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.PP
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_setquota was originally written by Ruslan Savchenko <savrus@mexmat\&.net>\&.
+.PP
+Further modifications were made by Shane Tzen <shane@ict\&.usc\&.edu>, Sven Hartge <sven@svenhartge\&.de> and Keller Fuchs <kellerfuchs@hashbang\&.sh>\&.
diff --git a/modules/pam_setquota/pam_setquota.8.xml b/modules/pam_setquota/pam_setquota.8.xml
new file mode 100644
index 0000000..fe83c80
--- /dev/null
+++ b/modules/pam_setquota/pam_setquota.8.xml
@@ -0,0 +1,301 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_setquota">
+
+ <refmeta>
+ <refentrytitle>pam_setquota</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_setquota-name">
+ <refname>pam_setquota</refname>
+ <refpurpose>PAM module to set or modify disk quotas on session start</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_setquota-cmdsynopsis">
+ <command>pam_setquota.so</command>
+ <arg choice="opt">
+ fs=<replaceable>/home</replaceable>
+ </arg>
+ <arg choice="opt">
+ overwrite=<replaceable>0</replaceable>
+ </arg>
+ <arg choice="opt">
+ debug=<replaceable>0</replaceable>
+ </arg>
+ <arg choice="opt">
+ startuid=<replaceable>1000</replaceable>
+ </arg>
+ <arg choice="opt">
+ enduid=<replaceable>0</replaceable>
+ </arg>
+ <arg choice="opt">
+ bsoftlimit=<replaceable>19000</replaceable>
+ </arg>
+ <arg choice="opt">
+ bhardlimit=<replaceable>20000</replaceable>
+ </arg>
+ <arg choice="opt">
+ isoftlimit=<replaceable>3000</replaceable>
+ </arg>
+ <arg choice="opt">
+ ihardlimit=<replaceable>4000</replaceable>
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_setquota-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ pam_setquota is a PAM module to set or modify a disk quota at session start
+ </para>
+ <para>
+ This makes quotas usable with central user databases, such as MySQL or LDAP.
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="pam_setquota-options">
+
+ <title>OPTIONS</title>
+ <para>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>fs=<replaceable>/home</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The device file or mountpoint the policy applies to. Defaults to the
+ filesystem containing the users home directory.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>overwrite=<replaceable>0</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Overwrite an existing quota. Note: Enabling this will remove the ability
+ for the admin to manually configure different quotas for users for a
+ filesystem with <citerefentry><refentrytitle>edquota</refentrytitle>
+ <manvolnum>8</manvolnum></citerefentry>. (Defaults to 0)
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>debug=<replaceable>0</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Enable debugging. A value of 1 outputs the old and new quota on a device.
+ A value of 2 also prints out the matched and found filesystems should
+ <option>fs</option> be unset. (Defaults to 0)
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>startuid=<replaceable>1000</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Describe the start of the UID range the policy is applied to.
+ (Defaults to UID_MIN from login.defs or the uidmin value defined
+ at compile-time if UID_MIN is undefined.)
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>enduid=<replaceable>0</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Describe the end of the UID range the policy is applied to. Setting
+ <emphasis>enduid=0</emphasis> results in an open-ended UID
+ range (i.e. all uids greater than <option>startuid</option> are
+ included). (Defaults to 0)
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>bsoftlimit=<replaceable>19000</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Soft limit for disk quota blocks, as defined by <citerefentry>
+ <refentrytitle>quotactl</refentrytitle><manvolnum>2</manvolnum>
+ </citerefentry>.
+ Note: <option>bsoftlimit</option> and <option>bhardlimit</option>
+ <emphasis>must</emphasis> be set at the same time!
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>bhardlimit=<replaceable>20000</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Hard limit for disk quota blocks, as defined by <citerefentry>
+ <refentrytitle>quotactl</refentrytitle><manvolnum>2</manvolnum>
+ </citerefentry>.
+ Note: <option>bsoftlimit</option> and <option>bhardlimit</option>
+ <emphasis>must</emphasis> be set at the same time!
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>isoftlimit=<replaceable>3000</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Soft limit for inodes, as defined by <citerefentry><refentrytitle>
+ quotactl</refentrytitle><manvolnum>2</manvolnum></citerefentry>.
+ Note: <option>isoftlimit</option> and <option>ihardlimit</option>
+ <emphasis>must</emphasis> be set at the same time!
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>ihardlimit=<replaceable>4000</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Hard limit for inodes, as defined by <citerefentry><refentrytitle>
+ quotactl</refentrytitle><manvolnum>2</manvolnum></citerefentry>.
+ Note: <option>isoftlimit</option> and <option>ihardlimit</option>
+ <emphasis>must</emphasis> be set at the same time!
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_setquota-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ Only the <option>session</option> module type is provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_setquota-return_values'>
+ <title>RETURN VALUES</title>
+ <para>
+ <variablelist>
+
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ The quota was set successfully.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ No action was taken because either the UID of the user was outside
+ of the specified range, a quota already existed and
+ <option>overwrite=1</option> was not configured or no limits were
+ configured at all.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ The user was not found.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_PERM_DENIED</term>
+ <listitem>
+ <para>
+ <filename>/proc/mounts</filename> could not be opened.
+ </para>
+ <para>
+ The filesystem or device specified was not found.
+ </para>
+ <para>
+ The limits for the user could not be retrieved. See syslog for
+ more information.
+ </para>
+ <para>
+ The limits for the user could not be set. See syslog for
+ more information.
+ </para>
+ <para>
+ Either <option>isoftlimit</option>/<option>ihardlimit</option>
+ or <option>bsoftlimit</option>/<option>bhardlimit</option> were
+ not set at the same time.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_setquota-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ A single invocation of `pam_setquota` applies a specific policy to a UID
+ range. Applying different policies to specific UID ranges is done by
+ invoking pam_setquota more than once. The last matching entry
+ defines the resulting quota.
+ <programlisting>
+ session required pam_setquota.so bsoftlimit=1000 bhardlimit=2000 isoftlimit=1000 ihardlimit=2000 startuid=1000 enduid=0 fs=/home
+ session required pam_setquota.so bsoftlimit=19000 bhardlimit=20000 isoftlimit=3000 ihardlimit=4000 startuid=2001 enduid=3000 fs=/dev/sda1
+ session required pam_setquota.so bsoftlimit=19000 bhardlimit=20000 isoftlimit=3000 ihardlimit=4000 startuid=3001 enduid=4000 fs=/dev/sda1 overwrite=1
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_setquota-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_setquota-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_setquota was originally written by
+ Ruslan Savchenko &lt;savrus@mexmat.net&gt;.
+ </para>
+ <para>
+ Further modifications were made by Shane Tzen &lt;shane@ict.usc.edu&gt;,
+ Sven Hartge &lt;sven@svenhartge.de&gt;
+ and Keller Fuchs &lt;kellerfuchs@hashbang.sh&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_setquota/pam_setquota.c b/modules/pam_setquota/pam_setquota.c
new file mode 100644
index 0000000..ec45baa
--- /dev/null
+++ b/modules/pam_setquota/pam_setquota.c
@@ -0,0 +1,389 @@
+/* PAM setquota module
+
+ This PAM module sets disk quota when a session begins.
+
+ Copyright © 2006 Ruslan Savchenko <savrus@mexmat.net>
+ Copyright © 2010 Shane Tzen <shane@ict.usc.edu>
+ Copyright © 2012-2020 Sven Hartge <sven@svenhartge.de>
+ Copyright © 2016 Keller Fuchs <kellerfuchs@hashbang.sh>
+*/
+
+#include <sys/types.h>
+#include <sys/quota.h>
+#include <linux/quota.h>
+#include <pwd.h>
+#include <syslog.h>
+#include <errno.h>
+#include <mntent.h>
+#include <stdio.h>
+#include <stdbool.h>
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+#include <security/pam_ext.h>
+#include <security/pam_modutil.h>
+#include "pam_inline.h"
+
+#ifndef PATH_LOGIN_DEFS
+# define PATH_LOGIN_DEFS "/etc/login.defs"
+#endif
+
+#define MAX_UID_VALUE 0xFFFFFFFFUL
+
+struct pam_params {
+ uid_t start_uid;
+ uid_t end_uid;
+ const char *fs;
+ size_t fs_len;
+ int overwrite;
+ int debug;
+};
+
+static inline void
+debug(pam_handle_t *pamh, const struct if_dqblk *p,
+ const char *device, const char *dbgprefix) {
+ pam_syslog(pamh, LOG_DEBUG, "%s device=%s bsoftlimit=%llu bhardlimit=%llu "
+ "isoftlimit=%llu ihardlimit=%llu btime=%llu itime=%llu",
+ dbgprefix, device,
+ (unsigned long long) p->dqb_bsoftlimit,
+ (unsigned long long) p->dqb_bhardlimit,
+ (unsigned long long) p->dqb_isoftlimit,
+ (unsigned long long) p->dqb_ihardlimit,
+ (unsigned long long) p->dqb_btime,
+ (unsigned long long) p->dqb_itime);
+}
+
+static unsigned long long
+str_to_dqb_num(pam_handle_t *pamh, const char *str, const char *param) {
+ char *ep = NULL;
+
+ errno = 0;
+ long long temp = strtoll(str, &ep, 10);
+ if (temp < 0 || str == ep || *ep != '\0' || errno !=0) {
+ pam_syslog(pamh, LOG_ERR, "Parameter \"%s=%s\" invalid, setting to 0", param, str);
+ return 0;
+ }
+ else {
+ return temp;
+ }
+}
+
+static bool
+parse_dqblk(pam_handle_t *pamh, int argc, const char **argv, struct if_dqblk *p) {
+ bool bhard = false, bsoft = false, ihard = false, isoft = false;
+
+ /* step through arguments */
+ for (; argc-- > 0; ++argv) {
+ const char *str;
+ if ((str = pam_str_skip_prefix(*argv, "bhardlimit=")) != NULL) {
+ p->dqb_bhardlimit = str_to_dqb_num(pamh, str, "bhardlimit");
+ p->dqb_valid |= QIF_BLIMITS;
+ bhard = true;
+ } else if ((str = pam_str_skip_prefix(*argv, "bsoftlimit=")) != NULL) {
+ p->dqb_bsoftlimit = str_to_dqb_num(pamh, str, "bsoftlimit");
+ p->dqb_valid |= QIF_BLIMITS;
+ bsoft = true;
+ } else if ((str = pam_str_skip_prefix(*argv, "ihardlimit=")) != NULL) {
+ p->dqb_ihardlimit = str_to_dqb_num(pamh, str, "ihardlimit");
+ p->dqb_valid |= QIF_ILIMITS;
+ ihard = true;
+ } else if ((str = pam_str_skip_prefix(*argv, "isoftlimit=")) != NULL) {
+ p->dqb_isoftlimit = str_to_dqb_num(pamh, str, "isoftlimit");
+ p->dqb_valid |= QIF_ILIMITS;
+ isoft = true;
+ } else if ((str = pam_str_skip_prefix(*argv, "btime=")) != NULL) {
+ p->dqb_btime = str_to_dqb_num(pamh, str, "btime");
+ p->dqb_valid |= QIF_BTIME;
+ } else if ((str = pam_str_skip_prefix(*argv, "itime=")) != NULL) {
+ p->dqb_itime = str_to_dqb_num(pamh, str, "itime");
+ p->dqb_valid |= QIF_ITIME;
+ }
+ }
+
+ /* return FALSE if a softlimit or hardlimit has been set
+ * independently of its counterpart.
+ */
+ return !(bhard ^ bsoft) && !(ihard ^ isoft);
+}
+
+/* inspired by pam_usertype_get_id */
+static uid_t
+str_to_uid(pam_handle_t *pamh, const char *value, uid_t default_value, const char *param) {
+ unsigned long ul;
+ char *ep;
+ uid_t uid;
+
+ errno = 0;
+ ul = strtoul(value, &ep, 10);
+ if (!(ul >= MAX_UID_VALUE
+ || (uid_t)ul >= MAX_UID_VALUE
+ || (errno != 0 && ul == 0)
+ || value == ep
+ || *ep != '\0')) {
+ uid = (uid_t)ul;
+ } else {
+ pam_syslog(pamh, LOG_ERR, "Parameter \"%s=%s\" invalid, "
+ "setting to %u", param, value, default_value);
+ uid = default_value;
+ }
+
+ return uid;
+}
+
+static void
+parse_params(pam_handle_t *pamh, int argc, const char **argv, struct pam_params *p) {
+ /* step through arguments */
+ for (; argc-- > 0; ++argv) {
+ const char *str;
+ char *ep = NULL;
+ if ((str = pam_str_skip_prefix(*argv, "startuid=")) != NULL) {
+ p->start_uid = str_to_uid(pamh, str, p->start_uid, "startuid");
+ } else if ((str = pam_str_skip_prefix(*argv, "enduid=")) != NULL) {
+ p->end_uid = str_to_uid(pamh, str, p->end_uid, "enduid");
+ } else if ((str = pam_str_skip_prefix(*argv, "fs=")) != NULL) {
+ p->fs = str;
+ p->fs_len = strlen(str);
+ /* Mask the unnecessary '/' from the end of fs parameter */
+ if (p->fs_len > 1 && p->fs[p->fs_len - 1] == '/')
+ --p->fs_len;
+ } else if ((str = pam_str_skip_prefix(*argv, "overwrite=")) != NULL) {
+ errno = 0;
+ p->overwrite = strtol(str, &ep, 10);
+ if (*ep != '\0' || str == ep || errno !=0 || (p->overwrite < 0)) {
+ pam_syslog(pamh, LOG_ERR, "Parameter \"overwrite=%s\" invalid, "
+ "setting to 0", str);
+ p->overwrite = 0;
+ }
+ } else if ((str = pam_str_skip_prefix(*argv, "debug=")) != NULL) {
+ errno = 0;
+ p->debug = strtol(str, &ep, 10);
+ if (*ep != '\0' || str == ep || errno != 0 || (p->debug < 0)) {
+ pam_syslog(pamh, LOG_ERR, "Parameter \"debug=%s\" invalid, "
+ "setting to 0", str);
+ p->debug = 0;
+ }
+ }
+ }
+}
+
+int
+pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ int retval;
+ char *val, *mntdevice = NULL;
+ const void *user;
+ const struct passwd *pwd;
+ struct pam_params param = {
+ .start_uid = PAM_USERTYPE_UIDMIN,
+ .end_uid = 0,
+ .fs = NULL };
+ struct if_dqblk ndqblk;
+ FILE *fp;
+ size_t mnt_len = 0, match_size = 0;
+#ifdef HAVE_GETMNTENT_R
+ char buf[BUFSIZ];
+ struct mntent ent;
+#endif
+ const struct mntent *mnt;
+ const char *service;
+
+ if (pam_get_item(pamh, PAM_SERVICE, (const void **)&service) != PAM_SUCCESS)
+ service = "";
+
+ /* Get UID_MIN for default start_uid from login.defs */
+ val = pam_modutil_search_key(pamh, PATH_LOGIN_DEFS, "UID_MIN");
+
+ /* Should UID_MIN be undefined, use current value of param.start_uid
+ * pre-defined as PAM_USERTYPE_UIDMIN set by configure as safe
+ * starting UID to avoid setting a quota for root and system
+ * users if startuid= parameter is absent.
+ */
+ if (val) {
+ param.start_uid = str_to_uid(pamh, val, param.start_uid, PATH_LOGIN_DEFS":UID_MIN");
+ }
+
+ /* Parse parameter values
+ * Must come after pam_modutil_search_key so that the current system
+ * default for UID_MIN is already in p.start_uid to serve as default
+ * for str_to_uid in case of a parse error.
+ * */
+ parse_params(pamh, argc, argv, &param);
+
+ if (param.debug >= 1)
+ pam_syslog(pamh, LOG_DEBUG, "Config: startuid=%u enduid=%u fs=%s "
+ "debug=%d overwrite=%d",
+ param.start_uid, param.end_uid,
+ param.fs ? param.fs : "(none)",
+ param.debug, param.overwrite);
+
+ /* Determine the user name so we can get the home directory */
+ retval = pam_get_item(pamh, PAM_USER, &user);
+ if (retval != PAM_SUCCESS || user == NULL || *(const char *)user == '\0') {
+ pam_syslog(pamh, LOG_NOTICE, "user unknown");
+ return PAM_USER_UNKNOWN;
+ }
+
+ /* Get the password entry */
+ pwd = pam_modutil_getpwnam(pamh, user);
+ if (pwd == NULL) {
+ pam_syslog(pamh, LOG_NOTICE, "user unknown");
+ return PAM_USER_UNKNOWN;
+ }
+
+ /* Check if we should not set quotas for user */
+ if ((pwd->pw_uid < param.start_uid) ||
+ ((param.end_uid >= param.start_uid) && (param.start_uid != 0) &&
+ (pwd->pw_uid > param.end_uid)))
+ return PAM_SUCCESS;
+
+ /* Find out what device the filesystem is hosted on */
+ if ((fp = setmntent("/proc/mounts", "r")) == NULL) {
+ pam_syslog(pamh, LOG_ERR, "Unable to open /proc/mounts");
+ return PAM_PERM_DENIED;
+ }
+
+ while (
+#ifdef HAVE_GETMNTENT_R
+ (mnt = getmntent_r(fp, &ent, buf, sizeof(buf))) != NULL
+#else
+ (mnt = getmntent(fp)) != NULL
+#endif
+ ) {
+ /* If param.fs is not specified use filesystem with users homedir
+ * as default.
+ */
+ if (param.fs == NULL) {
+ /* Mask trailing / from mnt->mnt_dir, to get a leading / on the
+ * remaining suffix returned by pam_str_skip_prefix_len()
+ */
+ for (mnt_len = strlen(mnt->mnt_dir); mnt_len > 0; --mnt_len)
+ if (mnt->mnt_dir[mnt_len - 1] != '/')
+ break;
+ const char *s;
+ if (param.debug >= 2)
+ pam_syslog(pamh, LOG_DEBUG, "Trying to match pw_dir=\"%s\" "
+ "with mnt_dir=\"%s\"", pwd->pw_dir, mnt->mnt_dir);
+ /*
+ * (mnt_len > match_size) Only try matching the mnt_dir if its length
+ * is longer than the last matched length, trying to find the longest
+ * mnt_dir for a given pwd_dir.
+ *
+ * (mnt_len == 0 && mnt->mnt_dir[0] == '/') special-cases the
+ * root-dir /, which is the only mnt_dir with a trailing '/', which
+ * got masked earlier.
+ */
+ if ((mnt_len > match_size || (mnt_len == 0 && mnt->mnt_dir[0] == '/')) &&
+ (s = pam_str_skip_prefix_len(pwd->pw_dir, mnt->mnt_dir, mnt_len)) != NULL &&
+ s[0] == '/') {
+ free(mntdevice);
+ if ((mntdevice = strdup(mnt->mnt_fsname)) == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "Memory allocation error");
+ endmntent(fp);
+ return PAM_PERM_DENIED;
+ }
+ match_size = mnt_len;
+ if (param.debug >= 2)
+ pam_syslog(pamh, LOG_DEBUG, "Found pw_dir=\"%s\" in mnt_dir=\"%s\" "
+ "with suffix=\"%s\" on device=\"%s\"", pwd->pw_dir,
+ mnt->mnt_dir, s, mntdevice);
+ }
+ /* param.fs has been specified, find exactly matching filesystem */
+ } else if ((strncmp(param.fs, mnt->mnt_dir, param.fs_len) == 0
+ && mnt->mnt_dir[param.fs_len] == '\0') ||
+ (strncmp(param.fs, mnt->mnt_fsname, param.fs_len) == 0
+ && mnt->mnt_fsname[param.fs_len] == '\0' )) {
+ free(mntdevice);
+ if ((mntdevice = strdup(mnt->mnt_fsname)) == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "Memory allocation error");
+ endmntent(fp);
+ return PAM_PERM_DENIED;
+ }
+ if (param.debug >= 2)
+ pam_syslog(pamh, LOG_DEBUG, "Found fs=\"%s\" in mnt_dir=\"%s\" "
+ "on device=\"%s\"", param.fs, mnt->mnt_dir, mntdevice);
+ }
+ }
+
+ endmntent(fp);
+
+ if (mntdevice == NULL) {
+ pam_syslog(pamh, LOG_ERR, "Filesystem or device not found: %s", param.fs ? param.fs : pwd->pw_dir);
+ return PAM_PERM_DENIED;
+ }
+
+ /* Get limits */
+ if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), mntdevice, pwd->pw_uid,
+ (void *)&ndqblk) == -1) {
+ pam_syslog(pamh, LOG_ERR, "fail to get limits for user %s : %m",
+ pwd->pw_name);
+ free(mntdevice);
+ return PAM_PERM_DENIED;
+ }
+
+ if (param.debug >= 1)
+ debug(pamh, &ndqblk, mntdevice, "Quota read:");
+
+ /* Only overwrite if quotas aren't already set or if overwrite is set */
+ if ((ndqblk.dqb_bsoftlimit == 0 && ndqblk.dqb_bhardlimit == 0 &&
+ ndqblk.dqb_isoftlimit == 0 && ndqblk.dqb_ihardlimit == 0) ||
+ param.overwrite == 1) {
+
+ /* Parse new limits
+ * Exit with an error should only the hard- or softlimit be
+ * configured but not both.
+ * This avoids errors, inconsistencies and possible race conditions
+ * during setquota.
+ */
+ ndqblk.dqb_valid = 0;
+ if (!parse_dqblk(pamh, argc, argv, &ndqblk)) {
+ pam_syslog(pamh, LOG_ERR,
+ "Both soft- and hardlimits for %s need to be configured "
+ "at the same time!", mntdevice);
+ free(mntdevice);
+ return PAM_PERM_DENIED;
+ }
+
+ /* Nothing changed? Are no limits defined at all in configuration? */
+ if (ndqblk.dqb_valid == 0) {
+ pam_syslog(pamh, LOG_AUTH | LOG_WARNING, "no limits defined in "
+ "configuration for user %s on %s", pwd->pw_name, mntdevice);
+ free(mntdevice);
+ return PAM_IGNORE;
+ }
+
+ /* Set limits */
+ if (quotactl(QCMD(Q_SETQUOTA, USRQUOTA), mntdevice, pwd->pw_uid,
+ (void *)&ndqblk) == -1) {
+ pam_syslog(pamh, LOG_ERR, "failed to set limits for user %s on %s: %m",
+ pwd->pw_name, mntdevice);
+ free(mntdevice);
+ return PAM_PERM_DENIED;
+ }
+ if (param.debug >= 1)
+ debug(pamh, &ndqblk, mntdevice, "Quota set:");
+
+ /* End module */
+ free(mntdevice);
+ return PAM_SUCCESS;
+
+ } else {
+ /* Quota exists and overwrite!=1 */
+ if (param.debug >= 1) {
+ pam_syslog(pamh, LOG_DEBUG, "Quota already exists for user %s "
+ "on %s, not overwriting it without \"overwrite=1\"",
+ pwd->pw_name, mntdevice);
+ }
+ /* End module */
+ free(mntdevice);
+ return PAM_IGNORE;
+ }
+
+}
+
+int
+pam_sm_close_session(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
diff --git a/modules/pam_setquota/tst-pam_setquota b/modules/pam_setquota/tst-pam_setquota
new file mode 100755
index 0000000..f50c958
--- /dev/null
+++ b/modules/pam_setquota/tst-pam_setquota
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_setquota.so
diff --git a/modules/pam_shells/Makefile.am b/modules/pam_shells/Makefile.am
new file mode 100644
index 0000000..b91bada
--- /dev/null
+++ b/modules/pam_shells/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_shells.8
+endif
+XMLS = README.xml pam_shells.8.xml
+dist_check_SCRIPTS = tst-pam_shells
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_shells.la
+pam_shells_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_shells/Makefile.in b/modules/pam_shells/Makefile.in
new file mode 100644
index 0000000..c92648b
--- /dev/null
+++ b/modules/pam_shells/Makefile.in
@@ -0,0 +1,1150 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_shells
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_shells_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_shells_la_SOURCES = pam_shells.c
+pam_shells_la_OBJECTS = pam_shells.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_shells.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_shells.c
+DIST_SOURCES = pam_shells.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_shells.8
+XMLS = README.xml pam_shells.8.xml
+dist_check_SCRIPTS = tst-pam_shells
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_shells.la
+pam_shells_la_LIBADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_shells/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_shells/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_shells.la: $(pam_shells_la_OBJECTS) $(pam_shells_la_DEPENDENCIES) $(EXTRA_pam_shells_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_shells_la_OBJECTS) $(pam_shells_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_shells.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_shells.log: tst-pam_shells
+ @p='tst-pam_shells'; \
+ b='tst-pam_shells'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_shells.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_shells.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_shells/README b/modules/pam_shells/README
new file mode 100644
index 0000000..e09dd20
--- /dev/null
+++ b/modules/pam_shells/README
@@ -0,0 +1,24 @@
+pam_shells — PAM module to check for valid login shell
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+pam_shells is a PAM module that only allows access to the system if the user's
+shell is listed in /etc/shells.
+
+It also checks if /etc/shells is a plain file and not world writable.
+
+OPTIONS
+
+This module does not recognise any options.
+
+EXAMPLES
+
+auth required pam_shells.so
+
+
+AUTHOR
+
+pam_shells was written by Erik Troan <ewt@redhat.com>.
+
diff --git a/modules/pam_shells/README.xml b/modules/pam_shells/README.xml
new file mode 100644
index 0000000..154b97b
--- /dev/null
+++ b/modules/pam_shells/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_shells.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_shells.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_shells-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_shells.8.xml" xpointer='xpointer(//refsect1[@id = "pam_shells-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_shells.8.xml" xpointer='xpointer(//refsect1[@id = "pam_shells-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_shells.8.xml" xpointer='xpointer(//refsect1[@id = "pam_shells-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_shells.8.xml" xpointer='xpointer(//refsect1[@id = "pam_shells-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_shells/pam_shells.8 b/modules/pam_shells/pam_shells.8
new file mode 100644
index 0000000..4e519d1
--- /dev/null
+++ b/modules/pam_shells/pam_shells.8
@@ -0,0 +1,91 @@
+'\" t
+.\" Title: pam_shells
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_SHELLS" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_shells \- PAM module to check for valid login shell
+.SH "SYNOPSIS"
+.HP \w'\fBpam_shells\&.so\fR\ 'u
+\fBpam_shells\&.so\fR
+.SH "DESCRIPTION"
+.PP
+pam_shells is a PAM module that only allows access to the system if the user\*(Aqs shell is listed in
+/etc/shells\&.
+.PP
+It also checks if
+/etc/shells
+is a plain file and not world writable\&.
+.SH "OPTIONS"
+.PP
+This module does not recognise any options\&.
+.SH "MODULE TYPES PROVIDED"
+.PP
+The
+\fBauth\fR
+and
+\fBaccount\fR
+module types are provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_AUTH_ERR
+.RS 4
+Access to the system was denied\&.
+.RE
+.PP
+PAM_SUCCESS
+.RS 4
+The user\*(Aqs login shell was listed as valid shell in
+/etc/shells\&.
+.RE
+.PP
+PAM_SERVICE_ERR
+.RS 4
+The module was not able to get the name of the user\&.
+.RE
+.SH "EXAMPLES"
+.PP
+.if n \{\
+.RS 4
+.\}
+.nf
+auth required pam_shells\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.PP
+\fBshells\fR(5),
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_shells was written by Erik Troan <ewt@redhat\&.com>\&.
diff --git a/modules/pam_shells/pam_shells.8.xml b/modules/pam_shells/pam_shells.8.xml
new file mode 100644
index 0000000..15f4767
--- /dev/null
+++ b/modules/pam_shells/pam_shells.8.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_shells">
+
+ <refmeta>
+ <refentrytitle>pam_shells</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_shells-name">
+ <refname>pam_shells</refname>
+ <refpurpose>PAM module to check for valid login shell</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_shells-cmdsynopsis">
+ <command>pam_shells.so</command>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_shells-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ pam_shells is a PAM module that only allows access to the
+ system if the user's shell is listed in <filename>/etc/shells</filename>.
+ </para>
+ <para>
+ It also checks if <filename>/etc/shells</filename> is a plain
+ file and not world writable.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_shells-options">
+
+ <title>OPTIONS</title>
+ <para> This module does not recognise any options.</para>
+ </refsect1>
+
+ <refsect1 id="pam_shells-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ The <option>auth</option> and <option>account</option>
+ module types are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_shells-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_AUTH_ERR</term>
+ <listitem>
+ <para>
+ Access to the system was denied.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ The user's login shell was listed as valid shell in
+ <filename>/etc/shells</filename>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ The module was not able to get the name of the user.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_shells-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ <programlisting>
+auth required pam_shells.so
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_shells-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>shells</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_shells-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_shells was written by Erik Troan &lt;ewt@redhat.com&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_shells/pam_shells.c b/modules/pam_shells/pam_shells.c
new file mode 100644
index 0000000..dc8f487
--- /dev/null
+++ b/modules/pam_shells/pam_shells.c
@@ -0,0 +1,108 @@
+/*
+ * pam_shells module
+ *
+ * by Erik Troan <ewt@redhat.com>, Red Hat Software.
+ * August 5, 1996.
+ * This code shamelessly ripped from the pam_securetty module.
+ */
+
+#include "config.h"
+
+#include <pwd.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+
+#define SHELL_FILE "/etc/shells"
+
+#define DEFAULT_SHELL "/bin/sh"
+
+static int perform_check(pam_handle_t *pamh)
+{
+ int retval = PAM_AUTH_ERR;
+ const char *userName;
+ const char *userShell;
+ char shellFileLine[256];
+ struct stat sb;
+ struct passwd * pw;
+ FILE * shellFile;
+
+ retval = pam_get_user(pamh, &userName, NULL);
+ if (retval != PAM_SUCCESS) {
+ return PAM_SERVICE_ERR;
+ }
+
+ pw = pam_modutil_getpwnam(pamh, userName);
+ if (pw == NULL || pw->pw_shell == NULL) {
+ return PAM_AUTH_ERR; /* user doesn't exist */
+ }
+ userShell = pw->pw_shell;
+ if (userShell[0] == '\0')
+ userShell = DEFAULT_SHELL;
+
+ if (stat(SHELL_FILE,&sb)) {
+ pam_syslog(pamh, LOG_ERR, "Cannot stat %s: %m", SHELL_FILE);
+ return PAM_AUTH_ERR; /* must have /etc/shells */
+ }
+
+ if ((sb.st_mode & S_IWOTH) || !S_ISREG(sb.st_mode)) {
+ pam_syslog(pamh, LOG_ERR,
+ "%s is either world writable or not a normal file",
+ SHELL_FILE);
+ return PAM_AUTH_ERR;
+ }
+
+ shellFile = fopen(SHELL_FILE,"r");
+ if (shellFile == NULL) { /* Check that we opened it successfully */
+ pam_syslog(pamh, LOG_ERR, "Error opening %s: %m", SHELL_FILE);
+ return PAM_SERVICE_ERR;
+ }
+
+ retval = 1;
+
+ while(retval && (fgets(shellFileLine, 255, shellFile) != NULL)) {
+ if (shellFileLine[strlen(shellFileLine) - 1] == '\n')
+ shellFileLine[strlen(shellFileLine) - 1] = '\0';
+ retval = strcmp(shellFileLine, userShell);
+ }
+
+ fclose(shellFile);
+
+ if (retval) {
+ return PAM_AUTH_ERR;
+ } else {
+ return PAM_SUCCESS;
+ }
+}
+
+/* --- authentication management functions (only) --- */
+
+int pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return perform_check(pamh);
+}
+
+int pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
+
+/* --- account management functions (only) --- */
+
+int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return perform_check(pamh);
+}
+
+/* end of module definition */
diff --git a/modules/pam_shells/tst-pam_shells b/modules/pam_shells/tst-pam_shells
new file mode 100755
index 0000000..dccc33d
--- /dev/null
+++ b/modules/pam_shells/tst-pam_shells
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_shells.so
diff --git a/modules/pam_stress/Makefile.am b/modules/pam_stress/Makefile.am
new file mode 100644
index 0000000..e964fcc
--- /dev/null
+++ b/modules/pam_stress/Makefile.am
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_stress.8
+endif
+XMLS = README.xml pam_stress.8.xml
+dist_check_SCRIPTS = tst-pam_stress
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+securelib_LTLIBRARIES = pam_stress.la
+pam_stress_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_stress/Makefile.in b/modules/pam_stress/Makefile.in
new file mode 100644
index 0000000..297f39d
--- /dev/null
+++ b/modules/pam_stress/Makefile.in
@@ -0,0 +1,1150 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_stress
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_stress_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_stress_la_SOURCES = pam_stress.c
+pam_stress_la_OBJECTS = pam_stress.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_stress.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_stress.c
+DIST_SOURCES = pam_stress.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_stress.8
+XMLS = README.xml pam_stress.8.xml
+dist_check_SCRIPTS = tst-pam_stress
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_stress.la
+pam_stress_la_LIBADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_stress/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_stress/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_stress.la: $(pam_stress_la_OBJECTS) $(pam_stress_la_DEPENDENCIES) $(EXTRA_pam_stress_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_stress_la_OBJECTS) $(pam_stress_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_stress.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_stress.log: tst-pam_stress
+ @p='tst-pam_stress'; \
+ b='tst-pam_stress'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_stress.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_stress.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_stress/README b/modules/pam_stress/README
new file mode 100644
index 0000000..230e862
--- /dev/null
+++ b/modules/pam_stress/README
@@ -0,0 +1,61 @@
+pam_stress — The stress-testing PAM module
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+The pam_stress PAM module is mainly intended to give the impression of failing
+as a fully functioning module might.
+
+OPTIONS
+
+debug
+
+ Put lots of information in syslog. *NOTE* this option writes passwords to
+ syslog, so don't use anything sensitive when testing.
+
+no_warn
+
+ Do not give warnings about things (otherwise warnings are issued via the
+ conversation function)
+
+use_first_pass
+
+ Do not prompt for a password, for pam_sm_authentication function just use
+ item PAM_AUTHTOK.
+
+try_first_pass
+
+ Do not prompt for a password unless there has been no previous
+ authentication token (item PAM_AUTHTOK is NULL)
+
+rootok
+
+ This is intended for the pam_sm_chauthtok function and it instructs this
+ function to permit root to change the user's password without entering the
+ old password.
+
+expired
+
+ An argument intended for the account and chauthtok module parts. It
+ instructs the module to act as if the user's password has expired
+
+fail_1
+
+ This instructs the module to make its first function fail.
+
+fail_2
+
+ This instructs the module to make its second function (if there is one)
+ fail.
+
+prelim
+
+ For pam_sm_chauthtok, means fail on PAM_PRELIM_CHECK.
+
+required
+
+ For pam_sm_chauthtok, means fail if the user hasn't already been
+ authenticated by this module. (See stress_new_pwd data string in the
+ NOTES.)
+
diff --git a/modules/pam_stress/README.xml b/modules/pam_stress/README.xml
new file mode 100644
index 0000000..6f94685
--- /dev/null
+++ b/modules/pam_stress/README.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamstress SYSTEM "pam_stress.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_stress.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_stress-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_stress.8.xml" xpointer='xpointer(//refsect1[@id = "pam_stress-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_stress.8.xml" xpointer='xpointer(//refsect1[@id = "pam_stress-options"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_stress/pam_stress.8 b/modules/pam_stress/pam_stress.8
new file mode 100644
index 0000000..2fdb939
--- /dev/null
+++ b/modules/pam_stress/pam_stress.8
@@ -0,0 +1,190 @@
+'\" t
+.\" Title: pam_stress
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_STRESS" "8" "09/03/2021" "Linux-PAM Manual" "Linux-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_stress \- The stress\-testing PAM module
+.SH "SYNOPSIS"
+.HP \w'\fBpam_stress\&.so\fR\ 'u
+\fBpam_stress\&.so\fR [debug] [no_warn] [use_first_pass] [try_first_pass] [rootok] [expired] [fail_1] [fail_2] [prelim] [required]
+.SH "DESCRIPTION"
+.PP
+The pam_stress PAM module is mainly intended to give the impression of failing as a fully functioning module might\&.
+.SH "OPTIONS"
+.PP
+\fBdebug\fR
+.RS 4
+Put lots of information in syslog\&. *NOTE* this option writes passwords to syslog, so don\*(Aqt use anything sensitive when testing\&.
+.RE
+.PP
+\fBno_warn\fR
+.RS 4
+Do not give warnings about things (otherwise warnings are issued via the conversation function)
+.RE
+.PP
+\fBuse_first_pass\fR
+.RS 4
+Do not prompt for a password, for pam_sm_authentication function just use item PAM_AUTHTOK\&.
+.RE
+.PP
+\fBtry_first_pass\fR
+.RS 4
+Do not prompt for a password unless there has been no previous authentication token (item PAM_AUTHTOK is NULL)
+.RE
+.PP
+\fBrootok\fR
+.RS 4
+This is intended for the pam_sm_chauthtok function and it instructs this function to permit root to change the user\*(Aqs password without entering the old password\&.
+.RE
+.PP
+\fBexpired\fR
+.RS 4
+An argument intended for the account and chauthtok module parts\&. It instructs the module to act as if the user\*(Aqs password has expired
+.RE
+.PP
+\fBfail_1\fR
+.RS 4
+This instructs the module to make its first function fail\&.
+.RE
+.PP
+\fBfail_2\fR
+.RS 4
+This instructs the module to make its second function (if there is one) fail\&.
+.RE
+.PP
+\fBprelim\fR
+.RS 4
+For pam_sm_chauthtok, means fail on PAM_PRELIM_CHECK\&.
+.RE
+.PP
+\fBrequired\fR
+.RS 4
+For pam_sm_chauthtok, means fail if the user hasn\*(Aqt already been authenticated by this module\&. (See stress_new_pwd data string in the NOTES\&.)
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+All module types (\fBauth\fR,
+\fBaccount\fR,
+\fBpassword\fR
+and
+\fBsession\fR) are provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_PERM_DENIED
+.RS 4
+Permission denied\&.
+.RE
+.PP
+PAM_AUTH_ERR
+.RS 4
+Access to the system was denied\&.
+.RE
+.PP
+PAM_CONV_ERR
+.RS 4
+Conversation failure\&.
+.RE
+.PP
+PAM_SUCCESS
+.RS 4
+The function passes all checks\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+The user is not known to the system\&.
+.RE
+.PP
+PAM_CRED_ERR
+.RS 4
+Failure involving user credentials\&.
+.RE
+.PP
+PAM_NEW_AUTHTOK_REQD
+.RS 4
+Authentication token is no longer valid; new one required\&.
+.RE
+.PP
+PAM_SESSION_ERR
+.RS 4
+Session failure\&.
+.RE
+.PP
+PAM_TRY_AGAIN
+.RS 4
+Failed preliminary check by service\&.
+.RE
+.PP
+PAM_AUTHTOK_LOCK_BUSY
+.RS 4
+Authentication token lock busy\&.
+.RE
+.PP
+PAM_AUTHTOK_ERR
+.RS 4
+Authentication token manipulation error\&.
+.RE
+.PP
+PAM_SYSTEM_ERR
+.RS 4
+System error\&.
+.RE
+.SH "NOTES"
+.PP
+This module uses the stress_new_pwd data string which tells pam_sm_chauthtok that pam_sm_acct_mgmt says we need a new password\&. The only possible value for this data string is \*(Aqyes\*(Aq\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+#%PAM\-1\&.0
+#
+# Any of the following will suffice
+account required pam_stress\&.so
+auth required pam_stress\&.so
+password required pam_stress\&.so
+session required pam_stress\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+.PP
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)\&.
+.SH "AUTHORS"
+.PP
+The pam_stress PAM module was developed by Andrew Morgan <morgan@linux\&.kernel\&.org>\&. The man page for pam_stress was written by Lucas Ramage <ramage\&.lucas@protonmail\&.com>\&.
diff --git a/modules/pam_stress/pam_stress.8.xml b/modules/pam_stress/pam_stress.8.xml
new file mode 100644
index 0000000..98888b1
--- /dev/null
+++ b/modules/pam_stress/pam_stress.8.xml
@@ -0,0 +1,356 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+
+<refentry id='pam_stress'>
+
+ <refmeta>
+ <refentrytitle>pam_stress</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id='pam_stress-name'>
+ <refname>pam_stress</refname>
+ <refpurpose>The stress-testing PAM module</refpurpose>
+ </refnamediv>
+
+<!-- body begins here -->
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_stress-cmdsynopsis">
+ <command>pam_stress.so</command>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ no_warn
+ </arg>
+ <arg choice="opt">
+ use_first_pass
+ </arg>
+ <arg choice="opt">
+ try_first_pass
+ </arg>
+ <arg choice="opt">
+ rootok
+ </arg>
+ <arg choice="opt">
+ expired
+ </arg>
+ <arg choice="opt">
+ fail_1
+ </arg>
+ <arg choice="opt">
+ fail_2
+ </arg>
+ <arg choice="opt">
+ prelim
+ </arg>
+ <arg choice="opt">
+ required
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_stress-description">
+ <title>DESCRIPTION</title>
+ <para>
+ The pam_stress PAM module is mainly intended to give the impression of failing as a fully
+functioning module might.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_stress-options">
+ <title>OPTIONS</title>
+ <variablelist>
+
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Put lots of information in syslog.
+ *NOTE* this option writes passwords to syslog, so don't use anything sensitive when testing.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>no_warn</option>
+ </term>
+ <listitem>
+ <para>
+ Do not give warnings about things (otherwise warnings are issued
+ via the conversation function)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>use_first_pass</option>
+ </term>
+ <listitem>
+ <para>
+ Do not prompt for a password, for pam_sm_authentication
+ function just use item PAM_AUTHTOK.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>try_first_pass</option>
+ </term>
+ <listitem>
+ <para>
+ Do not prompt for a password unless there has been no
+ previous authentication token (item PAM_AUTHTOK is NULL)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>rootok</option>
+ </term>
+ <listitem>
+ <para>
+ This is intended for the pam_sm_chauthtok function and
+ it instructs this function to permit root to change
+ the user's password without entering the old password.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>expired</option>
+ </term>
+ <listitem>
+ <para>
+ An argument intended for the account and chauthtok module
+ parts. It instructs the module to act as if the user's
+ password has expired
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>fail_1</option>
+ </term>
+ <listitem>
+ <para>
+ This instructs the module to make its first function fail.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>fail_2</option>
+ </term>
+ <listitem>
+ <para>
+ This instructs the module to make its second function (if there
+ is one) fail.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>prelim</option>
+ </term>
+ <listitem>
+ <para>
+ For pam_sm_chauthtok, means fail on PAM_PRELIM_CHECK.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>required</option>
+ </term>
+ <listitem>
+ <para>
+ For pam_sm_chauthtok, means fail if the user hasn't already
+ been authenticated by this module. (See stress_new_pwd data
+ string in the NOTES.)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_stress-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ All module types (<option>auth</option>, <option>account</option>,
+ <option>password</option> and <option>session</option>) are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_stress-return_values">
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory buffer error.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_PERM_DENIED</term>
+ <listitem>
+ <para>
+ Permission denied.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_AUTH_ERR</term>
+ <listitem>
+ <para>
+ Access to the system was denied.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_CONV_ERR</term>
+ <listitem>
+ <para>
+ Conversation failure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ The function passes all checks.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ The user is not known to the system.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_CRED_ERR</term>
+ <listitem>
+ <para>
+ Failure involving user credentials.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_NEW_AUTHTOK_REQD</term>
+ <listitem>
+ <para>
+ Authentication token is no longer valid; new one required.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SESSION_ERR</term>
+ <listitem>
+ <para>
+ Session failure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_TRY_AGAIN</term>
+ <listitem>
+ <para>
+ Failed preliminary check by service.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_AUTHTOK_LOCK_BUSY</term>
+ <listitem>
+ <para>
+ Authentication token lock busy.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_AUTHTOK_ERR</term>
+ <listitem>
+ <para>
+ Authentication token manipulation error.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SYSTEM_ERR</term>
+ <listitem>
+ <para>
+ System error.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_stress-notes'>
+ <title>NOTES</title>
+ <para>
+ This module uses the stress_new_pwd data string which tells
+ pam_sm_chauthtok that pam_sm_acct_mgmt says we need a new password.
+ The only possible value for this data string is 'yes'.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_stress-examples'>
+ <title>EXAMPLES</title>
+ <programlisting>
+#%PAM-1.0
+#
+# Any of the following will suffice
+account required pam_stress.so
+auth required pam_stress.so
+password required pam_stress.so
+session required pam_stress.so
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id="pam_stress-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_stress-authors">
+ <title>AUTHORS</title>
+ <para>
+ The pam_stress PAM module was developed by
+ Andrew Morgan &lt;morgan@linux.kernel.org&gt;.
+ The man page for pam_stress was written by
+ Lucas Ramage &lt;ramage.lucas@protonmail.com&gt;.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_stress/pam_stress.c b/modules/pam_stress/pam_stress.c
new file mode 100644
index 0000000..6c7a625
--- /dev/null
+++ b/modules/pam_stress/pam_stress.c
@@ -0,0 +1,534 @@
+/*
+ * pam_stress module
+ *
+ * created by Andrew Morgan <morgan@linux.kernel.org> 1996/3/12
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <syslog.h>
+
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+#include <security/pam_ext.h>
+
+/* ---------- */
+
+/* an internal function to turn all possible test arguments into bits
+ of a ctrl number */
+
+/* generic options */
+
+#define PAM_ST_DEBUG 01
+#define PAM_ST_NO_WARN 02
+#define PAM_ST_USE_PASS1 04
+#define PAM_ST_TRY_PASS1 010
+#define PAM_ST_ROOTOK 020
+
+/* simulation options */
+
+#define PAM_ST_EXPIRED 040
+#define PAM_ST_FAIL_1 0100
+#define PAM_ST_FAIL_2 0200
+#define PAM_ST_PRELIM 0400
+#define PAM_ST_REQUIRE_PWD 01000
+
+/* some syslogging */
+
+static void
+_pam_report (const pam_handle_t *pamh, int ctrl, const char *name,
+ int flags, int argc, const char **argv)
+{
+ if (ctrl & PAM_ST_DEBUG) {
+ pam_syslog(pamh, LOG_DEBUG, "CALLED: %s", name);
+ pam_syslog(pamh, LOG_DEBUG, "FLAGS : 0%o%s",
+ flags, (flags & PAM_SILENT) ? " (silent)":"");
+ pam_syslog(pamh, LOG_DEBUG, "CTRL = 0%o", ctrl);
+ pam_syslog(pamh, LOG_DEBUG, "ARGV :");
+ while (argc--) {
+ pam_syslog(pamh, LOG_DEBUG, " \"%s\"", *argv++);
+ }
+ }
+}
+
+static int
+_pam_parse (const pam_handle_t *pamh, int argc, const char **argv)
+{
+ int ctrl=0;
+
+ /* step through arguments */
+ for (ctrl=0; argc-- > 0; ++argv) {
+
+ /* generic options */
+
+ if (!strcmp(*argv,"debug"))
+ ctrl |= PAM_ST_DEBUG;
+ else if (!strcmp(*argv,"no_warn"))
+ ctrl |= PAM_ST_NO_WARN;
+ else if (!strcmp(*argv,"use_first_pass"))
+ ctrl |= PAM_ST_USE_PASS1;
+ else if (!strcmp(*argv,"try_first_pass"))
+ ctrl |= PAM_ST_TRY_PASS1;
+ else if (!strcmp(*argv,"rootok"))
+ ctrl |= PAM_ST_ROOTOK;
+
+ /* simulation options */
+
+ else if (!strcmp(*argv,"expired")) /* signal password needs
+ renewal */
+ ctrl |= PAM_ST_EXPIRED;
+ else if (!strcmp(*argv,"fail_1")) /* instruct fn 1 to fail */
+ ctrl |= PAM_ST_FAIL_1;
+ else if (!strcmp(*argv,"fail_2")) /* instruct fn 2 to fail */
+ ctrl |= PAM_ST_FAIL_2;
+ else if (!strcmp(*argv,"prelim")) /* instruct pam_sm_setcred
+ to fail on first call */
+ ctrl |= PAM_ST_PRELIM;
+ else if (!strcmp(*argv,"required")) /* module is fussy about the
+ user being authenticated */
+ ctrl |= PAM_ST_REQUIRE_PWD;
+
+ else {
+ pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
+ }
+ }
+
+ return ctrl;
+}
+
+static int converse(pam_handle_t *pamh, int nargs
+ , const struct pam_message **message
+ , struct pam_response **response)
+{
+ int retval;
+ const void *void_conv;
+ const struct pam_conv *conv;
+
+ retval = pam_get_item(pamh,PAM_CONV,&void_conv);
+ conv = void_conv;
+ if (retval == PAM_SUCCESS && conv) {
+ retval = conv->conv(nargs, message, response, conv->appdata_ptr);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR, "converse returned %d: %s",
+ retval, pam_strerror(pamh, retval));
+ }
+ } else {
+ pam_syslog(pamh, LOG_ERR, "converse failed to get pam_conv");
+ if (retval == PAM_SUCCESS)
+ retval = PAM_BAD_ITEM; /* conv was null */
+ }
+
+ return retval;
+}
+
+/* authentication management functions */
+
+static int stress_get_password(pam_handle_t *pamh, int flags
+ , int ctrl, char **password)
+{
+ const void *pam_pass;
+ char *pass;
+
+ if ( (ctrl & (PAM_ST_TRY_PASS1|PAM_ST_USE_PASS1))
+ && (pam_get_item(pamh,PAM_AUTHTOK,&pam_pass)
+ == PAM_SUCCESS)
+ && (pam_pass != NULL) ) {
+ if ((pass = strdup(pam_pass)) == NULL)
+ return PAM_BUF_ERR;
+ } else if ((ctrl & PAM_ST_USE_PASS1)) {
+ pam_syslog(pamh, LOG_WARNING, "no forwarded password");
+ return PAM_PERM_DENIED;
+ } else { /* we will have to get one */
+ struct pam_message msg[1];
+ const struct pam_message *pmsg[1];
+ struct pam_response *resp;
+ int retval;
+
+ /* set up conversation call */
+
+ pmsg[0] = &msg[0];
+ msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
+ msg[0].msg = "STRESS Password: ";
+ resp = NULL;
+
+ if ((retval = converse(pamh,1,pmsg,&resp)) != PAM_SUCCESS) {
+ return retval;
+ }
+
+ if (resp) {
+ if ((resp[0].resp == NULL) && (ctrl & PAM_ST_DEBUG)) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "pam_sm_authenticate: NULL authtok given");
+ }
+ if ((flags & PAM_DISALLOW_NULL_AUTHTOK)
+ && resp[0].resp == NULL) {
+ free(resp);
+ return PAM_AUTH_ERR;
+ }
+
+ pass = resp[0].resp; /* remember this! */
+
+ resp[0].resp = NULL;
+ } else {
+ if (ctrl & PAM_ST_DEBUG) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "pam_sm_authenticate: no error reported");
+ pam_syslog(pamh, LOG_DEBUG,
+ "getting password, but NULL returned!?");
+ }
+ return PAM_CONV_ERR;
+ }
+ free(resp);
+ }
+
+ *password = pass; /* this *MUST* be free()'d by this module */
+
+ return PAM_SUCCESS;
+}
+
+/* function to clean up data items */
+
+static void
+wipe_up (pam_handle_t *pamh UNUSED, void *data, int error UNUSED)
+{
+ free(data);
+}
+
+int pam_sm_authenticate(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ const char *username;
+ int retval=PAM_SUCCESS;
+ char *pass;
+ int ctrl;
+
+ D(("called."));
+
+ ctrl = _pam_parse(pamh, argc, argv);
+ _pam_report(pamh, ctrl, "pam_sm_authenticate", flags, argc, argv);
+
+ /* try to get the username */
+
+ retval = pam_get_user(pamh, &username, "username: ");
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE,
+ "pam_sm_authenticate: cannot determine user name: %s",
+ pam_strerror(pamh, retval));
+ return retval;
+ }
+ else if (ctrl & PAM_ST_DEBUG) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "pam_sm_authenticate: username = %s", username);
+ }
+
+ /* now get the password */
+
+ retval = stress_get_password(pamh,flags,ctrl,&pass);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_WARNING,
+ "pam_sm_authenticate: failed to get a password");
+ return retval;
+ }
+
+ /* try to set password item */
+
+ retval = pam_set_item(pamh,PAM_AUTHTOK,pass);
+ _pam_overwrite(pass); /* clean up local copy of password */
+ free(pass);
+ pass = NULL;
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_WARNING,
+ "pam_sm_authenticate: failed to store new password");
+ return retval;
+ }
+
+ /* if we are debugging then we print the password */
+
+ if (ctrl & PAM_ST_DEBUG) {
+ const void *pam_pass;
+ (void) pam_get_item(pamh,PAM_AUTHTOK,&pam_pass);
+ pam_syslog(pamh, LOG_DEBUG,
+ "pam_st_authenticate: password entered is: [%s]",
+ (const char *)pam_pass);
+ }
+
+ /* if we signal a fail for this function then fail */
+
+ if ((ctrl & PAM_ST_FAIL_1) && retval == PAM_SUCCESS)
+ return PAM_PERM_DENIED;
+
+ return retval;
+}
+
+int pam_sm_setcred(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ int ctrl = _pam_parse(pamh, argc, argv);
+
+ D(("called. [post parsing]"));
+
+ _pam_report(pamh, ctrl, "pam_sm_setcred", flags, argc, argv);
+
+ if (ctrl & PAM_ST_FAIL_2)
+ return PAM_CRED_ERR;
+
+ return PAM_SUCCESS;
+}
+
+/* account management functions */
+
+int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ int ctrl = _pam_parse(pamh, argc, argv);
+
+ D(("called. [post parsing]"));
+
+ _pam_report(pamh, ctrl,"pam_sm_acct_mgmt", flags, argc, argv);
+
+ if (ctrl & PAM_ST_FAIL_1)
+ return PAM_PERM_DENIED;
+ else if (ctrl & PAM_ST_EXPIRED) {
+ int retval;
+ void *text = strdup("yes");
+ if (!text)
+ return PAM_BUF_ERR;
+ retval = pam_set_data(pamh,"stress_new_pwd",text,wipe_up);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "pam_sm_acct_mgmt: failed setting stress_new_pwd");
+ free(text);
+ return retval;
+ }
+
+ if (ctrl & PAM_ST_DEBUG) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "pam_sm_acct_mgmt: need a new password");
+ }
+ return PAM_NEW_AUTHTOK_REQD;
+ }
+
+ return PAM_SUCCESS;
+}
+
+int pam_sm_open_session(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ const void *username, *service;
+ int ctrl = _pam_parse(pamh, argc, argv);
+
+ D(("called. [post parsing]"));
+
+ _pam_report(pamh, ctrl,"pam_sm_open_session", flags, argc, argv);
+
+ if ((pam_get_item(pamh, PAM_USER, &username)
+ != PAM_SUCCESS || !username)
+ || (pam_get_item(pamh, PAM_SERVICE, &service)
+ != PAM_SUCCESS || !service)) {
+ pam_syslog(pamh, LOG_WARNING, "pam_sm_open_session: for whom?");
+ return PAM_SESSION_ERR;
+ }
+
+ pam_syslog(pamh, LOG_NOTICE, "opened [%s] session for user [%s]",
+ (const char *)service, (const char *)username);
+
+ if (ctrl & PAM_ST_FAIL_1)
+ return PAM_SESSION_ERR;
+
+ return PAM_SUCCESS;
+}
+
+int pam_sm_close_session(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ const void *username, *service;
+ int ctrl = _pam_parse(pamh, argc, argv);
+
+ D(("called. [post parsing]"));
+
+ _pam_report(pamh, ctrl,"pam_sm_close_session", flags, argc, argv);
+
+ if ((pam_get_item(pamh, PAM_USER, &username)
+ != PAM_SUCCESS || !username)
+ || (pam_get_item(pamh, PAM_SERVICE, &service)
+ != PAM_SUCCESS || !service)) {
+ pam_syslog(pamh, LOG_WARNING, "pam_sm_close_session: for whom?");
+ return PAM_SESSION_ERR;
+ }
+
+ pam_syslog(pamh, LOG_NOTICE, "closed [%s] session for user [%s]",
+ (const char *)service, (const char *)username);
+
+ if (ctrl & PAM_ST_FAIL_2)
+ return PAM_SESSION_ERR;
+
+ return PAM_SUCCESS;
+}
+
+int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ int retval;
+ int ctrl = _pam_parse(pamh, argc, argv);
+
+ D(("called. [post parsing]"));
+
+ _pam_report(pamh, ctrl,"pam_sm_chauthtok", flags, argc, argv);
+
+ /* this function should be called twice by the Linux-PAM library */
+
+ if (flags & PAM_PRELIM_CHECK) { /* first call */
+ if (ctrl & PAM_ST_DEBUG) {
+ pam_syslog(pamh, LOG_DEBUG, "pam_sm_chauthtok: prelim check");
+ }
+ if (ctrl & PAM_ST_PRELIM)
+ return PAM_TRY_AGAIN;
+
+ return PAM_SUCCESS;
+ } else if (flags & PAM_UPDATE_AUTHTOK) { /* second call */
+ struct pam_message msg[3];
+ const struct pam_message *pmsg[3];
+ struct pam_response *resp;
+ const void *text;
+ char *txt=NULL;
+ int i;
+
+ if (ctrl & PAM_ST_DEBUG) {
+ pam_syslog(pamh, LOG_DEBUG, "pam_sm_chauthtok: alter password");
+ }
+
+ if (ctrl & PAM_ST_FAIL_1)
+ return PAM_AUTHTOK_LOCK_BUSY;
+
+ if ( !(ctrl & PAM_ST_EXPIRED)
+ && (flags & PAM_CHANGE_EXPIRED_AUTHTOK)
+ && (pam_get_data(pamh,"stress_new_pwd", &text)
+ != PAM_SUCCESS || strcmp(text,"yes"))) {
+ return PAM_SUCCESS; /* the token has not expired */
+ }
+
+ /* the password should be changed */
+
+ if ((ctrl & PAM_ST_REQUIRE_PWD)
+ && !(getuid() == 0 && (ctrl & PAM_ST_ROOTOK))
+ ) { /* first get old one? */
+ char *pass;
+
+ if (ctrl & PAM_ST_DEBUG) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "pam_sm_chauthtok: getting old password");
+ }
+ retval = stress_get_password(pamh,flags,ctrl,&pass);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "pam_sm_chauthtok: no password obtained");
+ return retval;
+ }
+ retval = pam_set_item(pamh, PAM_OLDAUTHTOK, pass);
+ _pam_overwrite(pass);
+ free(pass);
+ pass = NULL;
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "pam_sm_chauthtok: could not set OLDAUTHTOK");
+ return retval;
+ }
+ }
+
+ /* set up for conversation */
+
+ if (!(flags & PAM_SILENT)) {
+ const void *username;
+
+ if ( pam_get_item(pamh, PAM_USER, &username)
+ || username == NULL ) {
+ pam_syslog(pamh, LOG_ERR, "no username set");
+ return PAM_USER_UNKNOWN;
+ }
+ pmsg[0] = &msg[0];
+ msg[0].msg_style = PAM_TEXT_INFO;
+ if (asprintf(&txt, "Changing STRESS password for %s.",
+ (const char *)username) < 0) {
+ pam_syslog(pamh, LOG_CRIT, "out of memory");
+ return PAM_BUF_ERR;
+ }
+
+ msg[0].msg = txt;
+ i = 1;
+ } else {
+ i = 0;
+ }
+
+ pmsg[i] = &msg[i];
+ msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
+ msg[i++].msg = "Enter new STRESS password: ";
+ pmsg[i] = &msg[i];
+ msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
+ msg[i++].msg = "Retype new STRESS password: ";
+ resp = NULL;
+
+ retval = converse(pamh,i,pmsg,&resp);
+ if (txt) {
+ free(txt);
+ txt = NULL; /* clean up */
+ }
+ if (retval != PAM_SUCCESS) {
+ return retval;
+ }
+
+ if (resp == NULL) {
+ pam_syslog(pamh, LOG_ERR,
+ "pam_sm_chauthtok: no response from conv");
+ return PAM_CONV_ERR;
+ }
+
+ /* store the password */
+
+ if (resp[i-2].resp && resp[i-1].resp) {
+ if (strcmp(resp[i-2].resp,resp[i-1].resp)) {
+ /* passwords are not the same; forget and return error */
+
+ _pam_drop_reply(resp, i);
+
+ if (!(flags & PAM_SILENT) && !(ctrl & PAM_ST_NO_WARN)) {
+ pmsg[0] = &msg[0];
+ msg[0].msg_style = PAM_ERROR_MSG;
+ msg[0].msg = "Verification mis-typed; "
+ "password unchanged";
+ resp = NULL;
+ (void) converse(pamh,1,pmsg,&resp);
+ if (resp) {
+ _pam_drop_reply(resp, 1);
+ }
+ }
+ return PAM_AUTHTOK_ERR;
+ }
+
+ if (pam_get_item(pamh,PAM_AUTHTOK,&text)
+ == PAM_SUCCESS) {
+ (void) pam_set_item(pamh,PAM_OLDAUTHTOK,text);
+ text = NULL;
+ }
+ (void) pam_set_item(pamh,PAM_AUTHTOK,resp[0].resp);
+ } else {
+ pam_syslog(pamh, LOG_DEBUG,
+ "pam_sm_chauthtok: problem with resp");
+ retval = PAM_SYSTEM_ERR;
+ }
+
+ _pam_drop_reply(resp, i); /* clean up the passwords */
+ } else {
+ pam_syslog(pamh, LOG_ERR,
+ "pam_sm_chauthtok: this must be a Linux-PAM error");
+ return PAM_SYSTEM_ERR;
+ }
+
+ return retval;
+}
diff --git a/modules/pam_stress/tst-pam_stress b/modules/pam_stress/tst-pam_stress
new file mode 100755
index 0000000..24be756
--- /dev/null
+++ b/modules/pam_stress/tst-pam_stress
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_stress.so
diff --git a/modules/pam_succeed_if/Makefile.am b/modules/pam_succeed_if/Makefile.am
new file mode 100644
index 0000000..cb54f84
--- /dev/null
+++ b/modules/pam_succeed_if/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_succeed_if.8
+endif
+XMLS = README.xml pam_succeed_if.8.xml
+dist_check_SCRIPTS = tst-pam_succeed_if
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_succeed_if.la
+pam_succeed_if_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_succeed_if/Makefile.in b/modules/pam_succeed_if/Makefile.in
new file mode 100644
index 0000000..995b6db
--- /dev/null
+++ b/modules/pam_succeed_if/Makefile.in
@@ -0,0 +1,1150 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_succeed_if
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_succeed_if_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_succeed_if_la_SOURCES = pam_succeed_if.c
+pam_succeed_if_la_OBJECTS = pam_succeed_if.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_succeed_if.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_succeed_if.c
+DIST_SOURCES = pam_succeed_if.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_succeed_if.8
+XMLS = README.xml pam_succeed_if.8.xml
+dist_check_SCRIPTS = tst-pam_succeed_if
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_succeed_if.la
+pam_succeed_if_la_LIBADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_succeed_if/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_succeed_if/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_succeed_if.la: $(pam_succeed_if_la_OBJECTS) $(pam_succeed_if_la_DEPENDENCIES) $(EXTRA_pam_succeed_if_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_succeed_if_la_OBJECTS) $(pam_succeed_if_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_succeed_if.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_succeed_if.log: tst-pam_succeed_if
+ @p='tst-pam_succeed_if'; \
+ b='tst-pam_succeed_if'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_succeed_if.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_succeed_if.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_succeed_if/README b/modules/pam_succeed_if/README
new file mode 100644
index 0000000..3d2f3d5
--- /dev/null
+++ b/modules/pam_succeed_if/README
@@ -0,0 +1,131 @@
+pam_succeed_if — test account characteristics
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+pam_succeed_if.so is designed to succeed or fail authentication based on
+characteristics of the account belonging to the user being authenticated or
+values of other PAM items. One use is to select whether to load other modules
+based on this test.
+
+The module should be given one or more conditions as module arguments, and
+authentication will succeed only if all of the conditions are met.
+
+OPTIONS
+
+The following flags are supported:
+
+debug
+
+ Turns on debugging messages sent to syslog.
+
+use_uid
+
+ Evaluate conditions using the account of the user whose UID the application
+ is running under instead of the user being authenticated.
+
+quiet
+
+ Don't log failure or success to the system log.
+
+quiet_fail
+
+ Don't log failure to the system log.
+
+quiet_success
+
+ Don't log success to the system log.
+
+audit
+
+ Log unknown users to the system log.
+
+Conditions are three words: a field, a test, and a value to test for.
+
+Available fields are user, uid, gid, shell, home, ruser, rhost, tty and service
+:
+
+field < number
+
+ Field has a value numerically less than number.
+
+field <= number
+
+ Field has a value numerically less than or equal to number.
+
+field eq number
+
+ Field has a value numerically equal to number.
+
+field >= number
+
+ Field has a value numerically greater than or equal to number.
+
+field > number
+
+ Field has a value numerically greater than number.
+
+field ne number
+
+ Field has a value numerically different from number.
+
+field = string
+
+ Field exactly matches the given string.
+
+field != string
+
+ Field does not match the given string.
+
+field =~ glob
+
+ Field matches the given glob.
+
+field !~ glob
+
+ Field does not match the given glob.
+
+field in item:item:...
+
+ Field is contained in the list of items separated by colons.
+
+field notin item:item:...
+
+ Field is not contained in the list of items separated by colons.
+
+user ingroup group[:group:....]
+
+ User is in given group(s).
+
+user notingroup group[:group:....]
+
+ User is not in given group(s).
+
+user innetgr netgroup
+
+ (user,host) is in given netgroup.
+
+user notinnetgr group
+
+ (user,host) is not in given netgroup.
+
+EXAMPLES
+
+To emulate the behaviour of pam_wheel, except there is no fallback to group 0
+being only approximated by checking also the root group membership:
+
+auth required pam_succeed_if.so quiet user ingroup wheel:root
+
+
+Given that the type matches, only loads the othermodule rule if the UID is over
+500. Adjust the number after default to skip several rules.
+
+type [default=1 success=ignore] pam_succeed_if.so quiet uid > 500
+type required othermodule.so arguments...
+
+
+AUTHOR
+
+Nalin Dahyabhai <nalin@redhat.com>
+
diff --git a/modules/pam_succeed_if/README.xml b/modules/pam_succeed_if/README.xml
new file mode 100644
index 0000000..c52f00a
--- /dev/null
+++ b/modules/pam_succeed_if/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_succeed_if.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_succeed_if.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_succeed_if-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_succeed_if.8.xml" xpointer='xpointer(//refsect1[@id = "pam_succeed_if-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_succeed_if.8.xml" xpointer='xpointer(//refsect1[@id = "pam_succeed_if-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_succeed_if.8.xml" xpointer='xpointer(//refsect1[@id = "pam_succeed_if-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_succeed_if.8.xml" xpointer='xpointer(//refsect1[@id = "pam_succeed_if-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_succeed_if/pam_succeed_if.8 b/modules/pam_succeed_if/pam_succeed_if.8
new file mode 100644
index 0000000..8b33c62
--- /dev/null
+++ b/modules/pam_succeed_if/pam_succeed_if.8
@@ -0,0 +1,226 @@
+'\" t
+.\" Title: pam_succeed_if
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM
+.\" Source: Linux-PAM
+.\" Language: English
+.\"
+.TH "PAM_SUCCEED_IF" "8" "09/03/2021" "Linux-PAM" "Linux\-PAM"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_succeed_if \- test account characteristics
+.SH "SYNOPSIS"
+.HP \w'\fBpam_succeed_if\&.so\fR\ 'u
+\fBpam_succeed_if\&.so\fR [\fIflag\fR...] [\fIcondition\fR...]
+.SH "DESCRIPTION"
+.PP
+pam_succeed_if\&.so is designed to succeed or fail authentication based on characteristics of the account belonging to the user being authenticated or values of other PAM items\&. One use is to select whether to load other modules based on this test\&.
+.PP
+The module should be given one or more conditions as module arguments, and authentication will succeed only if all of the conditions are met\&.
+.SH "OPTIONS"
+.PP
+The following
+\fIflag\fRs are supported:
+.PP
+\fBdebug\fR
+.RS 4
+Turns on debugging messages sent to syslog\&.
+.RE
+.PP
+\fBuse_uid\fR
+.RS 4
+Evaluate conditions using the account of the user whose UID the application is running under instead of the user being authenticated\&.
+.RE
+.PP
+\fBquiet\fR
+.RS 4
+Don\*(Aqt log failure or success to the system log\&.
+.RE
+.PP
+\fBquiet_fail\fR
+.RS 4
+Don\*(Aqt log failure to the system log\&.
+.RE
+.PP
+\fBquiet_success\fR
+.RS 4
+Don\*(Aqt log success to the system log\&.
+.RE
+.PP
+\fBaudit\fR
+.RS 4
+Log unknown users to the system log\&.
+.RE
+.PP
+\fICondition\fRs are three words: a field, a test, and a value to test for\&.
+.PP
+Available fields are
+\fIuser\fR,
+\fIuid\fR,
+\fIgid\fR,
+\fIshell\fR,
+\fIhome\fR,
+\fIruser\fR,
+\fIrhost\fR,
+\fItty\fR
+and
+\fIservice\fR:
+.PP
+\fBfield < number\fR
+.RS 4
+Field has a value numerically less than number\&.
+.RE
+.PP
+\fBfield <= number\fR
+.RS 4
+Field has a value numerically less than or equal to number\&.
+.RE
+.PP
+\fBfield eq number\fR
+.RS 4
+Field has a value numerically equal to number\&.
+.RE
+.PP
+\fBfield >= number\fR
+.RS 4
+Field has a value numerically greater than or equal to number\&.
+.RE
+.PP
+\fBfield > number\fR
+.RS 4
+Field has a value numerically greater than number\&.
+.RE
+.PP
+\fBfield ne number\fR
+.RS 4
+Field has a value numerically different from number\&.
+.RE
+.PP
+\fBfield = string\fR
+.RS 4
+Field exactly matches the given string\&.
+.RE
+.PP
+\fBfield != string\fR
+.RS 4
+Field does not match the given string\&.
+.RE
+.PP
+\fBfield =~ glob\fR
+.RS 4
+Field matches the given glob\&.
+.RE
+.PP
+\fBfield !~ glob\fR
+.RS 4
+Field does not match the given glob\&.
+.RE
+.PP
+\fBfield in item:item:\&.\&.\&.\fR
+.RS 4
+Field is contained in the list of items separated by colons\&.
+.RE
+.PP
+\fBfield notin item:item:\&.\&.\&.\fR
+.RS 4
+Field is not contained in the list of items separated by colons\&.
+.RE
+.PP
+\fBuser ingroup group[:group:\&.\&.\&.\&.]\fR
+.RS 4
+User is in given group(s)\&.
+.RE
+.PP
+\fBuser notingroup group[:group:\&.\&.\&.\&.]\fR
+.RS 4
+User is not in given group(s)\&.
+.RE
+.PP
+\fBuser innetgr netgroup\fR
+.RS 4
+(user,host) is in given netgroup\&.
+.RE
+.PP
+\fBuser notinnetgr group\fR
+.RS 4
+(user,host) is not in given netgroup\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+All module types (\fBaccount\fR,
+\fBauth\fR,
+\fBpassword\fR
+and
+\fBsession\fR) are provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_SUCCESS
+.RS 4
+The condition was true\&.
+.RE
+.PP
+PAM_AUTH_ERR
+.RS 4
+The condition was false\&.
+.RE
+.PP
+PAM_SERVICE_ERR
+.RS 4
+A service error occurred or the arguments can\*(Aqt be parsed correctly\&.
+.RE
+.SH "EXAMPLES"
+.PP
+To emulate the behaviour of
+\fIpam_wheel\fR, except there is no fallback to group 0 being only approximated by checking also the root group membership:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+auth required pam_succeed_if\&.so quiet user ingroup wheel:root
+
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Given that the type matches, only loads the othermodule rule if the UID is over 500\&. Adjust the number after default to skip several rules\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+type [default=1 success=ignore] pam_succeed_if\&.so quiet uid > 500
+type required othermodule\&.so arguments\&.\&.\&.
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+.PP
+\fBglob\fR(7),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+Nalin Dahyabhai <nalin@redhat\&.com>
diff --git a/modules/pam_succeed_if/pam_succeed_if.8.xml b/modules/pam_succeed_if/pam_succeed_if.8.xml
new file mode 100644
index 0000000..14d939a
--- /dev/null
+++ b/modules/pam_succeed_if/pam_succeed_if.8.xml
@@ -0,0 +1,307 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+
+<refentry id='pam_succeed_if'>
+<!-- Copyright 2003, 2004 Red Hat, Inc. -->
+<!-- Written by Nalin Dahyabhai &lt;nalin@redhat.com&gt; -->
+
+ <refmeta>
+ <refentrytitle>pam_succeed_if</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class='sectdesc'>Linux-PAM</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id='pam_succeed_if-name'>
+ <refname>pam_succeed_if</refname>
+ <refpurpose>test account characteristics</refpurpose>
+ </refnamediv>
+
+
+ <refsynopsisdiv>
+ <cmdsynopsis id='pam_succeed_if-cmdsynopsis'>
+ <command>pam_succeed_if.so</command>
+ <arg choice='opt' rep='repeat'><replaceable>flag</replaceable></arg>
+ <arg choice='opt' rep='repeat'><replaceable>condition</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1 id='pam_succeed_if-description'>
+ <title>DESCRIPTION</title>
+ <para>
+ pam_succeed_if.so is designed to succeed or fail authentication
+ based on characteristics of the account belonging to the user being
+ authenticated or values of other PAM items. One use is to select whether
+ to load other modules based on this test.
+ </para>
+
+ <para>
+ The module should be given one or more conditions as module arguments,
+ and authentication will succeed only if all of the conditions are met.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_succeed_if-options">
+ <title>OPTIONS</title>
+ <para>
+ The following <emphasis>flag</emphasis>s are supported:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>debug</option></term>
+ <listitem>
+ <para>Turns on debugging messages sent to syslog.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>use_uid</option></term>
+ <listitem>
+ <para>
+ Evaluate conditions using the account of the user whose UID
+ the application is running under instead of the user being
+ authenticated.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>quiet</option></term>
+ <listitem>
+ <para>Don't log failure or success to the system log.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>quiet_fail</option></term>
+ <listitem>
+ <para>
+ Don't log failure to the system log.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>quiet_success</option></term>
+ <listitem>
+ <para>
+ Don't log success to the system log.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>audit</option></term>
+ <listitem>
+ <para>
+ Log unknown users to the system log.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ <emphasis>Condition</emphasis>s are three words: a field, a test,
+ and a value to test for.
+ </para>
+ <para>
+ Available fields are <emphasis>user</emphasis>,
+ <emphasis>uid</emphasis>, <emphasis>gid</emphasis>,
+ <emphasis>shell</emphasis>, <emphasis>home</emphasis>,
+ <emphasis>ruser</emphasis>, <emphasis>rhost</emphasis>,
+ <emphasis>tty</emphasis> and <emphasis>service</emphasis>:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>field &lt; number</option></term>
+ <listitem>
+ <para>Field has a value numerically less than number.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>field &lt;= number</option></term>
+ <listitem>
+ <para>
+ Field has a value numerically less than or equal to number.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>field eq number</option></term>
+ <listitem>
+ <para>
+ Field has a value numerically equal to number.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>field &gt;= number</option></term>
+ <listitem>
+ <para>
+ Field has a value numerically greater than or equal to number.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>field &gt; number</option></term>
+ <listitem>
+ <para>
+ Field has a value numerically greater than number.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>field ne number</option></term>
+ <listitem>
+ <para>
+ Field has a value numerically different from number.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>field = string</option></term>
+ <listitem>
+ <para>
+ Field exactly matches the given string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>field != string</option></term>
+ <listitem>
+ <para>
+ Field does not match the given string.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>field =~ glob</option></term>
+ <listitem>
+ <para>Field matches the given glob.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>field !~ glob</option></term>
+ <listitem>
+ <para>Field does not match the given glob.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>field in item:item:...</option></term>
+ <listitem>
+ <para>Field is contained in the list of items separated by colons.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>field notin item:item:...</option></term>
+ <listitem>
+ <para>Field is not contained in the list of items separated by colons.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>user ingroup group[:group:....]</option></term>
+ <listitem>
+ <para>User is in given group(s).</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>user notingroup group[:group:....]</option></term>
+ <listitem>
+ <para>User is not in given group(s).</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>user innetgr netgroup</option></term>
+ <listitem>
+ <para>(user,host) is in given netgroup.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>user notinnetgr group</option></term>
+ <listitem>
+ <para>(user,host) is not in given netgroup.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_succeed_if-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ All module types (<option>account</option>, <option>auth</option>,
+ <option>password</option> and <option>session</option>) are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_succeed_if-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ The condition was true.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_AUTH_ERR</term>
+ <listitem>
+ <para>
+ The condition was false.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ A service error occurred or the arguments can't be
+ parsed correctly.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+
+ <refsect1 id='pam_succeed_if-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ To emulate the behaviour of <emphasis>pam_wheel</emphasis>, except
+ there is no fallback to group 0 being only approximated by checking also the root group membership:
+ </para>
+ <programlisting>
+auth required pam_succeed_if.so quiet user ingroup wheel:root
+ </programlisting>
+
+ <para>
+ Given that the type matches, only loads the othermodule rule if
+ the UID is over 500. Adjust the number after default to skip
+ several rules.
+ </para>
+ <programlisting>
+type [default=1 success=ignore] pam_succeed_if.so quiet uid &gt; 500
+type required othermodule.so arguments...
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id='pam_succeed_if-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>glob</refentrytitle><manvolnum>7</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_succeed_if-author'>
+ <title>AUTHOR</title>
+ <para>Nalin Dahyabhai &lt;nalin@redhat.com&gt;</para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_succeed_if/pam_succeed_if.c b/modules/pam_succeed_if/pam_succeed_if.c
new file mode 100644
index 0000000..7103ae3
--- /dev/null
+++ b/modules/pam_succeed_if/pam_succeed_if.c
@@ -0,0 +1,618 @@
+/******************************************************************************
+ * A simple user-attribute based module for PAM.
+ *
+ * Copyright (c) 2003 Red Hat, Inc.
+ * Written by Nalin Dahyabhai <nalin@redhat.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <fnmatch.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+#include <netdb.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+
+/* Basically, run cmp(atol(left), atol(right)), returning PAM_SUCCESS if
+ * the function returns non-zero, PAM_AUTH_ERR if it returns zero, and
+ * PAM_SERVICE_ERR if the arguments can't be parsed as numbers. */
+static int
+evaluate_num(const pam_handle_t *pamh, const char *left,
+ const char *right, int (*cmp)(long long, long long))
+{
+ long long l, r;
+ char *p;
+ int ret = PAM_SUCCESS;
+
+ errno = 0;
+ l = strtoll(left, &p, 0);
+ if ((p == NULL) || (*p != '\0') || errno) {
+ pam_syslog(pamh, LOG_INFO, "\"%s\" is not a number", left);
+ ret = PAM_SERVICE_ERR;
+ }
+
+ r = strtoll(right, &p, 0);
+ if ((p == NULL) || (*p != '\0') || errno) {
+ pam_syslog(pamh, LOG_INFO, "\"%s\" is not a number", right);
+ ret = PAM_SERVICE_ERR;
+ }
+
+ if (ret != PAM_SUCCESS) {
+ return ret;
+ }
+
+ return cmp(l, r) ? PAM_SUCCESS : PAM_AUTH_ERR;
+}
+
+/* Simple numeric comparison callbacks. */
+static int
+eq(long long i, long long j)
+{
+ return i == j;
+}
+static int
+ne(long long i, long long j)
+{
+ return i != j;
+}
+static int
+lt(long long i, long long j)
+{
+ return i < j;
+}
+static int
+le(long long i, long long j)
+{
+ return lt(i, j) || eq(i, j);
+}
+static int
+gt(long long i, long long j)
+{
+ return i > j;
+}
+static int
+ge(long long i, long long j)
+{
+ return gt(i, j) || eq(i, j);
+}
+
+/* Test for numeric equality. */
+static int
+evaluate_eqn(const pam_handle_t *pamh, const char *left, const char *right)
+{
+ return evaluate_num(pamh, left, right, eq);
+}
+/* Test for string equality. */
+static int
+evaluate_eqs(const char *left, const char *right)
+{
+ return (strcmp(left, right) == 0) ? PAM_SUCCESS : PAM_AUTH_ERR;
+}
+/* Test for numeric inequality. */
+static int
+evaluate_nen(const pam_handle_t *pamh, const char *left, const char *right)
+{
+ return evaluate_num(pamh, left, right, ne);
+}
+/* Test for string inequality. */
+static int
+evaluate_nes(const char *left, const char *right)
+{
+ return (strcmp(left, right) != 0) ? PAM_SUCCESS : PAM_AUTH_ERR;
+}
+/* Test for numeric less-than-ness(?) */
+static int
+evaluate_lt(const pam_handle_t *pamh, const char *left, const char *right)
+{
+ return evaluate_num(pamh, left, right, lt);
+}
+/* Test for numeric less-than-or-equal-ness(?) */
+static int
+evaluate_le(const pam_handle_t *pamh, const char *left, const char *right)
+{
+ return evaluate_num(pamh, left, right, le);
+}
+/* Test for numeric greater-than-ness(?) */
+static int
+evaluate_gt(const pam_handle_t *pamh, const char *left, const char *right)
+{
+ return evaluate_num(pamh, left, right, gt);
+}
+/* Test for numeric greater-than-or-equal-ness(?) */
+static int
+evaluate_ge(const pam_handle_t *pamh, const char *left, const char *right)
+{
+ return evaluate_num(pamh, left, right, ge);
+}
+/* Check for file glob match. */
+static int
+evaluate_glob(const char *left, const char *right)
+{
+ return (fnmatch(right, left, 0) == 0) ? PAM_SUCCESS : PAM_AUTH_ERR;
+}
+/* Check for file glob mismatch. */
+static int
+evaluate_noglob(const char *left, const char *right)
+{
+ return (fnmatch(right, left, 0) != 0) ? PAM_SUCCESS : PAM_AUTH_ERR;
+}
+/* Check for list match. */
+static int
+evaluate_inlist(const char *left, const char *right)
+{
+ char *p;
+ /* Don't care about left containing ':'. */
+ while ((p=strstr(right, left)) != NULL) {
+ if (p == right || *(p-1) == ':') { /* ':' is a list separator */
+ p += strlen(left);
+ if (*p == '\0' || *p == ':') {
+ return PAM_SUCCESS;
+ }
+ }
+ right = strchr(p, ':');
+ if (right == NULL)
+ break;
+ else
+ ++right;
+ }
+ return PAM_AUTH_ERR;
+}
+/* Check for list mismatch. */
+static int
+evaluate_notinlist(const char *left, const char *right)
+{
+ return evaluate_inlist(left, right) != PAM_SUCCESS ? PAM_SUCCESS : PAM_AUTH_ERR;
+}
+/* Return PAM_SUCCESS if the user is in the group. */
+static int
+evaluate_ingroup(pam_handle_t *pamh, const char *user, const char *grouplist)
+{
+ char *ptr = NULL;
+ static const char delim[] = ":";
+ char const *grp = NULL;
+ char *group = strdup(grouplist);
+
+ if (group == NULL)
+ return PAM_BUF_ERR;
+
+ grp = strtok_r(group, delim, &ptr);
+ while(grp != NULL) {
+ if (pam_modutil_user_in_group_nam_nam(pamh, user, grp) == 1) {
+ free(group);
+ return PAM_SUCCESS;
+ }
+ grp = strtok_r(NULL, delim, &ptr);
+ }
+ free(group);
+ return PAM_AUTH_ERR;
+}
+/* Return PAM_SUCCESS if the user is NOT in the group. */
+static int
+evaluate_notingroup(pam_handle_t *pamh, const char *user, const char *grouplist)
+{
+ char *ptr = NULL;
+ static const char delim[] = ":";
+ char const *grp = NULL;
+ char *group = strdup(grouplist);
+
+ if (group == NULL)
+ return PAM_BUF_ERR;
+
+ grp = strtok_r(group, delim, &ptr);
+ while(grp != NULL) {
+ if (pam_modutil_user_in_group_nam_nam(pamh, user, grp) == 1) {
+ free(group);
+ return PAM_AUTH_ERR;
+ }
+ grp = strtok_r(NULL, delim, &ptr);
+ }
+ free(group);
+ return PAM_SUCCESS;
+}
+
+#ifdef HAVE_INNETGR
+# define SOMETIMES_UNUSED UNUSED
+#else
+# define SOMETIMES_UNUSED
+#endif
+
+/* Return PAM_SUCCESS if the (host,user) is in the netgroup. */
+static int
+evaluate_innetgr(const pam_handle_t* pamh SOMETIMES_UNUSED, const char *host, const char *user, const char *group)
+{
+#ifdef HAVE_INNETGR
+ if (innetgr(group, host, user, NULL) == 1)
+ return PAM_SUCCESS;
+#else
+ pam_syslog (pamh, LOG_ERR, "pam_succeed_if does not have netgroup support");
+#endif
+
+ return PAM_AUTH_ERR;
+}
+/* Return PAM_SUCCESS if the (host,user) is NOT in the netgroup. */
+static int
+evaluate_notinnetgr(const pam_handle_t* pamh SOMETIMES_UNUSED, const char *host, const char *user, const char *group)
+{
+#ifdef HAVE_INNETGR
+ if (innetgr(group, host, user, NULL) == 0)
+ return PAM_SUCCESS;
+#else
+ pam_syslog (pamh, LOG_ERR, "pam_succeed_if does not have netgroup support");
+#endif
+ return PAM_AUTH_ERR;
+}
+
+/* Match a triple. */
+static int
+evaluate(pam_handle_t *pamh, int debug,
+ const char *left, const char *qual, const char *right,
+ struct passwd **pwd, const char *user)
+{
+ char buf[LINE_MAX] = "";
+ const char *attribute = left;
+ /* Figure out what we're evaluating here, and convert it to a string.*/
+ if ((strcasecmp(left, "login") == 0) ||
+ (strcasecmp(left, "name") == 0) ||
+ (strcasecmp(left, "user") == 0)) {
+ snprintf(buf, sizeof(buf), "%s", user);
+ left = buf;
+ }
+ /* Get information about the user if needed. */
+ if ((*pwd == NULL) &&
+ ((strcasecmp(left, "uid") == 0) ||
+ (strcasecmp(left, "gid") == 0) ||
+ (strcasecmp(left, "shell") == 0) ||
+ (strcasecmp(left, "home") == 0) ||
+ (strcasecmp(left, "dir") == 0) ||
+ (strcasecmp(left, "homedir") == 0))) {
+ *pwd = pam_modutil_getpwnam(pamh, user);
+ if (*pwd == NULL) {
+ return PAM_USER_UNKNOWN;
+ }
+ }
+ if (strcasecmp(left, "uid") == 0) {
+ snprintf(buf, sizeof(buf), "%lu", (unsigned long) (*pwd)->pw_uid);
+ left = buf;
+ }
+ if (strcasecmp(left, "gid") == 0) {
+ snprintf(buf, sizeof(buf), "%lu", (unsigned long) (*pwd)->pw_gid);
+ left = buf;
+ }
+ if (strcasecmp(left, "shell") == 0) {
+ snprintf(buf, sizeof(buf), "%s", (*pwd)->pw_shell);
+ left = buf;
+ }
+ if ((strcasecmp(left, "home") == 0) ||
+ (strcasecmp(left, "dir") == 0) ||
+ (strcasecmp(left, "homedir") == 0)) {
+ snprintf(buf, sizeof(buf), "%s", (*pwd)->pw_dir);
+ left = buf;
+ }
+ if (strcasecmp(left, "service") == 0) {
+ const void *svc;
+ if (pam_get_item(pamh, PAM_SERVICE, &svc) != PAM_SUCCESS ||
+ svc == NULL)
+ svc = "";
+ snprintf(buf, sizeof(buf), "%s", (const char *)svc);
+ left = buf;
+ }
+ if (strcasecmp(left, "ruser") == 0) {
+ const void *ruser;
+ if (pam_get_item(pamh, PAM_RUSER, &ruser) != PAM_SUCCESS ||
+ ruser == NULL)
+ ruser = "";
+ snprintf(buf, sizeof(buf), "%s", (const char *)ruser);
+ left = buf;
+ user = buf;
+ }
+ if (strcasecmp(left, "rhost") == 0) {
+ const void *rhost;
+ if (pam_get_item(pamh, PAM_RHOST, &rhost) != PAM_SUCCESS ||
+ rhost == NULL)
+ rhost = "";
+ snprintf(buf, sizeof(buf), "%s", (const char *)rhost);
+ left = buf;
+ }
+ if (strcasecmp(left, "tty") == 0) {
+ const void *tty;
+ if (pam_get_item(pamh, PAM_TTY, &tty) != PAM_SUCCESS ||
+ tty == NULL)
+ tty = "";
+ snprintf(buf, sizeof(buf), "%s", (const char *)tty);
+ left = buf;
+ }
+ /* If we have no idea what's going on, return an error. */
+ if (left != buf) {
+ pam_syslog(pamh, LOG_ERR, "unknown attribute \"%s\"", left);
+ return PAM_SERVICE_ERR;
+ }
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG, "'%s' resolves to '%s'",
+ attribute, left);
+ }
+
+ /* Attribute value < some threshold. */
+ if ((strcasecmp(qual, "<") == 0) ||
+ (strcasecmp(qual, "lt") == 0)) {
+ return evaluate_lt(pamh, left, right);
+ }
+ /* Attribute value <= some threshold. */
+ if ((strcasecmp(qual, "<=") == 0) ||
+ (strcasecmp(qual, "le") == 0)) {
+ return evaluate_le(pamh, left, right);
+ }
+ /* Attribute value > some threshold. */
+ if ((strcasecmp(qual, ">") == 0) ||
+ (strcasecmp(qual, "gt") == 0)) {
+ return evaluate_gt(pamh, left, right);
+ }
+ /* Attribute value >= some threshold. */
+ if ((strcasecmp(qual, ">=") == 0) ||
+ (strcasecmp(qual, "ge") == 0)) {
+ return evaluate_ge(pamh, left, right);
+ }
+ /* Attribute value == some threshold. */
+ if (strcasecmp(qual, "eq") == 0) {
+ return evaluate_eqn(pamh, left, right);
+ }
+ /* Attribute value = some string. */
+ if (strcasecmp(qual, "=") == 0) {
+ return evaluate_eqs(left, right);
+ }
+ /* Attribute value != some threshold. */
+ if (strcasecmp(qual, "ne") == 0) {
+ return evaluate_nen(pamh, left, right);
+ }
+ /* Attribute value != some string. */
+ if (strcasecmp(qual, "!=") == 0) {
+ return evaluate_nes(left, right);
+ }
+ /* Attribute value matches some pattern. */
+ if ((strcasecmp(qual, "=~") == 0) ||
+ (strcasecmp(qual, "glob") == 0)) {
+ return evaluate_glob(left, right);
+ }
+ if ((strcasecmp(qual, "!~") == 0) ||
+ (strcasecmp(qual, "noglob") == 0)) {
+ return evaluate_noglob(left, right);
+ }
+ /* Attribute value matches item in list. */
+ if (strcasecmp(qual, "in") == 0) {
+ return evaluate_inlist(left, right);
+ }
+ if (strcasecmp(qual, "notin") == 0) {
+ return evaluate_notinlist(left, right);
+ }
+ /* User is in this group(s). */
+ if (strcasecmp(qual, "ingroup") == 0) {
+ return evaluate_ingroup(pamh, user, right);
+ }
+ /* User is not in this group(s). */
+ if (strcasecmp(qual, "notingroup") == 0) {
+ return evaluate_notingroup(pamh, user, right);
+ }
+ /* (Rhost, user) is in this netgroup. */
+ if (strcasecmp(qual, "innetgr") == 0) {
+ const void *rhost;
+ if (pam_get_item(pamh, PAM_RHOST, &rhost) != PAM_SUCCESS)
+ rhost = NULL;
+ return evaluate_innetgr(pamh, rhost, user, right);
+ }
+ /* (Rhost, user) is not in this group. */
+ if (strcasecmp(qual, "notinnetgr") == 0) {
+ const void *rhost;
+ if (pam_get_item(pamh, PAM_RHOST, &rhost) != PAM_SUCCESS)
+ rhost = NULL;
+ return evaluate_notinnetgr(pamh, rhost, user, right);
+ }
+ /* Fail closed. */
+ return PAM_SERVICE_ERR;
+}
+
+int
+pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ const char *user;
+ struct passwd *pwd = NULL;
+ int ret, i, count, use_uid, debug;
+ const char *left, *right, *qual;
+ int quiet_fail, quiet_succ, audit;
+
+ quiet_fail = 0;
+ quiet_succ = 0;
+ audit = 0;
+ for (use_uid = 0, debug = 0, i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "debug") == 0) {
+ debug++;
+ }
+ if (strcmp(argv[i], "use_uid") == 0) {
+ use_uid++;
+ }
+ if (strcmp(argv[i], "quiet") == 0) {
+ quiet_fail++;
+ quiet_succ++;
+ }
+ if (strcmp(argv[i], "quiet_fail") == 0) {
+ quiet_fail++;
+ }
+ if (strcmp(argv[i], "quiet_success") == 0) {
+ quiet_succ++;
+ }
+ if (strcmp(argv[i], "audit") == 0) {
+ audit++;
+ }
+ }
+
+ if (use_uid) {
+ /* Get information about the user. */
+ pwd = pam_modutil_getpwuid(pamh, getuid());
+ if (pwd == NULL) {
+ pam_syslog(pamh, LOG_ERR,
+ "error retrieving information about user %lu",
+ (unsigned long)getuid());
+ return PAM_USER_UNKNOWN;
+ }
+ user = pwd->pw_name;
+ } else {
+ /* Get the user's name. */
+ ret = pam_get_user(pamh, &user, NULL);
+ if (ret != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE,
+ "cannot determine user name: %s",
+ pam_strerror(pamh, ret));
+ return ret;
+ }
+
+ /* Postpone requesting password data until it is needed */
+ }
+
+ /* Walk the argument list. */
+ count = 0;
+ left = qual = right = NULL;
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "debug") == 0) {
+ continue;
+ }
+ if (strcmp(argv[i], "use_uid") == 0) {
+ continue;
+ }
+ if (strcmp(argv[i], "quiet") == 0) {
+ continue;
+ }
+ if (strcmp(argv[i], "quiet_fail") == 0) {
+ continue;
+ }
+ if (strcmp(argv[i], "quiet_success") == 0) {
+ continue;
+ }
+ if (strcmp(argv[i], "audit") == 0) {
+ continue;
+ }
+ if (left == NULL) {
+ left = argv[i];
+ continue;
+ }
+ if (qual == NULL) {
+ qual = argv[i];
+ continue;
+ }
+ if (right == NULL) {
+ right = argv[i];
+ if (right == NULL)
+ continue;
+
+ count++;
+ ret = evaluate(pamh, debug,
+ left, qual, right,
+ &pwd, user);
+ if (ret == PAM_USER_UNKNOWN && audit)
+ pam_syslog(pamh, LOG_NOTICE,
+ "error retrieving information about user %s",
+ user);
+ if (ret != PAM_SUCCESS) {
+ if(!quiet_fail && ret != PAM_USER_UNKNOWN)
+ pam_syslog(pamh, LOG_INFO,
+ "requirement \"%s %s %s\" "
+ "not met by user \"%s\"",
+ left, qual, right, user);
+ left = qual = right = NULL;
+ break;
+ }
+ else
+ if(!quiet_succ)
+ pam_syslog(pamh, LOG_INFO,
+ "requirement \"%s %s %s\" "
+ "was met by user \"%s\"",
+ left, qual, right, user);
+ left = qual = right = NULL;
+ continue;
+ }
+ }
+
+ if (left || qual || right) {
+ ret = PAM_SERVICE_ERR;
+ pam_syslog(pamh, LOG_ERR,
+ "incomplete condition detected");
+ } else if (count == 0) {
+ pam_syslog(pamh, LOG_INFO,
+ "no condition detected; module succeeded");
+ }
+
+ return ret;
+}
+
+int
+pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_IGNORE;
+}
+
+int
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+int
+pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+int
+pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+int
+pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
diff --git a/modules/pam_succeed_if/tst-pam_succeed_if b/modules/pam_succeed_if/tst-pam_succeed_if
new file mode 100755
index 0000000..f2b6dd3
--- /dev/null
+++ b/modules/pam_succeed_if/tst-pam_succeed_if
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_succeed_if.so
diff --git a/modules/pam_time/Makefile.am b/modules/pam_time/Makefile.am
new file mode 100644
index 0000000..833d51a
--- /dev/null
+++ b/modules/pam_time/Makefile.am
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = time.conf.5 pam_time.8
+endif
+XMLS = README.xml time.conf.5.xml pam_time.8.xml
+dist_check_SCRIPTS = tst-pam_time
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DPAM_TIME_CONF=\"$(SCONFIGDIR)/time.conf\" $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+pam_time_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+securelib_LTLIBRARIES = pam_time.la
+dist_secureconf_DATA = time.conf
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_time/Makefile.in b/modules/pam_time/Makefile.in
new file mode 100644
index 0000000..08d02d6
--- /dev/null
+++ b/modules/pam_time/Makefile.in
@@ -0,0 +1,1221 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_time
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(dist_secureconf_DATA) \
+ $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man5dir)" \
+ "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(secureconfdir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_time_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_time_la_SOURCES = pam_time.c
+pam_time_la_OBJECTS = pam_time.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_time.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_time.c
+DIST_SOURCES = pam_time.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man5dir = $(mandir)/man5
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA) $(dist_secureconf_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = time.conf.5 pam_time.8
+XMLS = README.xml time.conf.5.xml pam_time.8.xml
+dist_check_SCRIPTS = tst-pam_time
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DPAM_TIME_CONF=\"$(SCONFIGDIR)/time.conf\" $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+pam_time_la_LIBADD = $(top_builddir)/libpam/libpam.la
+securelib_LTLIBRARIES = pam_time.la
+dist_secureconf_DATA = time.conf
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_time/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_time/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_time.la: $(pam_time_la_OBJECTS) $(pam_time_la_DEPENDENCIES) $(EXTRA_pam_time_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_time_la_OBJECTS) $(pam_time_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_time.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man5: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man5dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man5dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man5dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.5[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man5dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man5dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man5:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man5dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.5[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^5][0-9a-z]*$$,5,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man5dir)'; $(am__uninstall_files_from_dir)
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+install-dist_secureconfDATA: $(dist_secureconf_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(dist_secureconf_DATA)'; test -n "$(secureconfdir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(secureconfdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(secureconfdir)" || exit 1; \
+ fi; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(secureconfdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(secureconfdir)" || exit $$?; \
+ done
+
+uninstall-dist_secureconfDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(dist_secureconf_DATA)'; test -n "$(secureconfdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ dir='$(DESTDIR)$(secureconfdir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_time.log: tst-pam_time
+ @p='tst-pam_time'; \
+ b='tst-pam_time'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(secureconfdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_time.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-dist_secureconfDATA install-man \
+ install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man5 install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_time.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-dist_secureconfDATA uninstall-man \
+ uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man5 uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dist_secureconfDATA install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-man5 install-man8 install-pdf install-pdf-am \
+ install-ps install-ps-am install-securelibLTLIBRARIES \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am recheck tags tags-am uninstall \
+ uninstall-am uninstall-dist_secureconfDATA uninstall-man \
+ uninstall-man5 uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_time/README b/modules/pam_time/README
new file mode 100644
index 0000000..9b20847
--- /dev/null
+++ b/modules/pam_time/README
@@ -0,0 +1,35 @@
+pam_time — PAM module for time control access
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+The pam_time PAM module does not authenticate the user, but instead it
+restricts access to a system and or specific applications at various times of
+the day and on specific days or over various terminal lines. This module can be
+configured to deny access to (individual) users based on their name, the time
+of day, the day of week, the service they are applying for and their terminal
+from which they are making their request.
+
+By default rules for time/port access are taken from config file /etc/security/
+time.conf. An alternative file can be specified with the conffile option.
+
+If Linux PAM is compiled with audit support the module will report when it
+denies access.
+
+EXAMPLES
+
+These are some example lines which might be specified in /etc/security/
+time.conf.
+
+All users except for root are denied access to console-login at all times:
+
+login ; tty* & !ttyp* ; !root ; !Al0000-2400
+
+
+Games (configured to use PAM) are only to be accessed out of working hours.
+This rule does not apply to the user waster:
+
+games ; * ; !waster ; Wd0000-2400 | Wk1800-0800
+
+
diff --git a/modules/pam_time/README.xml b/modules/pam_time/README.xml
new file mode 100644
index 0000000..6c11eec
--- /dev/null
+++ b/modules/pam_time/README.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamtime SYSTEM "pam_time.8.xml">
+-->
+<!--
+<!ENTITY timeconf SYSTEM "time.conf.5.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_time.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_time-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_time.8.xml" xpointer='xpointer(//refsect1[@id = "pam_time-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="time.conf.5.xml" xpointer='xpointer(//refsect1[@id = "time.conf-examples"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_time/pam_time.8 b/modules/pam_time/pam_time.8
new file mode 100644
index 0000000..28d84d7
--- /dev/null
+++ b/modules/pam_time/pam_time.8
@@ -0,0 +1,122 @@
+'\" t
+.\" Title: pam_time
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_TIME" "8" "09/03/2021" "Linux-PAM Manual" "Linux-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_time \- PAM module for time control access
+.SH "SYNOPSIS"
+.HP \w'\fBpam_time\&.so\fR\ 'u
+\fBpam_time\&.so\fR [conffile=conf\-file] [debug] [noaudit]
+.SH "DESCRIPTION"
+.PP
+The pam_time PAM module does not authenticate the user, but instead it restricts access to a system and or specific applications at various times of the day and on specific days or over various terminal lines\&. This module can be configured to deny access to (individual) users based on their name, the time of day, the day of week, the service they are applying for and their terminal from which they are making their request\&.
+.PP
+By default rules for time/port access are taken from config file
+/etc/security/time\&.conf\&. An alternative file can be specified with the
+\fIconffile\fR
+option\&.
+.PP
+If Linux PAM is compiled with audit support the module will report when it denies access\&.
+.SH "OPTIONS"
+.PP
+\fBconffile=/path/to/time\&.conf\fR
+.RS 4
+Indicate an alternative time\&.conf style configuration file to override the default\&.
+.RE
+.PP
+\fBdebug\fR
+.RS 4
+Some debug information is printed with
+\fBsyslog\fR(3)\&.
+.RE
+.PP
+\fBnoaudit\fR
+.RS 4
+Do not report logins at disallowed time to the audit subsystem\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+Only the
+\fBaccount\fR
+type is provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_SUCCESS
+.RS 4
+Access was granted\&.
+.RE
+.PP
+PAM_ABORT
+.RS 4
+Not all relevant data could be gotten\&.
+.RE
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_PERM_DENIED
+.RS 4
+Access was not granted\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+The user is not known to the system\&.
+.RE
+.SH "FILES"
+.PP
+/etc/security/time\&.conf
+.RS 4
+Default configuration file
+.RE
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+#%PAM\-1\&.0
+#
+# apply pam_time accounting to login requests
+#
+login account required pam_time\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+.PP
+\fBtime.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)\&.
+.SH "AUTHOR"
+.PP
+pam_time was written by Andrew G\&. Morgan <morgan@kernel\&.org>\&.
diff --git a/modules/pam_time/pam_time.8.xml b/modules/pam_time/pam_time.8.xml
new file mode 100644
index 0000000..4708220
--- /dev/null
+++ b/modules/pam_time/pam_time.8.xml
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+
+<refentry id='pam_time'>
+
+ <refmeta>
+ <refentrytitle>pam_time</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id='pam_time-name'>
+ <refname>pam_time</refname>
+ <refpurpose>
+ PAM module for time control access
+ </refpurpose>
+ </refnamediv>
+
+<!-- body begins here -->
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_time-cmdsynopsis">
+ <command>pam_time.so</command>
+ <arg choice="opt">
+ conffile=conf-file
+ </arg>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ noaudit
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1 id="pam_time-description">
+ <title>DESCRIPTION</title>
+ <para>
+ The pam_time PAM module does not authenticate the user, but instead
+ it restricts access to a system and or specific applications at
+ various times of the day and on specific days or over various
+ terminal lines. This module can be configured to deny access to
+ (individual) users based on their name, the time of day, the day of
+ week, the service they are applying for and their terminal from which
+ they are making their request.
+ </para>
+ <para>
+ By default rules for time/port access are taken from config file
+ <filename>/etc/security/time.conf</filename>.
+ An alternative file can be specified with the <emphasis>conffile</emphasis> option.
+ </para>
+ <para>
+ If Linux PAM is compiled with audit support the module will report
+ when it denies access.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_time-options">
+ <title>OPTIONS</title>
+ <variablelist>
+
+ <varlistentry>
+ <term>
+ <option>conffile=/path/to/time.conf</option>
+ </term>
+ <listitem>
+ <para>
+ Indicate an alternative time.conf style configuration file to override the default.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Some debug information is printed with
+ <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>noaudit</option>
+ </term>
+ <listitem>
+ <para>
+ Do not report logins at disallowed time to the audit subsystem.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_time-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ Only the <option>account</option> type is provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_time-return_values">
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Access was granted.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_ABORT</term>
+ <listitem>
+ <para>
+ Not all relevant data could be gotten.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory buffer error.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_PERM_DENIED</term>
+ <listitem>
+ <para>
+ Access was not granted.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ The user is not known to the system.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_time-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/security/time.conf</filename></term>
+ <listitem>
+ <para>Default configuration file</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_time-examples'>
+ <title>EXAMPLES</title>
+ <programlisting>
+#%PAM-1.0
+#
+# apply pam_time accounting to login requests
+#
+login account required pam_time.so
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id="pam_time-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>time.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_time-authors">
+ <title>AUTHOR</title>
+ <para>
+ pam_time was written by Andrew G. Morgan &lt;morgan@kernel.org&gt;.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_time/pam_time.c b/modules/pam_time/pam_time.c
new file mode 100644
index 0000000..089ae22
--- /dev/null
+++ b/modules/pam_time/pam_time.c
@@ -0,0 +1,677 @@
+/*
+ * pam_time module
+ *
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/6/22
+ * (File syntax and much other inspiration from the shadow package
+ * shadow-960129)
+ * Field parsing rewritten by Tomas Mraz <tm@t8m.info>
+ */
+
+#include "config.h"
+
+#include <sys/file.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <time.h>
+#include <syslog.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <netdb.h>
+
+#include <security/_pam_macros.h>
+#include <security/pam_modules.h>
+#include <security/pam_ext.h>
+#include <security/pam_modutil.h>
+#include "pam_inline.h"
+
+#ifdef HAVE_LIBAUDIT
+#include <libaudit.h>
+#endif
+
+#define PAM_TIME_BUFLEN 1000
+#define FIELD_SEPARATOR ';' /* this is new as of .02 */
+
+#define PAM_DEBUG_ARG 0x0001
+#define PAM_NO_AUDIT 0x0002
+
+#ifndef TRUE
+# define TRUE 1
+#endif
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+typedef enum { AND, OR } operator;
+
+static int
+_pam_parse (const pam_handle_t *pamh, int argc, const char **argv, const char **conffile)
+{
+ int ctrl = 0;
+
+ *conffile = PAM_TIME_CONF;
+ /* step through arguments */
+ for (; argc-- > 0; ++argv) {
+ const char *str;
+
+ /* generic options */
+
+ if (!strcmp(*argv, "debug")) {
+ ctrl |= PAM_DEBUG_ARG;
+ } else if (!strcmp(*argv, "noaudit")) {
+ ctrl |= PAM_NO_AUDIT;
+ } else if ((str = pam_str_skip_prefix(*argv, "conffile=")) != NULL) {
+ if (str[0] == '\0') {
+ pam_syslog(pamh, LOG_ERR,
+ "conffile= specification missing argument - ignored");
+ } else {
+ *conffile = str;
+ D(("new Configuration File: %s", *conffile));
+ }
+ } else {
+ pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
+ }
+ }
+
+ return ctrl;
+}
+
+/* --- static functions for checking whether the user should be let in --- */
+
+static char *
+shift_buf(char *mem, int from)
+{
+ char *start = mem;
+ while ((*mem = mem[from]) != '\0')
+ ++mem;
+ memset(mem, '\0', PAM_TIME_BUFLEN - (mem - start));
+ return mem;
+}
+
+static void
+trim_spaces(char *buf, char *from)
+{
+ while (from > buf) {
+ --from;
+ if (*from == ' ')
+ *from = '\0';
+ else
+ break;
+ }
+}
+
+#define STATE_NL 0 /* new line starting */
+#define STATE_COMMENT 1 /* inside comment */
+#define STATE_FIELD 2 /* field following */
+#define STATE_EOF 3 /* end of file or error */
+
+static int
+read_field(const pam_handle_t *pamh, int fd, char **buf, int *from, int *state, const char *file)
+{
+ char *to;
+ char *src;
+ int i;
+ char c;
+ int onspace;
+
+ /* is buf set ? */
+ if (! *buf) {
+ *buf = (char *) calloc(1, PAM_TIME_BUFLEN+1);
+ if (! *buf) {
+ pam_syslog(pamh, LOG_CRIT, "out of memory");
+ D(("no memory"));
+ *state = STATE_EOF;
+ return -1;
+ }
+ *from = 0;
+ *state = STATE_NL;
+ fd = open(file, O_RDONLY);
+ if (fd < 0) {
+ pam_syslog(pamh, LOG_ERR, "error opening %s: %m", file);
+ _pam_drop(*buf);
+ *state = STATE_EOF;
+ return -1;
+ }
+ }
+
+
+ if (*from > 0)
+ to = shift_buf(*buf, *from);
+ else
+ to = *buf;
+
+ while (fd != -1 && to - *buf < PAM_TIME_BUFLEN) {
+ i = pam_modutil_read(fd, to, PAM_TIME_BUFLEN - (to - *buf));
+ if (i < 0) {
+ pam_syslog(pamh, LOG_ERR, "error reading %s: %m", file);
+ close(fd);
+ memset(*buf, 0, PAM_TIME_BUFLEN);
+ _pam_drop(*buf);
+ *state = STATE_EOF;
+ return -1;
+ } else if (!i) {
+ close(fd);
+ fd = -1; /* end of file reached */
+ }
+
+ to += i;
+ }
+
+ if (to == *buf) {
+ /* nothing previously in buf, nothing read */
+ _pam_drop(*buf);
+ *state = STATE_EOF;
+ return -1;
+ }
+
+ memset(to, '\0', PAM_TIME_BUFLEN - (to - *buf));
+
+ to = *buf;
+ onspace = 1; /* delete any leading spaces */
+
+ for (src = to; (c=*src) != '\0'; ++src) {
+ if (*state == STATE_COMMENT && c != '\n') {
+ continue;
+ }
+
+ switch (c) {
+ case '\n':
+ *state = STATE_NL;
+ *to = '\0';
+ *from = (src - *buf) + 1;
+ trim_spaces(*buf, to);
+ return fd;
+
+ case '\t':
+ case ' ':
+ if (!onspace) {
+ onspace = 1;
+ *to++ = ' ';
+ }
+ break;
+
+ case '!':
+ onspace = 1; /* ignore following spaces */
+ *to++ = '!';
+ break;
+
+ case '#':
+ *state = STATE_COMMENT;
+ break;
+
+ case FIELD_SEPARATOR:
+ *state = STATE_FIELD;
+ *to = '\0';
+ *from = (src - *buf) + 1;
+ trim_spaces(*buf, to);
+ return fd;
+
+ case '\\':
+ if (src[1] == '\n') {
+ ++src; /* skip it */
+ break;
+ }
+ /* fallthrough */
+ default:
+ *to++ = c;
+ onspace = 0;
+ }
+ if (src > to)
+ *src = '\0'; /* clearing */
+ }
+
+ if (*state != STATE_COMMENT) {
+ *state = STATE_COMMENT;
+ pam_syslog(pamh, LOG_ERR, "field too long - ignored");
+ **buf = '\0';
+ } else {
+ *to = '\0';
+ trim_spaces(*buf, to);
+ }
+
+ *from = 0;
+ return fd;
+}
+
+/* read a member from a field */
+
+static int
+logic_member(const char *string, int *at)
+{
+ int c,to;
+ int done=0;
+ int token=0;
+
+ to=*at;
+ do {
+ c = string[to++];
+
+ switch (c) {
+
+ case '\0':
+ --to;
+ done = 1;
+ break;
+
+ case '&':
+ case '|':
+ case '!':
+ if (token) {
+ --to;
+ }
+ done = 1;
+ break;
+
+ default:
+ if (isalpha(c) || c == '*' || isdigit(c) || c == '_'
+ || c == '-' || c == '.' || c == '/' || c == ':') {
+ token = 1;
+ } else if (token) {
+ --to;
+ done = 1;
+ } else {
+ ++*at;
+ }
+ }
+ } while (!done);
+
+ return to - *at;
+}
+
+typedef enum { VAL, OP } expect;
+
+static int
+logic_field(pam_handle_t *pamh, const void *me, const char *x, int rule,
+ int (*agrees)(pam_handle_t *pamh,
+ const void *, const char *, int, int))
+{
+ int left=FALSE, right, not=FALSE;
+ operator oper=OR;
+ int at=0, l;
+ expect next=VAL;
+
+ while ((l = logic_member(x,&at))) {
+ int c = x[at];
+
+ if (next == VAL) {
+ if (c == '!')
+ not = !not;
+ else if (isalpha(c) || c == '*' || isdigit(c) || c == '_'
+ || c == '-' || c == '.' || c == '/' || c == ':') {
+ right = not ^ agrees(pamh, me, x+at, l, rule);
+ if (oper == AND)
+ left &= right;
+ else
+ left |= right;
+ next = OP;
+ } else {
+ pam_syslog(pamh, LOG_ERR,
+ "garbled syntax; expected name (rule #%d)",
+ rule);
+ return FALSE;
+ }
+ } else { /* OP */
+ switch (c) {
+ case '&':
+ oper = AND;
+ break;
+ case '|':
+ oper = OR;
+ break;
+ default:
+ pam_syslog(pamh, LOG_ERR,
+ "garbled syntax; expected & or | (rule #%d)",
+ rule);
+ D(("%c at %d",c,at));
+ return FALSE;
+ }
+ next = VAL;
+ not = FALSE;
+ }
+ at += l;
+ }
+
+ return left;
+}
+
+static int
+is_same(pam_handle_t *pamh UNUSED, const void *A, const char *b,
+ int len, int rule UNUSED)
+{
+ int i;
+ const char *a;
+
+ a = A;
+ for (i=0; len > 0; ++i, --len) {
+ if (b[i] != a[i]) {
+ if (b[i++] == '*') {
+ return (!--len || !strncmp(b+i,a+strlen(a)-len,len));
+ } else
+ return FALSE;
+ }
+ }
+
+ /* Ok, we know that b is a substring from A and does not contain
+ wildcards, but now the length of both strings must be the same,
+ too. In this case it means, a[i] has to be the end of the string. */
+ if (a[i] != '\0')
+ return FALSE;
+
+ return ( !len );
+}
+
+typedef struct {
+ int day; /* array of 7 bits, one set for today */
+ int minute; /* integer, hour*100+minute for now */
+} TIME;
+
+static struct day {
+ const char *d;
+ int bit;
+} const days[11] = {
+ { "su", 01 },
+ { "mo", 02 },
+ { "tu", 04 },
+ { "we", 010 },
+ { "th", 020 },
+ { "fr", 040 },
+ { "sa", 0100 },
+ { "wk", 076 },
+ { "wd", 0101 },
+ { "al", 0177 },
+ { NULL, 0 }
+};
+
+static TIME
+time_now(void)
+{
+ struct tm *local;
+ time_t the_time;
+ TIME this;
+
+ the_time = time((time_t *)0); /* get the current time */
+ local = localtime(&the_time);
+ this.day = days[local->tm_wday].bit;
+ this.minute = local->tm_hour*100 + local->tm_min;
+
+ D(("day: 0%o, time: %.4d", this.day, this.minute));
+ return this;
+}
+
+/* take the current date and see if the range "date" passes it */
+static int
+check_time(pam_handle_t *pamh, const void *AT, const char *times,
+ int len, int rule)
+{
+ int not,pass;
+ int marked_day, time_start, time_end;
+ const TIME *at;
+ int i,j=0;
+
+ at = AT;
+ D(("chcking: 0%o/%.4d vs. %s", at->day, at->minute, times));
+
+ if (times == NULL) {
+ /* this should not happen */
+ pam_syslog(pamh, LOG_CRIT,
+ "internal error in file %s at line %d",
+ __FILE__, __LINE__);
+ return FALSE;
+ }
+
+ if (times[j] == '!') {
+ ++j;
+ not = TRUE;
+ } else {
+ not = FALSE;
+ }
+
+ for (marked_day = 0; len > 0 && isalpha(times[j]); --len) {
+ int this_day=-1;
+
+ D(("%c%c ?", times[j], times[j+1]));
+ for (i=0; days[i].d != NULL; ++i) {
+ if (tolower(times[j]) == days[i].d[0]
+ && tolower(times[j+1]) == days[i].d[1] ) {
+ this_day = days[i].bit;
+ break;
+ }
+ }
+ j += 2;
+ if (this_day == -1) {
+ pam_syslog(pamh, LOG_ERR, "bad day specified (rule #%d)", rule);
+ return FALSE;
+ }
+ marked_day ^= this_day;
+ }
+ if (marked_day == 0) {
+ pam_syslog(pamh, LOG_ERR, "no day specified");
+ return FALSE;
+ }
+ D(("day range = 0%o", marked_day));
+
+ time_start = 0;
+ for (i=0; len > 0 && i < 4 && isdigit(times[i+j]); ++i, --len) {
+ time_start *= 10;
+ time_start += times[i+j]-'0'; /* is this portable? */
+ }
+ j += i;
+
+ if (times[j] == '-') {
+ time_end = 0;
+ for (i=1; len > 0 && i < 5 && isdigit(times[i+j]); ++i, --len) {
+ time_end *= 10;
+ time_end += times[i+j]-'0'; /* is this portable */
+ }
+ j += i;
+ } else
+ time_end = -1;
+
+ D(("i=%d, time_end=%d, times[j]='%c'", i, time_end, times[j]));
+ if (i != 5 || time_end == -1) {
+ pam_syslog(pamh, LOG_ERR, "no/bad times specified (rule #%d)", rule);
+ return TRUE;
+ }
+ D(("times(%d to %d)", time_start,time_end));
+ D(("marked_day = 0%o", marked_day));
+
+ /* compare with the actual time now */
+
+ pass = FALSE;
+ if (time_start < time_end) { /* start < end ? --> same day */
+ if ((at->day & marked_day) && (at->minute >= time_start)
+ && (at->minute < time_end)) {
+ D(("time is listed"));
+ pass = TRUE;
+ }
+ } else { /* spans two days */
+ if ((at->day & marked_day) && (at->minute >= time_start)) {
+ D(("caught on first day"));
+ pass = TRUE;
+ } else {
+ marked_day <<= 1;
+ marked_day |= (marked_day & 0200) ? 1:0;
+ D(("next day = 0%o", marked_day));
+ if ((at->day & marked_day) && (at->minute <= time_end)) {
+ D(("caught on second day"));
+ pass = TRUE;
+ }
+ }
+ }
+
+ return (not ^ pass);
+}
+
+static int
+check_account(pam_handle_t *pamh, const char *service,
+ const char *tty, const char *user, const char *file)
+{
+ int from=0, state=STATE_NL, fd=-1;
+ char *buffer=NULL;
+ int count=0;
+ TIME here_and_now;
+ int retval=PAM_SUCCESS;
+
+ here_and_now = time_now(); /* find current time */
+ do {
+ int good=TRUE,intime;
+
+ /* here we get the service name field */
+
+ fd = read_field(pamh, fd, &buffer, &from, &state, file);
+ if (!buffer || !buffer[0]) {
+ /* empty line .. ? */
+ continue;
+ }
+ ++count;
+
+ if (state != STATE_FIELD) {
+ pam_syslog(pamh, LOG_ERR,
+ "%s: malformed rule #%d", file, count);
+ continue;
+ }
+
+ good = logic_field(pamh, service, buffer, count, is_same);
+ D(("with service: %s", good ? "passes":"fails" ));
+
+ /* here we get the terminal name field */
+
+ fd = read_field(pamh, fd, &buffer, &from, &state, file);
+ if (state != STATE_FIELD) {
+ pam_syslog(pamh, LOG_ERR,
+ "%s: malformed rule #%d", file, count);
+ continue;
+ }
+ good &= logic_field(pamh, tty, buffer, count, is_same);
+ D(("with tty: %s", good ? "passes":"fails" ));
+
+ /* here we get the username field */
+
+ fd = read_field(pamh, fd, &buffer, &from, &state, file);
+ if (state != STATE_FIELD) {
+ pam_syslog(pamh, LOG_ERR,
+ "%s: malformed rule #%d", file, count);
+ continue;
+ }
+ /* If buffer starts with @, we are using netgroups */
+ if (buffer[0] == '@')
+#ifdef HAVE_INNETGR
+ good &= innetgr (&buffer[1], NULL, user, NULL);
+#else
+ pam_syslog (pamh, LOG_ERR, "pam_time does not have netgroup support");
+#endif
+ else
+ good &= logic_field(pamh, user, buffer, count, is_same);
+ D(("with user: %s", good ? "passes":"fails" ));
+
+ /* here we get the time field */
+
+ fd = read_field(pamh, fd, &buffer, &from, &state, file);
+ if (state == STATE_FIELD) {
+ pam_syslog(pamh, LOG_ERR,
+ "%s: poorly terminated rule #%d", file, count);
+ continue;
+ }
+
+ intime = logic_field(pamh, &here_and_now, buffer, count, check_time);
+ D(("with time: %s", intime ? "passes":"fails" ));
+
+ if (good && !intime) {
+ /*
+ * for security parse whole file.. also need to ensure
+ * that the buffer is free()'d and the file is closed.
+ */
+ retval = PAM_PERM_DENIED;
+ } else {
+ D(("rule passed"));
+ }
+ } while (state != STATE_EOF);
+
+ return retval;
+}
+
+/* --- public account management functions --- */
+
+int
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ const void *service=NULL, *void_tty=NULL;
+ const char *tty;
+ const char *user=NULL;
+ const char *conf_file = NULL;
+ int ctrl;
+ int rv;
+
+ ctrl = _pam_parse(pamh, argc, argv, &conf_file);
+
+ if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_DEBUG, "conffile=%s", conf_file);
+ }
+
+ /* set service name */
+
+ if (pam_get_item(pamh, PAM_SERVICE, &service)
+ != PAM_SUCCESS || service == NULL) {
+ pam_syslog(pamh, LOG_ERR, "cannot find the current service name");
+ return PAM_ABORT;
+ }
+
+ /* set username */
+
+ if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS || *user == '\0') {
+ pam_syslog(pamh, LOG_NOTICE, "cannot determine user name");
+ return PAM_USER_UNKNOWN;
+ }
+
+ /* set tty name */
+
+ if (pam_get_item(pamh, PAM_TTY, &void_tty) != PAM_SUCCESS
+ || void_tty == NULL) {
+ D(("PAM_TTY not set, probing stdin"));
+ tty = ttyname(STDIN_FILENO);
+ if (tty == NULL) {
+ tty = "";
+ }
+ if (pam_set_item(pamh, PAM_TTY, tty) != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR, "couldn't set tty name");
+ return PAM_ABORT;
+ }
+ }
+ else
+ tty = void_tty;
+
+ if (tty[0] == '/') { /* full path */
+ const char *t;
+ tty++;
+ if ((t = strchr(tty, '/')) != NULL) {
+ tty = t + 1;
+ }
+ }
+
+ /* good, now we have the service name, the user and the terminal name */
+
+ D(("service=%s", service));
+ D(("user=%s", user));
+ D(("tty=%s", tty));
+
+ rv = check_account(pamh, service, tty, user, conf_file);
+ if (rv != PAM_SUCCESS) {
+#ifdef HAVE_LIBAUDIT
+ if (!(ctrl & PAM_NO_AUDIT)) {
+ pam_modutil_audit_write(pamh, AUDIT_ANOM_LOGIN_TIME,
+ "pam_time", rv); /* ignore return value as we fail anyway */
+ }
+#endif
+ if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_DEBUG, "user %s rejected", user);
+ }
+ }
+ return rv;
+}
+
+/* end of module definition */
diff --git a/modules/pam_time/time.conf b/modules/pam_time/time.conf
new file mode 100644
index 0000000..68d2dad
--- /dev/null
+++ b/modules/pam_time/time.conf
@@ -0,0 +1,65 @@
+# this is an example configuration file for the pam_time module. Its syntax
+# was initially based heavily on that of the shadow package (shadow-960129).
+#
+# the syntax of the lines is as follows:
+#
+# services;ttys;users;times
+#
+# white space is ignored and lines maybe extended with '\\n' (escaped
+# newlines). As should be clear from reading these comments,
+# text following a '#' is ignored to the end of the line.
+#
+# the combination of individual users/terminals etc is a logic list
+# namely individual tokens that are optionally prefixed with '!' (logical
+# not) and separated with '&' (logical and) and '|' (logical or).
+#
+# services
+# is a logic list of PAM service names that the rule applies to.
+#
+# ttys
+# is a logic list of terminal names that this rule applies to.
+#
+# users
+# is a logic list of users or a netgroup of users to whom this
+# rule applies.
+#
+# NB. For these items the simple wildcard '*' may be used only once.
+#
+# times
+# the format here is a logic list of day/time-range
+# entries the days are specified by a sequence of two character
+# entries, MoTuSa for example is Monday Tuesday and Saturday. Note
+# that repeated days are unset MoMo = no day, and MoWk = all weekdays
+# bar Monday. The two character combinations accepted are
+#
+# Mo Tu We Th Fr Sa Su Wk Wd Al
+#
+# the last two being week-end days and all 7 days of the week
+# respectively. As a final example, AlFr means all days except Friday.
+#
+# each day/time-range can be prefixed with a '!' to indicate "anything
+# but"
+#
+# The time-range part is two 24-hour times HHMM separated by a hyphen
+# indicating the start and finish time (if the finish time is smaller
+# than the start time it is deemed to apply on the following day).
+#
+# for a rule to be active, ALL of service+ttys+users must be satisfied
+# by the applying process.
+#
+
+#
+# Here is a simple example: running blank on tty* (any ttyXXX device),
+# the users 'you' and 'me' are denied service all of the time
+#
+
+#blank;tty* & !ttyp*;you|me;!Al0000-2400
+
+# Another silly example, user 'root' is denied xsh access
+# from pseudo terminals at the weekend and on mondays.
+
+#xsh;ttyp*;root;!WdMo0000-2400
+
+#
+# End of example file.
+#
diff --git a/modules/pam_time/time.conf.5 b/modules/pam_time/time.conf.5
new file mode 100644
index 0000000..2dda8be
--- /dev/null
+++ b/modules/pam_time/time.conf.5
@@ -0,0 +1,115 @@
+'\" t
+.\" Title: time.conf
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "TIME\&.CONF" "5" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+time.conf \- configuration file for the pam_time module
+.SH "DESCRIPTION"
+.PP
+The pam_time PAM module does not authenticate the user, but instead it restricts access to a system and or specific applications at various times of the day and on specific days or over various terminal lines\&. This module can be configured to deny access to (individual) users based on their name, the time of day, the day of week, the service they are applying for and their terminal from which they are making their request\&.
+.PP
+For this module to function correctly there must be a correctly formatted
+/etc/security/time\&.conf
+file present\&. White spaces are ignored and lines maybe extended with \*(Aq\e\*(Aq (escaped newlines)\&. Text following a \*(Aq#\*(Aq is ignored to the end of the line\&.
+.PP
+The syntax of the lines is as follows:
+.PP
+\fIservices\fR;\fIttys\fR;\fIusers\fR;\fItimes\fR
+.PP
+In words, each rule occupies a line, terminated with a newline or the beginning of a comment; a \*(Aq\fB#\fR\*(Aq\&. It contains four fields separated with semicolons, \*(Aq\fB;\fR\*(Aq\&.
+.PP
+The first field, the
+\fIservices\fR
+field, is a logic list of PAM service names that the rule applies to\&.
+.PP
+The second field, the
+\fItty\fR
+field, is a logic list of terminal names that this rule applies to\&.
+.PP
+The third field, the
+\fIusers\fR
+field, is a logic list of users or a netgroup of users to whom this rule applies\&.
+.PP
+A logic list namely means individual tokens that are optionally prefixed with \*(Aq!\*(Aq (logical not) and separated with \*(Aq&\*(Aq (logical and) and \*(Aq|\*(Aq (logical or)\&.
+.PP
+For these items the simple wildcard \*(Aq*\*(Aq may be used only once\&. With netgroups no wildcards or logic operators are allowed\&.
+.PP
+The
+\fItimes\fR
+field is used to indicate the times at which this rule applies\&. The format here is a logic list of day/time\-range entries\&. The days are specified by a sequence of two character entries, MoTuSa for example is Monday Tuesday and Saturday\&. Note that repeated days are unset MoMo = no day, and MoWk = all weekdays bar Monday\&. The two character combinations accepted are Mo Tu We Th Fr Sa Su Wk Wd Al, the last two being week\-end days and all 7 days of the week respectively\&. As a final example, AlFr means all days except Friday\&.
+.PP
+Each day/time\-range can be prefixed with a \*(Aq!\*(Aq to indicate "anything but"\&. The time\-range part is two 24\-hour times HHMM, separated by a hyphen, indicating the start and finish time (if the finish time is smaller than the start time it is deemed to apply on the following day)\&.
+.PP
+For a rule to be active, ALL of service+ttys+users must be satisfied by the applying process\&.
+.PP
+Note, currently there is no daemon enforcing the end of a session\&. This needs to be remedied\&.
+.PP
+Poorly formatted rules are logged as errors using
+\fBsyslog\fR(3)\&.
+.SH "EXAMPLES"
+.PP
+These are some example lines which might be specified in
+/etc/security/time\&.conf\&.
+.PP
+All users except for
+\fIroot\fR
+are denied access to console\-login at all times:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+login ; tty* & !ttyp* ; !root ; !Al0000\-2400
+
+.fi
+.if n \{\
+.RE
+.\}
+.PP
+Games (configured to use PAM) are only to be accessed out of working hours\&. This rule does not apply to the user
+\fIwaster\fR:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+games ; * ; !waster ; Wd0000\-2400 | Wk1800\-0800
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.PP
+\fBpam_time\fR(8),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_time was written by Andrew G\&. Morgan <morgan@kernel\&.org>\&.
diff --git a/modules/pam_time/time.conf.5.xml b/modules/pam_time/time.conf.5.xml
new file mode 100644
index 0000000..acbe232
--- /dev/null
+++ b/modules/pam_time/time.conf.5.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="time.conf">
+
+ <refmeta>
+ <refentrytitle>time.conf</refentrytitle>
+ <manvolnum>5</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>time.conf</refname>
+ <refpurpose>configuration file for the pam_time module</refpurpose>
+ </refnamediv>
+
+ <refsect1 id='time.conf-description'>
+ <title>DESCRIPTION</title>
+
+ <para>
+ The pam_time PAM module does not authenticate the user, but instead
+ it restricts access to a system and or specific applications at
+ various times of the day and on specific days or over various
+ terminal lines. This module can be configured to deny access to
+ (individual) users based on their name, the time of day, the day of
+ week, the service they are applying for and their terminal from which
+ they are making their request.
+ </para>
+ <para>
+ For this module to function correctly there must be a correctly
+ formatted <filename>/etc/security/time.conf</filename> file present.
+ White spaces are ignored and lines maybe extended with '\' (escaped
+ newlines). Text following a '#' is ignored to the end of the line.
+ </para>
+
+ <para>
+ The syntax of the lines is as follows:
+ </para>
+
+ <para>
+ <replaceable>services</replaceable>;<replaceable>ttys</replaceable>;<replaceable>users</replaceable>;<replaceable>times</replaceable>
+ </para>
+ <para>
+ In words, each rule occupies a line, terminated with a newline
+ or the beginning of a comment; a '<emphasis remap='B'>#</emphasis>'.
+ It contains four fields separated with semicolons,
+ '<emphasis remap='B'>;</emphasis>'.
+ </para>
+
+ <para>
+ The first field, the <replaceable>services</replaceable> field,
+ is a logic list of PAM service names that the rule applies to.
+ </para>
+
+ <para>
+ The second field, the <replaceable>tty</replaceable>
+ field, is a logic list of terminal names that this rule applies to.
+ </para>
+
+ <para>
+ The third field, the <replaceable>users</replaceable>
+ field, is a logic list of users or a netgroup of users to whom this
+ rule applies.
+ </para>
+
+ <para>
+ A logic list namely means individual tokens that are optionally prefixed
+ with '!' (logical not) and separated with '&amp;' (logical and) and '|'
+ (logical or).
+ </para>
+
+ <para>
+ For these items the simple wildcard '*' may be used only once.
+ With netgroups no wildcards or logic operators are allowed.
+ </para>
+
+ <para>
+ The <replaceable>times</replaceable> field is used to indicate the times
+ at which this rule applies. The format here is a logic
+ list of day/time-range entries. The days are specified by a sequence of
+ two character entries, MoTuSa for example is Monday Tuesday and Saturday.
+ Note that repeated days are unset MoMo = no day, and MoWk = all weekdays
+ bar Monday. The two character combinations accepted are Mo Tu We Th Fr Sa
+ Su Wk Wd Al, the last two being week-end days and all 7 days of the week
+ respectively. As a final example, AlFr means all days except Friday.
+ </para>
+ <para>
+ Each day/time-range can be prefixed with a '!' to indicate
+ "anything but".
+ The time-range part is two 24-hour times HHMM, separated by a hyphen,
+ indicating the start and finish time (if the finish time is smaller
+ than the start time it is deemed to apply on the following day).
+ </para>
+
+ <para>
+ For a rule to be active, ALL of service+ttys+users must be satisfied
+ by the applying process.
+ </para>
+ <para>
+ Note, currently there is no daemon enforcing the end of a session.
+ This needs to be remedied.
+ </para>
+ <para>
+ Poorly formatted rules are logged as errors using
+ <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="time.conf-examples">
+ <title>EXAMPLES</title>
+ <para>
+ These are some example lines which might be specified in
+ <filename>/etc/security/time.conf</filename>.
+ </para>
+ <para>
+ All users except for <emphasis>root</emphasis> are denied access
+ to console-login at all times:
+ <programlisting>
+login ; tty* &amp; !ttyp* ; !root ; !Al0000-2400
+ </programlisting>
+ </para>
+
+ <para>
+ Games (configured to use PAM) are only to be accessed out of
+ working hours. This rule does not apply to the user
+ <emphasis>waster</emphasis>:
+ <programlisting>
+games ; * ; !waster ; Wd0000-2400 | Wk1800-0800
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id="time.conf-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry><refentrytitle>pam_time</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id="time.conf-author">
+ <title>AUTHOR</title>
+ <para>
+ pam_time was written by Andrew G. Morgan &lt;morgan@kernel.org&gt;.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_time/tst-pam_time b/modules/pam_time/tst-pam_time
new file mode 100755
index 0000000..030717b
--- /dev/null
+++ b/modules/pam_time/tst-pam_time
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_time.so
diff --git a/modules/pam_timestamp/Makefile.am b/modules/pam_timestamp/Makefile.am
new file mode 100644
index 0000000..d290b85
--- /dev/null
+++ b/modules/pam_timestamp/Makefile.am
@@ -0,0 +1,60 @@
+#
+# Copyright (c) 2005, 2009 Thorsten Kukuk <kukuk@suse.de>
+# Copyright (c) 2005, 2008 Red Hat, Inc.
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_timestamp.8 pam_timestamp_check.8
+endif
+XMLS = README.xml pam_timestamp.8.xml pam_timestamp_check.8.xml
+dist_check_SCRIPTS = tst-pam_timestamp
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+noinst_HEADERS = hmacsha1.h sha1.h hmac_openssl_wrapper.h
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+pam_timestamp_la_LDFLAGS = -no-undefined -avoid-version -module $(AM_LDFLAGS) $(CRYPTO_LIBS)
+pam_timestamp_la_LIBADD = $(top_builddir)/libpam/libpam.la
+if HAVE_VERSIONING
+ pam_timestamp_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_timestamp.la
+sbin_PROGRAMS = pam_timestamp_check
+
+pam_timestamp_la_SOURCES = pam_timestamp.c
+if COND_USE_OPENSSL
+pam_timestamp_la_SOURCES += hmac_openssl_wrapper.c
+else
+pam_timestamp_la_SOURCES += hmacsha1.c sha1.c
+endif
+pam_timestamp_la_CFLAGS = $(AM_CFLAGS)
+
+pam_timestamp_check_SOURCES = pam_timestamp_check.c
+pam_timestamp_check_CFLAGS = $(AM_CFLAGS) @EXE_CFLAGS@
+pam_timestamp_check_LDADD = $(top_builddir)/libpam/libpam.la
+pam_timestamp_check_LDFLAGS = @EXE_LDFLAGS@
+
+if COND_USE_OPENSSL
+hmacfile_SOURCES = hmac_openssl_wrapper.c
+else
+hmacfile_SOURCES = hmacfile.c hmacsha1.c sha1.c
+endif
+hmacfile_LDADD = $(top_builddir)/libpam/libpam.la
+
+check_PROGRAMS = hmacfile
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_timestamp/Makefile.in b/modules/pam_timestamp/Makefile.in
new file mode 100644
index 0000000..440020b
--- /dev/null
+++ b/modules/pam_timestamp/Makefile.in
@@ -0,0 +1,1349 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2009 Thorsten Kukuk <kukuk@suse.de>
+# Copyright (c) 2005, 2008 Red Hat, Inc.
+#
+
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+sbin_PROGRAMS = pam_timestamp_check$(EXEEXT)
+@COND_USE_OPENSSL_TRUE@am__append_2 = hmac_openssl_wrapper.c
+@COND_USE_OPENSSL_FALSE@am__append_3 = hmacsha1.c sha1.c
+check_PROGRAMS = hmacfile$(EXEEXT)
+subdir = modules/pam_timestamp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(noinst_HEADERS) \
+ $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(securelibdir)" \
+ "$(DESTDIR)$(man8dir)"
+PROGRAMS = $(sbin_PROGRAMS)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_timestamp_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+am__pam_timestamp_la_SOURCES_DIST = pam_timestamp.c \
+ hmac_openssl_wrapper.c hmacsha1.c sha1.c
+@COND_USE_OPENSSL_TRUE@am__objects_1 = pam_timestamp_la-hmac_openssl_wrapper.lo
+@COND_USE_OPENSSL_FALSE@am__objects_2 = pam_timestamp_la-hmacsha1.lo \
+@COND_USE_OPENSSL_FALSE@ pam_timestamp_la-sha1.lo
+am_pam_timestamp_la_OBJECTS = pam_timestamp_la-pam_timestamp.lo \
+ $(am__objects_1) $(am__objects_2)
+pam_timestamp_la_OBJECTS = $(am_pam_timestamp_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+pam_timestamp_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(pam_timestamp_la_CFLAGS) $(CFLAGS) \
+ $(pam_timestamp_la_LDFLAGS) $(LDFLAGS) -o $@
+am__hmacfile_SOURCES_DIST = hmacfile.c hmacsha1.c sha1.c \
+ hmac_openssl_wrapper.c
+@COND_USE_OPENSSL_FALSE@am_hmacfile_OBJECTS = hmacfile.$(OBJEXT) \
+@COND_USE_OPENSSL_FALSE@ hmacsha1.$(OBJEXT) sha1.$(OBJEXT)
+@COND_USE_OPENSSL_TRUE@am_hmacfile_OBJECTS = \
+@COND_USE_OPENSSL_TRUE@ hmac_openssl_wrapper.$(OBJEXT)
+hmacfile_OBJECTS = $(am_hmacfile_OBJECTS)
+hmacfile_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+am_pam_timestamp_check_OBJECTS = \
+ pam_timestamp_check-pam_timestamp_check.$(OBJEXT)
+pam_timestamp_check_OBJECTS = $(am_pam_timestamp_check_OBJECTS)
+pam_timestamp_check_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_timestamp_check_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(pam_timestamp_check_CFLAGS) $(CFLAGS) \
+ $(pam_timestamp_check_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/hmac_openssl_wrapper.Po \
+ ./$(DEPDIR)/hmacfile.Po ./$(DEPDIR)/hmacsha1.Po \
+ ./$(DEPDIR)/pam_timestamp_check-pam_timestamp_check.Po \
+ ./$(DEPDIR)/pam_timestamp_la-hmac_openssl_wrapper.Plo \
+ ./$(DEPDIR)/pam_timestamp_la-hmacsha1.Plo \
+ ./$(DEPDIR)/pam_timestamp_la-pam_timestamp.Plo \
+ ./$(DEPDIR)/pam_timestamp_la-sha1.Plo ./$(DEPDIR)/sha1.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(pam_timestamp_la_SOURCES) $(hmacfile_SOURCES) \
+ $(pam_timestamp_check_SOURCES)
+DIST_SOURCES = $(am__pam_timestamp_la_SOURCES_DIST) \
+ $(am__hmacfile_SOURCES_DIST) $(pam_timestamp_check_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_timestamp.8 pam_timestamp_check.8
+XMLS = README.xml pam_timestamp.8.xml pam_timestamp_check.8.xml
+dist_check_SCRIPTS = tst-pam_timestamp
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+noinst_HEADERS = hmacsha1.h sha1.h hmac_openssl_wrapper.h
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+pam_timestamp_la_LDFLAGS = -no-undefined -avoid-version -module \
+ $(AM_LDFLAGS) $(CRYPTO_LIBS) $(am__append_1)
+pam_timestamp_la_LIBADD = $(top_builddir)/libpam/libpam.la
+securelib_LTLIBRARIES = pam_timestamp.la
+pam_timestamp_la_SOURCES = pam_timestamp.c $(am__append_2) \
+ $(am__append_3)
+pam_timestamp_la_CFLAGS = $(AM_CFLAGS)
+pam_timestamp_check_SOURCES = pam_timestamp_check.c
+pam_timestamp_check_CFLAGS = $(AM_CFLAGS) @EXE_CFLAGS@
+pam_timestamp_check_LDADD = $(top_builddir)/libpam/libpam.la
+pam_timestamp_check_LDFLAGS = @EXE_LDFLAGS@
+@COND_USE_OPENSSL_FALSE@hmacfile_SOURCES = hmacfile.c hmacsha1.c sha1.c
+@COND_USE_OPENSSL_TRUE@hmacfile_SOURCES = hmac_openssl_wrapper.c
+hmacfile_LDADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_timestamp/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_timestamp/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(sbindir)" && rm -f $$files
+
+clean-sbinPROGRAMS:
+ @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_timestamp.la: $(pam_timestamp_la_OBJECTS) $(pam_timestamp_la_DEPENDENCIES) $(EXTRA_pam_timestamp_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(pam_timestamp_la_LINK) -rpath $(securelibdir) $(pam_timestamp_la_OBJECTS) $(pam_timestamp_la_LIBADD) $(LIBS)
+
+hmacfile$(EXEEXT): $(hmacfile_OBJECTS) $(hmacfile_DEPENDENCIES) $(EXTRA_hmacfile_DEPENDENCIES)
+ @rm -f hmacfile$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(hmacfile_OBJECTS) $(hmacfile_LDADD) $(LIBS)
+
+pam_timestamp_check$(EXEEXT): $(pam_timestamp_check_OBJECTS) $(pam_timestamp_check_DEPENDENCIES) $(EXTRA_pam_timestamp_check_DEPENDENCIES)
+ @rm -f pam_timestamp_check$(EXEEXT)
+ $(AM_V_CCLD)$(pam_timestamp_check_LINK) $(pam_timestamp_check_OBJECTS) $(pam_timestamp_check_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac_openssl_wrapper.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmacfile.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmacsha1.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_timestamp_check-pam_timestamp_check.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_timestamp_la-hmac_openssl_wrapper.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_timestamp_la-hmacsha1.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_timestamp_la-pam_timestamp.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_timestamp_la-sha1.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+pam_timestamp_la-pam_timestamp.lo: pam_timestamp.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_timestamp_la_CFLAGS) $(CFLAGS) -MT pam_timestamp_la-pam_timestamp.lo -MD -MP -MF $(DEPDIR)/pam_timestamp_la-pam_timestamp.Tpo -c -o pam_timestamp_la-pam_timestamp.lo `test -f 'pam_timestamp.c' || echo '$(srcdir)/'`pam_timestamp.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pam_timestamp_la-pam_timestamp.Tpo $(DEPDIR)/pam_timestamp_la-pam_timestamp.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pam_timestamp.c' object='pam_timestamp_la-pam_timestamp.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_timestamp_la_CFLAGS) $(CFLAGS) -c -o pam_timestamp_la-pam_timestamp.lo `test -f 'pam_timestamp.c' || echo '$(srcdir)/'`pam_timestamp.c
+
+pam_timestamp_la-hmac_openssl_wrapper.lo: hmac_openssl_wrapper.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_timestamp_la_CFLAGS) $(CFLAGS) -MT pam_timestamp_la-hmac_openssl_wrapper.lo -MD -MP -MF $(DEPDIR)/pam_timestamp_la-hmac_openssl_wrapper.Tpo -c -o pam_timestamp_la-hmac_openssl_wrapper.lo `test -f 'hmac_openssl_wrapper.c' || echo '$(srcdir)/'`hmac_openssl_wrapper.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pam_timestamp_la-hmac_openssl_wrapper.Tpo $(DEPDIR)/pam_timestamp_la-hmac_openssl_wrapper.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hmac_openssl_wrapper.c' object='pam_timestamp_la-hmac_openssl_wrapper.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_timestamp_la_CFLAGS) $(CFLAGS) -c -o pam_timestamp_la-hmac_openssl_wrapper.lo `test -f 'hmac_openssl_wrapper.c' || echo '$(srcdir)/'`hmac_openssl_wrapper.c
+
+pam_timestamp_la-hmacsha1.lo: hmacsha1.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_timestamp_la_CFLAGS) $(CFLAGS) -MT pam_timestamp_la-hmacsha1.lo -MD -MP -MF $(DEPDIR)/pam_timestamp_la-hmacsha1.Tpo -c -o pam_timestamp_la-hmacsha1.lo `test -f 'hmacsha1.c' || echo '$(srcdir)/'`hmacsha1.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pam_timestamp_la-hmacsha1.Tpo $(DEPDIR)/pam_timestamp_la-hmacsha1.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='hmacsha1.c' object='pam_timestamp_la-hmacsha1.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_timestamp_la_CFLAGS) $(CFLAGS) -c -o pam_timestamp_la-hmacsha1.lo `test -f 'hmacsha1.c' || echo '$(srcdir)/'`hmacsha1.c
+
+pam_timestamp_la-sha1.lo: sha1.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_timestamp_la_CFLAGS) $(CFLAGS) -MT pam_timestamp_la-sha1.lo -MD -MP -MF $(DEPDIR)/pam_timestamp_la-sha1.Tpo -c -o pam_timestamp_la-sha1.lo `test -f 'sha1.c' || echo '$(srcdir)/'`sha1.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pam_timestamp_la-sha1.Tpo $(DEPDIR)/pam_timestamp_la-sha1.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='sha1.c' object='pam_timestamp_la-sha1.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_timestamp_la_CFLAGS) $(CFLAGS) -c -o pam_timestamp_la-sha1.lo `test -f 'sha1.c' || echo '$(srcdir)/'`sha1.c
+
+pam_timestamp_check-pam_timestamp_check.o: pam_timestamp_check.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_timestamp_check_CFLAGS) $(CFLAGS) -MT pam_timestamp_check-pam_timestamp_check.o -MD -MP -MF $(DEPDIR)/pam_timestamp_check-pam_timestamp_check.Tpo -c -o pam_timestamp_check-pam_timestamp_check.o `test -f 'pam_timestamp_check.c' || echo '$(srcdir)/'`pam_timestamp_check.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pam_timestamp_check-pam_timestamp_check.Tpo $(DEPDIR)/pam_timestamp_check-pam_timestamp_check.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pam_timestamp_check.c' object='pam_timestamp_check-pam_timestamp_check.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_timestamp_check_CFLAGS) $(CFLAGS) -c -o pam_timestamp_check-pam_timestamp_check.o `test -f 'pam_timestamp_check.c' || echo '$(srcdir)/'`pam_timestamp_check.c
+
+pam_timestamp_check-pam_timestamp_check.obj: pam_timestamp_check.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_timestamp_check_CFLAGS) $(CFLAGS) -MT pam_timestamp_check-pam_timestamp_check.obj -MD -MP -MF $(DEPDIR)/pam_timestamp_check-pam_timestamp_check.Tpo -c -o pam_timestamp_check-pam_timestamp_check.obj `if test -f 'pam_timestamp_check.c'; then $(CYGPATH_W) 'pam_timestamp_check.c'; else $(CYGPATH_W) '$(srcdir)/pam_timestamp_check.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pam_timestamp_check-pam_timestamp_check.Tpo $(DEPDIR)/pam_timestamp_check-pam_timestamp_check.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pam_timestamp_check.c' object='pam_timestamp_check-pam_timestamp_check.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pam_timestamp_check_CFLAGS) $(CFLAGS) -c -o pam_timestamp_check-pam_timestamp_check.obj `if test -f 'pam_timestamp_check.c'; then $(CYGPATH_W) 'pam_timestamp_check.c'; else $(CYGPATH_W) '$(srcdir)/pam_timestamp_check.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_timestamp.log: tst-pam_timestamp
+ @p='tst-pam_timestamp'; \
+ b='tst-pam_timestamp'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+hmacfile.log: hmacfile$(EXEEXT)
+ @p='hmacfile$(EXEEXT)'; \
+ b='hmacfile'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) \
+ $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(MANS) $(DATA) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-sbinPROGRAMS clean-securelibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/hmac_openssl_wrapper.Po
+ -rm -f ./$(DEPDIR)/hmacfile.Po
+ -rm -f ./$(DEPDIR)/hmacsha1.Po
+ -rm -f ./$(DEPDIR)/pam_timestamp_check-pam_timestamp_check.Po
+ -rm -f ./$(DEPDIR)/pam_timestamp_la-hmac_openssl_wrapper.Plo
+ -rm -f ./$(DEPDIR)/pam_timestamp_la-hmacsha1.Plo
+ -rm -f ./$(DEPDIR)/pam_timestamp_la-pam_timestamp.Plo
+ -rm -f ./$(DEPDIR)/pam_timestamp_la-sha1.Plo
+ -rm -f ./$(DEPDIR)/sha1.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-sbinPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/hmac_openssl_wrapper.Po
+ -rm -f ./$(DEPDIR)/hmacfile.Po
+ -rm -f ./$(DEPDIR)/hmacsha1.Po
+ -rm -f ./$(DEPDIR)/pam_timestamp_check-pam_timestamp_check.Po
+ -rm -f ./$(DEPDIR)/pam_timestamp_la-hmac_openssl_wrapper.Plo
+ -rm -f ./$(DEPDIR)/pam_timestamp_la-hmacsha1.Plo
+ -rm -f ./$(DEPDIR)/pam_timestamp_la-pam_timestamp.Plo
+ -rm -f ./$(DEPDIR)/pam_timestamp_la-sha1.Plo
+ -rm -f ./$(DEPDIR)/sha1.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-sbinPROGRAMS \
+ uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-sbinPROGRAMS clean-securelibLTLIBRARIES cscopelist-am \
+ ctags ctags-am distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-sbinPROGRAMS \
+ uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_timestamp/README b/modules/pam_timestamp/README
new file mode 100644
index 0000000..e1ed508
--- /dev/null
+++ b/modules/pam_timestamp/README
@@ -0,0 +1,56 @@
+pam_timestamp — Authenticate using cached successful authentication attempts
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+In a nutshell, pam_timestamp caches successful authentication attempts, and
+allows you to use a recent successful attempt as the basis for authentication.
+This is similar mechanism which is used in sudo.
+
+When an application opens a session using pam_timestamp, a timestamp file is
+created in the timestampdir directory for the user. When an application
+attempts to authenticate the user, a pam_timestamp will treat a sufficiently
+recent timestamp file as grounds for succeeding.
+
+The default encryption hash is taken from the HMAC_CRYPTO_ALGO variable from /
+etc/login.defs.
+
+OPTIONS
+
+timestampdir=directory
+
+ Specify an alternate directory where pam_timestamp creates timestamp files.
+
+timestamp_timeout=number
+
+ How long should pam_timestamp treat timestamp as valid after their last
+ modification date (in seconds). Default is 300 seconds.
+
+verbose
+
+ Attempt to inform the user when access is granted.
+
+debug
+
+ Turns on debugging messages sent to syslog(3).
+
+NOTES
+
+Users can get confused when they are not always asked for passwords when
+running a given program. Some users reflexively begin typing information before
+noticing that it is not being asked for.
+
+EXAMPLES
+
+auth sufficient pam_timestamp.so verbose
+auth required pam_unix.so
+
+session required pam_unix.so
+session optional pam_timestamp.so
+
+
+AUTHOR
+
+pam_timestamp was written by Nalin Dahyabhai.
+
diff --git a/modules/pam_timestamp/README.xml b/modules/pam_timestamp/README.xml
new file mode 100644
index 0000000..5b72deb
--- /dev/null
+++ b/modules/pam_timestamp/README.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_timestamp.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_timestamp.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_timestamp-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_timestamp.8.xml" xpointer='xpointer(//refsect1[@id = "pam_timestamp-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_timestamp.8.xml" xpointer='xpointer(//refsect1[@id = "pam_timestamp-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_timestamp.8.xml" xpointer='xpointer(//refsect1[@id = "pam_timestamp-notes"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_timestamp.8.xml" xpointer='xpointer(//refsect1[@id = "pam_timestamp-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_timestamp.8.xml" xpointer='xpointer(//refsect1[@id = "pam_timestamp-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_timestamp/hmac_openssl_wrapper.c b/modules/pam_timestamp/hmac_openssl_wrapper.c
new file mode 100644
index 0000000..926c2fb
--- /dev/null
+++ b/modules/pam_timestamp/hmac_openssl_wrapper.c
@@ -0,0 +1,381 @@
+/* Wrapper for hmac openssl implementation.
+ *
+ * Copyright (c) 2021 Red Hat, Inc.
+ * Written by Iker Pedrosa <ipedrosa@redhat.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+
+#ifdef WITH_OPENSSL
+
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <openssl/evp.h>
+#include <openssl/params.h>
+#include <openssl/core_names.h>
+
+#include <security/pam_ext.h>
+#include <security/pam_modutil.h>
+
+#include "hmac_openssl_wrapper.h"
+
+#define LOGIN_DEFS "/etc/login.defs"
+#define CRYPTO_KEY "HMAC_CRYPTO_ALGO"
+#define DEFAULT_ALGORITHM "SHA512"
+#define MAX_HMAC_LENGTH 512
+#define MAX_KEY_LENGTH EVP_MAX_KEY_LENGTH
+
+static char *
+get_crypto_algorithm(pam_handle_t *pamh, int debug){
+ char *config_value = NULL;
+
+ config_value = pam_modutil_search_key(pamh, LOGIN_DEFS, CRYPTO_KEY);
+
+ if (config_value == NULL) {
+ config_value = strdup(DEFAULT_ALGORITHM);
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "Key [%s] not found, falling back to default algorithm [%s]\n",
+ CRYPTO_KEY, DEFAULT_ALGORITHM);
+ }
+ }
+
+ return config_value;
+}
+
+static int
+generate_key(pam_handle_t *pamh, char **key, size_t key_size)
+{
+ int fd = 0;
+ size_t bytes_read = 0;
+ char * tmp = NULL;
+
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd == -1) {
+ pam_syslog(pamh, LOG_ERR, "Cannot open /dev/urandom: %m");
+ return PAM_AUTH_ERR;
+ }
+
+ tmp = malloc(key_size);
+ if (!tmp) {
+ pam_syslog(pamh, LOG_CRIT, "Not enough memory");
+ close(fd);
+ return PAM_AUTH_ERR;
+ }
+
+ bytes_read = pam_modutil_read(fd, tmp, key_size);
+ close(fd);
+
+ if (bytes_read < key_size) {
+ pam_syslog(pamh, LOG_ERR, "Short read on random device");
+ free(tmp);
+ return PAM_AUTH_ERR;
+ }
+
+ *key = tmp;
+
+ return PAM_SUCCESS;
+}
+
+static int
+read_file(pam_handle_t *pamh, int fd, char **text, size_t *text_length)
+{
+ struct stat st;
+ size_t bytes_read = 0;
+ char *tmp = NULL;
+
+ if (fstat(fd, &st) == -1) {
+ pam_syslog(pamh, LOG_ERR, "Unable to stat file: %m");
+ close(fd);
+ return PAM_AUTH_ERR;
+ }
+
+ if (st.st_size == 0) {
+ pam_syslog(pamh, LOG_ERR, "Key file size cannot be 0");
+ close(fd);
+ return PAM_AUTH_ERR;
+ }
+
+ tmp = malloc(st.st_size);
+ if (!tmp) {
+ pam_syslog(pamh, LOG_CRIT, "Not enough memory");
+ close(fd);
+ return PAM_AUTH_ERR;
+ }
+
+ bytes_read = pam_modutil_read(fd, tmp, st.st_size);
+ close(fd);
+
+ if (bytes_read < (size_t)st.st_size) {
+ pam_syslog(pamh, LOG_ERR, "Short read on key file");
+ memset(tmp, 0, st.st_size);
+ free(tmp);
+ return PAM_AUTH_ERR;
+ }
+
+ *text = tmp;
+ *text_length = st.st_size;
+
+ return PAM_SUCCESS;
+}
+
+static int
+write_file(pam_handle_t *pamh, const char *file_name, char *text,
+ size_t text_length, uid_t owner, gid_t group)
+{
+ int fd = 0;
+ size_t bytes_written = 0;
+
+ fd = open(file_name,
+ O_WRONLY | O_CREAT | O_TRUNC,
+ S_IRUSR | S_IWUSR);
+ if (fd == -1) {
+ pam_syslog(pamh, LOG_ERR, "Unable to open [%s]: %m", file_name);
+ memset(text, 0, text_length);
+ free(text);
+ return PAM_AUTH_ERR;
+ }
+
+ if (fchown(fd, owner, group) == -1) {
+ pam_syslog(pamh, LOG_ERR, "Unable to change ownership [%s]: %m", file_name);
+ memset(text, 0, text_length);
+ free(text);
+ close(fd);
+ return PAM_AUTH_ERR;
+ }
+
+ bytes_written = pam_modutil_write(fd, text, text_length);
+ close(fd);
+
+ if (bytes_written < text_length) {
+ pam_syslog(pamh, LOG_ERR, "Short write on %s", file_name);
+ free(text);
+ return PAM_AUTH_ERR;
+ }
+
+ return PAM_SUCCESS;
+}
+
+static int
+key_management(pam_handle_t *pamh, const char *file_name, char **text,
+ size_t text_length, uid_t owner, gid_t group)
+{
+ int fd = 0;
+
+ fd = open(file_name, O_RDONLY | O_NOFOLLOW);
+ if (fd == -1) {
+ if (errno == ENOENT) {
+ if (generate_key(pamh, text, text_length)) {
+ pam_syslog(pamh, LOG_ERR, "Unable to generate key");
+ return PAM_AUTH_ERR;
+ }
+
+ if (write_file(pamh, file_name, *text, text_length, owner, group)) {
+ pam_syslog(pamh, LOG_ERR, "Unable to write key");
+ return PAM_AUTH_ERR;
+ }
+ } else {
+ pam_syslog(pamh, LOG_ERR, "Unable to open %s: %m", file_name);
+ return PAM_AUTH_ERR;
+ }
+ } else {
+ if (read_file(pamh, fd, text, &text_length)) {
+ pam_syslog(pamh, LOG_ERR, "Error reading key file %s\n", file_name);
+ return PAM_AUTH_ERR;
+ }
+ }
+
+ return PAM_SUCCESS;
+}
+
+static int
+hmac_management(pam_handle_t *pamh, int debug, void **out, size_t *out_length,
+ char *key, size_t key_length,
+ const void *text, size_t text_length)
+{
+ int ret = PAM_AUTH_ERR;
+ EVP_MAC *evp_mac = NULL;
+ EVP_MAC_CTX *ctx = NULL;
+ unsigned char *hmac_message = NULL;
+ size_t hmac_length;
+ char *algo = NULL;
+ OSSL_PARAM subalg_param[] = { OSSL_PARAM_END, OSSL_PARAM_END };
+
+ algo = get_crypto_algorithm(pamh, debug);
+
+ subalg_param[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
+ algo,
+ 0);
+
+ evp_mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
+ if (evp_mac == NULL) {
+ pam_syslog(pamh, LOG_ERR, "Unable to create hmac implementation");
+ goto done;
+ }
+
+ ctx = EVP_MAC_CTX_new(evp_mac);
+ if (ctx == NULL) {
+ pam_syslog(pamh, LOG_ERR, "Unable to create hmac context");
+ goto done;
+ }
+
+ ret = EVP_MAC_init(ctx, (const unsigned char *)key, key_length, subalg_param);
+ if (ret == 0) {
+ pam_syslog(pamh, LOG_ERR, "Unable to initialize hmac context");
+ goto done;
+ }
+
+ ret = EVP_MAC_update(ctx, (const unsigned char *)text, text_length);
+ if (ret == 0) {
+ pam_syslog(pamh, LOG_ERR, "Unable to update hmac context");
+ goto done;
+ }
+
+ hmac_message = (unsigned char*)malloc(sizeof(unsigned char) * MAX_HMAC_LENGTH);
+ if (!hmac_message) {
+ pam_syslog(pamh, LOG_CRIT, "Not enough memory");
+ goto done;
+ }
+
+ ret = EVP_MAC_final(ctx, hmac_message, &hmac_length, MAX_HMAC_LENGTH);
+ if (ret == 0) {
+ pam_syslog(pamh, LOG_ERR, "Unable to calculate hmac message");
+ goto done;
+ }
+
+ *out_length = hmac_length;
+ *out = malloc(*out_length);
+ if (*out == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "Not enough memory");
+ goto done;
+ }
+
+ memcpy(*out, hmac_message, *out_length);
+ ret = PAM_SUCCESS;
+
+done:
+ if (hmac_message != NULL) {
+ free(hmac_message);
+ }
+ if (key != NULL) {
+ memset(key, 0, key_length);
+ free(key);
+ }
+ if (ctx != NULL) {
+ EVP_MAC_CTX_free(ctx);
+ }
+ if (evp_mac != NULL) {
+ EVP_MAC_free(evp_mac);
+ }
+ free(algo);
+
+ return ret;
+}
+
+int
+hmac_size(pam_handle_t *pamh, int debug, size_t *hmac_length)
+{
+ int ret = PAM_AUTH_ERR;
+ EVP_MAC *evp_mac = NULL;
+ EVP_MAC_CTX *ctx = NULL;
+ const unsigned char key[] = "ThisIsJustAKey";
+ size_t key_length = MAX_KEY_LENGTH;
+ char *algo = NULL;
+ OSSL_PARAM subalg_param[] = { OSSL_PARAM_END, OSSL_PARAM_END };
+
+ algo = get_crypto_algorithm(pamh, debug);
+
+ subalg_param[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
+ algo,
+ 0);
+
+ evp_mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
+ if (evp_mac == NULL) {
+ pam_syslog(pamh, LOG_ERR, "Unable to create hmac implementation");
+ goto done;
+ }
+
+ ctx = EVP_MAC_CTX_new(evp_mac);
+ if (ctx == NULL) {
+ pam_syslog(pamh, LOG_ERR, "Unable to create hmac context");
+ goto done;
+ }
+
+ ret = EVP_MAC_init(ctx, key, key_length, subalg_param);
+ if (ret == 0) {
+ pam_syslog(pamh, LOG_ERR, "Unable to initialize hmac context");
+ goto done;
+ }
+
+ *hmac_length = EVP_MAC_CTX_get_mac_size(ctx);
+ ret = PAM_SUCCESS;
+
+done:
+ if (ctx != NULL) {
+ EVP_MAC_CTX_free(ctx);
+ }
+ if (evp_mac != NULL) {
+ EVP_MAC_free(evp_mac);
+ }
+ free(algo);
+
+ return ret;
+}
+
+int
+hmac_generate(pam_handle_t *pamh, int debug, void **mac, size_t *mac_length,
+ const char *key_file, uid_t owner, gid_t group,
+ const void *text, size_t text_length)
+{
+ char *key = NULL;
+ size_t key_length = MAX_KEY_LENGTH;
+
+ if (key_management(pamh, key_file, &key, key_length, owner, group)) {
+ return PAM_AUTH_ERR;
+ }
+
+ if (hmac_management(pamh, debug, mac, mac_length, key, key_length,
+ text, text_length)) {
+ return PAM_AUTH_ERR;
+ }
+
+ return PAM_SUCCESS;
+}
+
+#endif /* WITH_OPENSSL */
diff --git a/modules/pam_timestamp/hmac_openssl_wrapper.h b/modules/pam_timestamp/hmac_openssl_wrapper.h
new file mode 100644
index 0000000..cc27c81
--- /dev/null
+++ b/modules/pam_timestamp/hmac_openssl_wrapper.h
@@ -0,0 +1,57 @@
+/* Wrapper for hmac openssl implementation.
+ *
+ * Copyright (c) 2021 Red Hat, Inc.
+ * Written by Iker Pedrosa <ipedrosa@redhat.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef PAM_TIMESTAMP_HMAC_OPENSSL_WRAPPER_H
+#define PAM_TIMESTAMP_HMAC_OPENSSL_WRAPPER_H
+
+#include "config.h"
+
+#ifdef WITH_OPENSSL
+
+#include <openssl/hmac.h>
+#include <security/pam_modules.h>
+
+int
+hmac_size(pam_handle_t *pamh, int debug, size_t *hmac_length);
+
+int
+hmac_generate(pam_handle_t *pamh, int debug, void **mac, size_t *mac_length,
+ const char *key_file, uid_t owner, gid_t group,
+ const void *text, size_t text_length);
+
+#endif /* WITH_OPENSSL */
+#endif /* PAM_TIMESTAMP_HMAC_OPENSSL_WRAPPER_H */
diff --git a/modules/pam_timestamp/hmacfile.c b/modules/pam_timestamp/hmacfile.c
new file mode 100644
index 0000000..371f814
--- /dev/null
+++ b/modules/pam_timestamp/hmacfile.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2003,2004 Red Hat, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "pam_inline.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "hmacsha1.h"
+
+static void
+testvectors(void)
+{
+ void *hmac;
+ size_t hmac_len;
+ size_t i, j;
+ char hex[3];
+ struct vector {
+ const char *key;
+ int key_len;
+ const char *data;
+ int data_len;
+ const char *hmac;
+ } vectors[] = {
+ {
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", 20,
+ "Hi There", 8,
+ "b617318655057264e28bc0b6fb378c8ef146be00",
+ },
+
+#ifdef HMAC_ALLOW_SHORT_KEYS
+ {
+ "Jefe", 4,
+ "what do ya want for nothing?", 28,
+ "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79",
+ },
+#endif
+
+ {
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa", 20,
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd", 50,
+ "125d7342b9ac11cd91a39af48aa17b4f63f175d3",
+ },
+
+ {
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", 25,
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd",
+ 50,
+ "4c9007f4026250c6bc8414f9bf50c86c2d7235da",
+ },
+
+ {
+ "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", 20,
+ "Test With Truncation", 20,
+ "4c1a03424b55e07fe7f27be1d58bb9324a9a5a04",
+ },
+
+ {
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ 80,
+ "Test Using Larger Than Block-Size Key - Hash Key First", 54,
+ "aa4ae5e15272d00e95705637ce8a3b55ed402112",
+ },
+
+ {
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa",
+ 80,
+ "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73,
+ "e8e99d0f45237d786d6bbaa7965c7808bbff1a91",
+ },
+ };
+ for (i = 0; i < PAM_ARRAY_SIZE(vectors); i++) {
+ hmac = NULL;
+ hmac_len = 0;
+ hmac_sha1_generate(&hmac, &hmac_len,
+ vectors[i].key, vectors[i].key_len,
+ vectors[i].data, vectors[i].data_len);
+ if (hmac != NULL) {
+ unsigned char *hmacc = hmac;
+ for (j = 0; j < hmac_len; j++) {
+ snprintf(hex, sizeof(hex), "%02x",
+ hmacc[j] & 0xff);
+ if (strncasecmp(hex,
+ vectors[i].hmac + 2 * j,
+ 2) != 0) {
+ printf("Incorrect result for vector %lu\n",
+ (unsigned long) i + 1);
+ exit(1);
+
+ }
+ }
+ free(hmac);
+ } else {
+ printf("Error in vector %lu.\n",
+ (unsigned long) i + 1);
+ exit(1);
+ }
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ void *hmac;
+ size_t maclen;
+ const char *keyfile;
+ int i;
+ size_t j;
+
+ testvectors();
+
+ keyfile = argv[1];
+ for (i = 2; i < argc; i++) {
+ hmac_sha1_generate_file(NULL, &hmac, &maclen, keyfile, -1, -1,
+ argv[i], strlen(argv[i]));
+ if (hmac != NULL) {
+ unsigned char *hmacc = hmac;
+ for (j = 0; j < maclen; j++) {
+ printf("%02x", hmacc[j] & 0xff);
+ }
+ printf(" %s\n", argv[i]);
+ free(hmac);
+ }
+ }
+ return 0;
+}
diff --git a/modules/pam_timestamp/hmacsha1.c b/modules/pam_timestamp/hmacsha1.c
new file mode 100644
index 0000000..45a3cac
--- /dev/null
+++ b/modules/pam_timestamp/hmacsha1.c
@@ -0,0 +1,295 @@
+/* An implementation of HMAC using SHA-1.
+ *
+ * Copyright (c) 2003 Red Hat, Inc.
+ * Written by Nalin Dahyabhai <nalin@redhat.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/* See RFC 2104 for descriptions. */
+#include "config.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <security/pam_ext.h>
+#include "hmacsha1.h"
+#include "sha1.h"
+
+#define MINIMUM_KEY_SIZE SHA1_OUTPUT_SIZE
+#define MAXIMUM_KEY_SIZE SHA1_BLOCK_SIZE
+
+static void
+hmac_key_create(pam_handle_t *pamh, const char *filename, size_t key_size,
+ uid_t owner, gid_t group)
+{
+ int randfd, keyfd, i;
+ size_t count;
+ char *key;
+
+ /* Open the destination file. */
+ keyfd = open(filename,
+ O_WRONLY | O_CREAT | O_EXCL | O_TRUNC,
+ S_IRUSR | S_IWUSR);
+ if (keyfd == -1) {
+ pam_syslog(pamh, LOG_ERR, "Cannot create %s: %m", filename);
+ return;
+ }
+
+
+ if (fchown(keyfd, owner, group) == -1) {
+ pam_syslog(pamh, LOG_ERR, "Cannot chown %s: %m", filename);
+ close(keyfd);
+ return;
+ }
+
+ /* Open the random device to get key data. */
+ randfd = open("/dev/urandom", O_RDONLY);
+ if (randfd == -1) {
+ pam_syslog(pamh, LOG_ERR, "Cannot open /dev/urandom: %m");
+ close(keyfd);
+ return;
+ }
+
+ /* Read random data for use as the key. */
+ key = malloc(key_size);
+ count = 0;
+ if (!key) {
+ close(keyfd);
+ close(randfd);
+ return;
+ }
+ while (count < key_size) {
+ i = read(randfd, key + count, key_size - count);
+ if ((i == 0) || (i == -1)) {
+ break;
+ }
+ count += i;
+ }
+
+ close(randfd);
+
+ /* If we didn't get enough, stop here. */
+ if (count < key_size) {
+ pam_syslog(pamh, LOG_ERR, "Short read on random device");
+ memset(key, 0, key_size);
+ free(key);
+ close(keyfd);
+ return;
+ }
+
+ /* Now write the key. */
+ count = 0;
+ while (count < key_size) {
+ i = write(keyfd, key + count, key_size - count);
+ if ((i == 0) || (i == -1)) {
+ break;
+ }
+ count += i;
+ }
+ memset(key, 0, key_size);
+ free(key);
+ close(keyfd);
+}
+
+static void
+hmac_key_read(pam_handle_t *pamh, const char *filename, size_t default_key_size,
+ uid_t owner, gid_t group,
+ void **key, size_t *key_size)
+{
+ char *tmp;
+ int keyfd, i, count;
+ struct stat st;
+
+ tmp = NULL;
+ *key = NULL;
+ *key_size = 0;
+
+ /* Try to open the key file. */
+ keyfd = open(filename, O_RDONLY);
+ if (keyfd == -1) {
+ /* No such thing? Create it. */
+ if (errno == ENOENT) {
+ hmac_key_create(pamh, filename, default_key_size,
+ owner, group);
+ keyfd = open(filename, O_RDONLY);
+ } else {
+ pam_syslog(pamh, LOG_ERR, "Cannot open %s: %m", filename);
+ }
+ if (keyfd == -1)
+ return;
+ }
+
+ /* If we failed to open the file, we're done. */
+ if (fstat(keyfd, &st) == -1) {
+ close(keyfd);
+ return;
+ }
+
+ /* Read the contents of the file. */
+ tmp = malloc(st.st_size);
+ if (!tmp) {
+ close(keyfd);
+ return;
+ }
+
+ count = 0;
+ while (count < st.st_size) {
+ i = read(keyfd, tmp + count, st.st_size - count);
+ if ((i == 0) || (i == -1)) {
+ break;
+ }
+ count += i;
+ }
+ close(keyfd);
+
+ /* Require that we got the expected amount of data. */
+ if (count < st.st_size) {
+ memset(tmp, 0, st.st_size);
+ free(tmp);
+ return;
+ }
+
+ /* Pass the key back. */
+ *key = tmp;
+ *key_size = st.st_size;
+}
+
+static void
+xor_block(unsigned char *p, unsigned char byte, size_t length)
+{
+ size_t i;
+ for (i = 0; i < length; i++) {
+ p[i] = p[i] ^ byte;
+ }
+}
+
+void
+hmac_sha1_generate(void **mac, size_t *mac_length,
+ const void *raw_key, size_t raw_key_size,
+ const void *text, size_t text_length)
+{
+ unsigned char key[MAXIMUM_KEY_SIZE], tmp_key[MAXIMUM_KEY_SIZE];
+ size_t maximum_key_size = SHA1_BLOCK_SIZE,
+ minimum_key_size = SHA1_OUTPUT_SIZE;
+ const unsigned char ipad = 0x36, opad = 0x5c;
+ struct sha1_context sha1;
+ unsigned char inner[SHA1_OUTPUT_SIZE], outer[SHA1_OUTPUT_SIZE];
+
+ *mac = NULL;
+ *mac_length = 0;
+
+#ifndef HMAC_ALLOW_SHORT_KEYS
+ /* If the key is too short, don't bother. */
+ if (raw_key_size < minimum_key_size) {
+ return;
+ }
+#endif
+
+ /* If the key is too long, "compress" it, else copy it and pad it
+ * out with zero bytes. */
+ memset(key, 0, sizeof(key));
+ if (raw_key_size > maximum_key_size) {
+ sha1_init(&sha1);
+ sha1_update(&sha1, raw_key, raw_key_size);
+ sha1_output(&sha1, key);
+ } else {
+ memmove(key, raw_key, raw_key_size);
+ }
+
+ /* Generate the inner sum. */
+ memcpy(tmp_key, key, sizeof(tmp_key));
+ xor_block(tmp_key, ipad, sizeof(tmp_key));
+
+ sha1_init(&sha1);
+ sha1_update(&sha1, tmp_key, sizeof(tmp_key));
+ sha1_update(&sha1, text, text_length);
+ sha1_output(&sha1, inner);
+
+ /* Generate the outer sum. */
+ memcpy(tmp_key, key, sizeof(tmp_key));
+ xor_block(tmp_key, opad, sizeof(tmp_key));
+
+ sha1_init(&sha1);
+ sha1_update(&sha1, tmp_key, sizeof(tmp_key));
+ sha1_update(&sha1, inner, sizeof(inner));
+ sha1_output(&sha1, outer);
+
+ /* We don't need any of the keys any more. */
+ memset(key, 0, sizeof(key));
+ memset(tmp_key, 0, sizeof(tmp_key));
+
+ /* Allocate space to store the output. */
+ *mac_length = sizeof(outer);
+ *mac = malloc(*mac_length);
+ if (*mac == NULL) {
+ *mac_length = 0;
+ return;
+ }
+
+ memcpy(*mac, outer, *mac_length);
+}
+
+void
+hmac_sha1_generate_file(pam_handle_t *pamh, void **mac, size_t *mac_length,
+ const char *keyfile, uid_t owner, gid_t group,
+ const void *text, size_t text_length)
+{
+ void *key;
+ size_t key_length;
+
+ hmac_key_read(pamh, keyfile,
+ MAXIMUM_KEY_SIZE, owner, group,
+ &key, &key_length);
+ if (key == NULL) {
+ *mac = NULL;
+ *mac_length = 0;
+ return;
+ }
+ hmac_sha1_generate(mac, mac_length,
+ key, key_length,
+ text, text_length);
+ memset(key, 0, key_length);
+ free(key);
+}
+
+size_t
+hmac_sha1_size(void)
+{
+ return SHA1_OUTPUT_SIZE;
+}
diff --git a/modules/pam_timestamp/hmacsha1.h b/modules/pam_timestamp/hmacsha1.h
new file mode 100644
index 0000000..200d1d0
--- /dev/null
+++ b/modules/pam_timestamp/hmacsha1.h
@@ -0,0 +1,15 @@
+#ifndef pam_timestamp_hmacfile_h
+#define pam_timestamp_hmacfile_h
+
+#include <sys/types.h>
+#include <security/pam_modules.h>
+
+size_t hmac_sha1_size(void);
+void hmac_sha1_generate(void **mac, size_t *mac_length,
+ const void *key, size_t key_length,
+ const void *text, size_t text_length);
+void hmac_sha1_generate_file(pam_handle_t *pamh, void **mac, size_t *mac_length,
+ const char *keyfile, uid_t owner, gid_t group,
+ const void *text, size_t text_length);
+
+#endif
diff --git a/modules/pam_timestamp/pam_timestamp.8 b/modules/pam_timestamp/pam_timestamp.8
new file mode 100644
index 0000000..cd8195d
--- /dev/null
+++ b/modules/pam_timestamp/pam_timestamp.8
@@ -0,0 +1,135 @@
+'\" t
+.\" Title: pam_timestamp
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_TIMESTAMP" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_timestamp \- Authenticate using cached successful authentication attempts
+.SH "SYNOPSIS"
+.HP \w'\fBpam_timestamp\&.so\fR\ 'u
+\fBpam_timestamp\&.so\fR [timestampdir=\fIdirectory\fR] [timestamp_timeout=\fInumber\fR] [verbose] [debug]
+.SH "DESCRIPTION"
+.PP
+In a nutshell,
+\fIpam_timestamp\fR
+caches successful authentication attempts, and allows you to use a recent successful attempt as the basis for authentication\&. This is similar mechanism which is used in
+\fBsudo\fR\&.
+.PP
+When an application opens a session using
+\fIpam_timestamp\fR, a timestamp file is created in the
+\fItimestampdir\fR
+directory for the user\&. When an application attempts to authenticate the user, a
+\fIpam_timestamp\fR
+will treat a sufficiently recent timestamp file as grounds for succeeding\&.
+.PP
+The default encryption hash is taken from the
+\fBHMAC_CRYPTO_ALGO\fR
+variable from
+\fI/etc/login\&.defs\fR\&.
+.SH "OPTIONS"
+.PP
+\fBtimestampdir=\fR\fB\fIdirectory\fR\fR
+.RS 4
+Specify an alternate directory where
+\fIpam_timestamp\fR
+creates timestamp files\&.
+.RE
+.PP
+\fBtimestamp_timeout=\fR\fB\fInumber\fR\fR
+.RS 4
+How long should
+\fIpam_timestamp\fR
+treat timestamp as valid after their last modification date (in seconds)\&. Default is 300 seconds\&.
+.RE
+.PP
+\fBverbose\fR
+.RS 4
+Attempt to inform the user when access is granted\&.
+.RE
+.PP
+\fBdebug\fR
+.RS 4
+Turns on debugging messages sent to
+\fBsyslog\fR(3)\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+The
+\fBauth\fR
+and
+\fBsession\fR
+module types are provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_AUTH_ERR
+.RS 4
+The module was not able to retrieve the user name or no valid timestamp file was found\&.
+.RE
+.PP
+PAM_SUCCESS
+.RS 4
+Everything was successful\&.
+.RE
+.PP
+PAM_SESSION_ERR
+.RS 4
+Timestamp file could not be created or updated\&.
+.RE
+.SH "NOTES"
+.PP
+Users can get confused when they are not always asked for passwords when running a given program\&. Some users reflexively begin typing information before noticing that it is not being asked for\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+auth sufficient pam_timestamp\&.so verbose
+auth required pam_unix\&.so
+
+session required pam_unix\&.so
+session optional pam_timestamp\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "FILES"
+.PP
+/var/run/pam_timestamp/\&.\&.\&.
+.RS 4
+timestamp files and directories
+.RE
+.SH "SEE ALSO"
+.PP
+\fBpam_timestamp_check\fR(8),
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_timestamp was written by Nalin Dahyabhai\&.
diff --git a/modules/pam_timestamp/pam_timestamp.8.xml b/modules/pam_timestamp/pam_timestamp.8.xml
new file mode 100644
index 0000000..83e5aea
--- /dev/null
+++ b/modules/pam_timestamp/pam_timestamp.8.xml
@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_timestamp">
+
+ <refmeta>
+ <refentrytitle>pam_timestamp</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_timestamp-name">
+ <refname>pam_timestamp</refname>
+ <refpurpose>Authenticate using cached successful authentication attempts</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_timestamp-cmdsynopsis">
+ <command>pam_timestamp.so</command>
+ <arg choice="opt">
+ timestampdir=<replaceable>directory</replaceable>
+ </arg>
+ <arg choice="opt">
+ timestamp_timeout=<replaceable>number</replaceable>
+ </arg>
+ <arg choice="opt">
+ verbose
+ </arg>
+ <arg choice="opt">
+ debug
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_timestamp-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ In a nutshell, <emphasis>pam_timestamp</emphasis> caches successful
+authentication attempts, and allows you to use a recent successful attempt as
+the basis for authentication. This is similar mechanism which is used in
+<command>sudo</command>.
+ </para>
+ <para>
+ When an application opens a session using <emphasis>pam_timestamp</emphasis>,
+a timestamp file is created in the <emphasis>timestampdir</emphasis> directory
+for the user. When an application attempts to authenticate the user, a
+<emphasis>pam_timestamp</emphasis> will treat a sufficiently recent timestamp
+file as grounds for succeeding.
+ </para>
+ <para condition="openssl_hmac">
+ The default encryption hash is taken from the
+ <emphasis remap='B'>HMAC_CRYPTO_ALGO</emphasis> variable from
+ <emphasis>/etc/login.defs</emphasis>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_timestamp-options">
+
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>timestampdir=<replaceable>directory</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Specify an alternate directory where
+ <emphasis>pam_timestamp</emphasis> creates timestamp files.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>timestamp_timeout=<replaceable>number</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ How long should <emphasis>pam_timestamp</emphasis>
+ treat timestamp as valid after their
+ last modification date (in seconds). Default is 300 seconds.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>verbose</option>
+ </term>
+ <listitem>
+ <para>
+ Attempt to inform the user when access is granted.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Turns on debugging messages sent to <citerefentry>
+ <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_timestamp-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ The <option>auth</option> and <option>session</option>
+ module types are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_timestamp-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_AUTH_ERR</term>
+ <listitem>
+ <para>
+ The module was not able to retrieve the user name or
+ no valid timestamp file was found.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Everything was successful.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SESSION_ERR</term>
+ <listitem>
+ <para>
+ Timestamp file could not be created or updated.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_timestamp-notes'>
+ <title>NOTES</title>
+ <para>
+ Users can get confused when they are not always asked for passwords when
+running a given program. Some users reflexively begin typing information before
+noticing that it is not being asked for.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_timestamp-examples'>
+ <title>EXAMPLES</title>
+ <programlisting>
+auth sufficient pam_timestamp.so verbose
+auth required pam_unix.so
+
+session required pam_unix.so
+session optional pam_timestamp.so
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id="pam_timestamp-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/var/run/pam_timestamp/...</filename></term>
+ <listitem>
+ <para>timestamp files and directories</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_timestamp-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam_timestamp_check</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_timestamp-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_timestamp was written by Nalin Dahyabhai.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_timestamp/pam_timestamp.c b/modules/pam_timestamp/pam_timestamp.c
new file mode 100644
index 0000000..01dd138
--- /dev/null
+++ b/modules/pam_timestamp/pam_timestamp.c
@@ -0,0 +1,873 @@
+/******************************************************************************
+ * A module for Linux-PAM that will cache authentication results, inspired by
+ * (and implemented with an eye toward being mixable with) sudo.
+ *
+ * Copyright (c) 2002 Red Hat, Inc.
+ * Written by Nalin Dahyabhai <nalin@redhat.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <utmp.h>
+#include <syslog.h>
+#include <paths.h>
+#ifdef WITH_OPENSSL
+#include "hmac_openssl_wrapper.h"
+#else
+#include "hmacsha1.h"
+#endif /* WITH_OPENSSL */
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+#include <security/pam_ext.h>
+#include <security/pam_modutil.h>
+#include "pam_inline.h"
+
+/* The default timeout we use is 5 minutes, which matches the sudo default
+ * for the timestamp_timeout parameter. */
+#define DEFAULT_TIMESTAMP_TIMEOUT (5 * 60)
+#define MODULE "pam_timestamp"
+#define TIMESTAMPDIR _PATH_VARRUN MODULE
+#define TIMESTAMPKEY TIMESTAMPDIR "/_pam_timestamp_key"
+
+/* Various buffers we use need to be at least as large as either PATH_MAX or
+ * LINE_MAX, so choose the larger of the two. */
+#if (LINE_MAX > PATH_MAX)
+#define BUFLEN LINE_MAX
+#else
+#define BUFLEN PATH_MAX
+#endif
+
+#define ROOT_USER 0
+#define ROOT_GROUP 0
+
+/* Return PAM_SUCCESS if the given directory looks "safe". */
+static int
+check_dir_perms(pam_handle_t *pamh, const char *tdir)
+{
+ char scratch[BUFLEN];
+ struct stat st;
+ int i;
+ /* Check that the directory is "safe". */
+ if ((tdir == NULL) || (strlen(tdir) == 0)) {
+ return PAM_AUTH_ERR;
+ }
+ /* Iterate over the path, checking intermediate directories. */
+ memset(scratch, 0, sizeof(scratch));
+ for (i = 0; (tdir[i] != '\0') && (i < (int)sizeof(scratch)); i++) {
+ scratch[i] = tdir[i];
+ if ((scratch[i] == '/') || (tdir[i + 1] == '\0')) {
+ /* We now have the name of a directory in the path, so
+ * we need to check it. */
+ if ((lstat(scratch, &st) == -1) && (errno != ENOENT)) {
+ pam_syslog(pamh, LOG_ERR,
+ "unable to read `%s': %m",
+ scratch);
+ return PAM_AUTH_ERR;
+ }
+ if (!S_ISDIR(st.st_mode)) {
+ pam_syslog(pamh, LOG_ERR,
+ "`%s' is not a directory",
+ scratch);
+ return PAM_AUTH_ERR;
+ }
+ if (S_ISLNK(st.st_mode)) {
+ pam_syslog(pamh, LOG_ERR,
+ "`%s' is a symbolic link",
+ scratch);
+ return PAM_AUTH_ERR;
+ }
+ if (st.st_uid != 0) {
+ pam_syslog(pamh, LOG_ERR,
+ "`%s' owner UID != 0",
+ scratch);
+ return PAM_AUTH_ERR;
+ }
+ if (st.st_gid != 0) {
+ pam_syslog(pamh, LOG_ERR,
+ "`%s' owner GID != 0",
+ scratch);
+ return PAM_AUTH_ERR;
+ }
+ if ((st.st_mode & (S_IWGRP | S_IWOTH)) != 0) {
+ pam_syslog(pamh, LOG_ERR,
+ "`%s' permissions are lax",
+ scratch);
+ return PAM_AUTH_ERR;
+ }
+ }
+ }
+ return PAM_SUCCESS;
+}
+
+/* Validate a tty pathname as actually belonging to a tty, and return its base
+ * name if it's valid. */
+static const char *
+check_tty(const char *tty)
+{
+ /* Check that we're not being set up to take a fall. */
+ if ((tty == NULL) || (strlen(tty) == 0)) {
+ return NULL;
+ }
+ /* Pull out the meaningful part of the tty's name. */
+ if (strchr(tty, '/') != NULL) {
+ if (pam_str_skip_prefix(tty, "/dev/") == NULL) {
+ /* Make sure the device node is actually in /dev/,
+ * noted by Michal Zalewski. */
+ return NULL;
+ }
+ tty = strrchr(tty, '/') + 1;
+ }
+ /* Make sure the tty wasn't actually a directory (no basename). */
+ if (!strlen(tty) || !strcmp(tty, ".") || !strcmp(tty, "..")) {
+ return NULL;
+ }
+ return tty;
+}
+
+/* Determine the right path name for a given user's timestamp. */
+static int
+format_timestamp_name(char *path, size_t len,
+ const char *timestamp_dir,
+ const char *tty,
+ const char *ruser,
+ const char *user)
+{
+ if (strcmp(ruser, user) == 0) {
+ return snprintf(path, len, "%s/%s/%s", timestamp_dir,
+ ruser, tty);
+ } else {
+ return snprintf(path, len, "%s/%s/%s:%s", timestamp_dir,
+ ruser, tty, user);
+ }
+}
+
+/* Check if a given timestamp date, when compared to a current time, fits
+ * within the given interval. */
+static int
+timestamp_good(time_t then, time_t now, time_t interval)
+{
+ if (((now >= then) && ((now - then) < interval)) ||
+ ((now < then) && ((then - now) < (2 * interval)))) {
+ return PAM_SUCCESS;
+ }
+ return PAM_AUTH_ERR;
+}
+
+static int
+check_login_time(const char *ruser, time_t timestamp)
+{
+ struct utmp utbuf, *ut;
+ time_t oldest_login = 0;
+
+ setutent();
+ while(
+#ifdef HAVE_GETUTENT_R
+ !getutent_r(&utbuf, &ut)
+#else
+ (ut = getutent()) != NULL
+#endif
+ ) {
+ if (ut->ut_type != USER_PROCESS) {
+ continue;
+ }
+ if (strncmp(ruser, ut->ut_user, sizeof(ut->ut_user)) != 0) {
+ continue;
+ }
+ if (oldest_login == 0 || oldest_login > ut->ut_tv.tv_sec) {
+ oldest_login = ut->ut_tv.tv_sec;
+ }
+ }
+ endutent();
+ if(oldest_login == 0 || timestamp < oldest_login) {
+ return PAM_AUTH_ERR;
+ }
+ return PAM_SUCCESS;
+}
+
+#ifndef PAM_TIMESTAMP_MAIN
+static int
+get_ruser(pam_handle_t *pamh, char *ruserbuf, size_t ruserbuflen)
+{
+ const void *ruser;
+ struct passwd *pwd;
+
+ if (ruserbuf == NULL || ruserbuflen < 1)
+ return -2;
+ /* Get the name of the source user. */
+ if (pam_get_item(pamh, PAM_RUSER, &ruser) != PAM_SUCCESS) {
+ ruser = NULL;
+ }
+ if ((ruser == NULL) || (strlen(ruser) == 0)) {
+ /* Barring that, use the current RUID. */
+ pwd = pam_modutil_getpwuid(pamh, getuid());
+ if (pwd != NULL) {
+ ruser = pwd->pw_name;
+ }
+ } else {
+ /*
+ * This ruser is used by format_timestamp_name as a component
+ * of constructed timestamp pathname, so ".", "..", and '/'
+ * are disallowed to avoid potential path traversal issues.
+ */
+ if (!strcmp(ruser, ".") ||
+ !strcmp(ruser, "..") ||
+ strchr(ruser, '/')) {
+ ruser = NULL;
+ }
+ }
+ if (ruser == NULL || strlen(ruser) >= ruserbuflen) {
+ *ruserbuf = '\0';
+ return -1;
+ }
+ strcpy(ruserbuf, ruser);
+ return 0;
+}
+
+/* Get the path to the timestamp to use. */
+static int
+get_timestamp_name(pam_handle_t *pamh, int argc, const char **argv,
+ char *path, size_t len)
+{
+ const char *user, *tty;
+ const void *void_tty;
+ const char *tdir = TIMESTAMPDIR;
+ char ruser[BUFLEN];
+ int i, debug = 0;
+
+ /* Parse arguments. */
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "debug") == 0) {
+ debug = 1;
+ }
+ }
+ for (i = 0; i < argc; i++) {
+ const char *str;
+
+ if ((str = pam_str_skip_prefix(argv[i], "timestampdir=")) != NULL) {
+ tdir = str;
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "storing timestamps in `%s'",
+ tdir);
+ }
+ }
+ }
+ i = check_dir_perms(pamh, tdir);
+ if (i != PAM_SUCCESS) {
+ return i;
+ }
+ /* Get the name of the target user. */
+ if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS || user[0] == '\0') {
+ return PAM_AUTH_ERR;
+ }
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG, "becoming user `%s'", user);
+ }
+ /* Get the name of the source user. */
+ if (get_ruser(pamh, ruser, sizeof(ruser)) || strlen(ruser) == 0) {
+ return PAM_AUTH_ERR;
+ }
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG, "currently user `%s'", ruser);
+ }
+ /* Get the name of the terminal. */
+ if (pam_get_item(pamh, PAM_TTY, &void_tty) != PAM_SUCCESS) {
+ tty = NULL;
+ } else {
+ tty = void_tty;
+ }
+ if ((tty == NULL) || (strlen(tty) == 0)) {
+ tty = ttyname(STDIN_FILENO);
+ if ((tty == NULL) || (strlen(tty) == 0)) {
+ tty = ttyname(STDOUT_FILENO);
+ }
+ if ((tty == NULL) || (strlen(tty) == 0)) {
+ tty = ttyname(STDERR_FILENO);
+ }
+ if ((tty == NULL) || (strlen(tty) == 0)) {
+ /* Match sudo's behavior for this case. */
+ tty = "unknown";
+ }
+ }
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG, "tty is `%s'", tty);
+ }
+ /* Snip off all but the last part of the tty name. */
+ tty = check_tty(tty);
+ if (tty == NULL) {
+ return PAM_AUTH_ERR;
+ }
+ /* Generate the name of the file used to cache auth results. These
+ * paths should jive with sudo's per-tty naming scheme. */
+ if (format_timestamp_name(path, len, tdir, tty, ruser, user) >= (int)len) {
+ return PAM_AUTH_ERR;
+ }
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG, "using timestamp file `%s'", path);
+ }
+ return PAM_SUCCESS;
+}
+
+/* Tell the user that access has been granted. */
+static void
+verbose_success(pam_handle_t *pamh, long diff)
+{
+ pam_info(pamh, _("Access has been granted"
+ " (last access was %ld seconds ago)."), diff);
+}
+
+int
+pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ struct stat st;
+ time_t interval = DEFAULT_TIMESTAMP_TIMEOUT;
+ int i, fd, debug = 0, verbose = 0;
+ char path[BUFLEN], *p, *message, *message_end;
+ long tmp;
+ const void *void_service;
+ const char *service;
+ time_t now, then;
+
+ /* Parse arguments. */
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "debug") == 0) {
+ debug = 1;
+ }
+ }
+ for (i = 0; i < argc; i++) {
+ const char *str;
+
+ if ((str = pam_str_skip_prefix(argv[i], "timestamp_timeout=")) != NULL) {
+ tmp = strtol(str, &p, 0);
+ if ((p != NULL) && (*p == '\0')) {
+ interval = tmp;
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "setting timeout to %ld"
+ " seconds", (long)interval);
+ }
+ }
+ } else
+ if (strcmp(argv[i], "verbose") == 0) {
+ verbose = 1;
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "becoming more verbose");
+ }
+ }
+ }
+
+ if (flags & PAM_SILENT) {
+ verbose = 0;
+ }
+
+ /* Get the name of the timestamp file. */
+ if (get_timestamp_name(pamh, argc, argv,
+ path, sizeof(path)) != PAM_SUCCESS) {
+ return PAM_AUTH_ERR;
+ }
+
+ /* Get the name of the service. */
+ if (pam_get_item(pamh, PAM_SERVICE, &void_service) != PAM_SUCCESS) {
+ service = NULL;
+ } else {
+ service = void_service;
+ }
+ if ((service == NULL) || (strlen(service) == 0)) {
+ service = "(unknown)";
+ }
+
+ /* Open the timestamp file. */
+ fd = open(path, O_RDONLY | O_NOFOLLOW);
+ if (fd == -1) {
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "cannot open timestamp `%s': %m",
+ path);
+ }
+ return PAM_AUTH_ERR;
+ }
+
+ if (fstat(fd, &st) == 0) {
+ int count;
+ void *mac;
+ size_t maclen;
+ char ruser[BUFLEN];
+
+ /* Check that the file is owned by the superuser. */
+ if ((st.st_uid != 0) || (st.st_gid != 0)) {
+ pam_syslog(pamh, LOG_ERR, "timestamp file `%s' is "
+ "not owned by root", path);
+ close(fd);
+ return PAM_AUTH_ERR;
+ }
+
+ /* Check that the file is a normal file. */
+ if (!(S_ISREG(st.st_mode))) {
+ pam_syslog(pamh, LOG_ERR, "timestamp file `%s' is "
+ "not a regular file", path);
+ close(fd);
+ return PAM_AUTH_ERR;
+ }
+
+#ifdef WITH_OPENSSL
+ if (hmac_size(pamh, debug, &maclen)) {
+ return PAM_AUTH_ERR;
+ }
+#else
+ maclen = hmac_sha1_size();
+#endif /* WITH_OPENSSL */
+ /* Check that the file is the expected size. */
+ if (st.st_size == 0) {
+ /* Invalid, but may have been created by sudo. */
+ close(fd);
+ return PAM_AUTH_ERR;
+ }
+ if (st.st_size !=
+ (off_t)(strlen(path) + 1 + sizeof(then) + maclen)) {
+ pam_syslog(pamh, LOG_NOTICE, "timestamp file `%s' "
+ "appears to be corrupted", path);
+ close(fd);
+ return PAM_AUTH_ERR;
+ }
+
+ /* Read the file contents. */
+ message = malloc(st.st_size);
+ count = 0;
+ if (!message) {
+ close(fd);
+ return PAM_BUF_ERR;
+ }
+ while (count < st.st_size) {
+ i = read(fd, message + count, st.st_size - count);
+ if ((i == 0) || (i == -1)) {
+ break;
+ }
+ count += i;
+ }
+ if (count < st.st_size) {
+ pam_syslog(pamh, LOG_NOTICE, "error reading timestamp "
+ "file `%s': %m", path);
+ close(fd);
+ free(message);
+ return PAM_AUTH_ERR;
+ }
+ message_end = message + strlen(path) + 1 + sizeof(then);
+
+ /* Regenerate the MAC. */
+#ifdef WITH_OPENSSL
+ if (hmac_generate(pamh, debug, &mac, &maclen, TIMESTAMPKEY,
+ ROOT_USER, ROOT_GROUP, message, message_end - message)) {
+ close(fd);
+ free(message);
+ return PAM_AUTH_ERR;
+ }
+#else
+ hmac_sha1_generate_file(pamh, &mac, &maclen, TIMESTAMPKEY,
+ ROOT_USER, ROOT_GROUP, message, message_end - message);
+#endif /* WITH_OPENSSL */
+ if ((mac == NULL) ||
+ (memcmp(path, message, strlen(path)) != 0) ||
+ (memcmp(mac, message_end, maclen) != 0)) {
+ pam_syslog(pamh, LOG_NOTICE, "timestamp file `%s' is "
+ "corrupted", path);
+ close(fd);
+ free(mac);
+ free(message);
+ return PAM_AUTH_ERR;
+ }
+ free(mac);
+ memmove(&then, message + strlen(path) + 1, sizeof(then));
+ free(message);
+
+ /* Check oldest login against timestamp */
+ if (get_ruser(pamh, ruser, sizeof(ruser)))
+ {
+ close(fd);
+ return PAM_AUTH_ERR;
+ }
+ if (check_login_time(ruser, then) != PAM_SUCCESS)
+ {
+ pam_syslog(pamh, LOG_NOTICE, "timestamp file `%s' is "
+ "older than oldest login, disallowing "
+ "access to %s for user %s",
+ path, service, ruser);
+ close(fd);
+ return PAM_AUTH_ERR;
+ }
+
+ /* Compare the dates. */
+ now = time(NULL);
+ if (timestamp_good(then, now, interval) == PAM_SUCCESS) {
+ close(fd);
+ pam_syslog(pamh, LOG_NOTICE, "timestamp file `%s' is "
+ "only %ld seconds old, allowing access to %s "
+ "for user %s", path, (long) (now - st.st_mtime),
+ service, ruser);
+ if (verbose) {
+ verbose_success(pamh, now - st.st_mtime);
+ }
+ return PAM_SUCCESS;
+ } else {
+ close(fd);
+ pam_syslog(pamh, LOG_NOTICE, "timestamp file `%s' has "
+ "unacceptable age (%ld seconds), disallowing "
+ "access to %s for user %s",
+ path, (long) (now - st.st_mtime),
+ service, ruser);
+ return PAM_AUTH_ERR;
+ }
+ }
+ close(fd);
+
+ /* Fail by default. */
+ return PAM_AUTH_ERR;
+}
+
+int
+pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED, int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
+
+int
+pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED, int argc, const char **argv)
+{
+ char path[BUFLEN], subdir[BUFLEN], *text, *p;
+ void *mac;
+ size_t maclen;
+ time_t now;
+ int fd, i, debug = 0;
+
+ /* Parse arguments. */
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "debug") == 0) {
+ debug = 1;
+ }
+ }
+
+ /* Get the name of the timestamp file. */
+ if (get_timestamp_name(pamh, argc, argv,
+ path, sizeof(path)) != PAM_SUCCESS) {
+ return PAM_SESSION_ERR;
+ }
+
+ /* Create the directory for the timestamp file if it doesn't already
+ * exist. */
+ for (i = 1; i < (int) sizeof(path) && path[i] != '\0'; i++) {
+ if (path[i] == '/') {
+ /* Attempt to create the directory. */
+ memcpy(subdir, path, i);
+ subdir[i] = '\0';
+ if (mkdir(subdir, 0700) == 0) {
+ /* Attempt to set the owner to the superuser. */
+ if (lchown(subdir, 0, 0) != 0) {
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "error setting permissions on `%s': %m",
+ subdir);
+ }
+ return PAM_SESSION_ERR;
+ }
+ } else {
+ if (errno != EEXIST) {
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "error creating directory `%s': %m",
+ subdir);
+ }
+ return PAM_SESSION_ERR;
+ }
+ }
+ }
+ }
+
+#ifdef WITH_OPENSSL
+ if (hmac_size(pamh, debug, &maclen)) {
+ return PAM_SESSION_ERR;
+ }
+#else
+ maclen = hmac_sha1_size();
+#endif /* WITH_OPENSSL */
+
+ /* Generate the message. */
+ text = malloc(strlen(path) + 1 + sizeof(now) + maclen);
+ if (text == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "unable to allocate memory: %m");
+ return PAM_SESSION_ERR;
+ }
+ p = text;
+
+ strcpy(text, path);
+ p += strlen(path) + 1;
+
+ now = time(NULL);
+ memmove(p, &now, sizeof(now));
+ p += sizeof(now);
+
+ /* Generate the MAC and append it to the plaintext. */
+#ifdef WITH_OPENSSL
+ if (hmac_generate(pamh, debug, &mac, &maclen, TIMESTAMPKEY,
+ ROOT_USER, ROOT_GROUP, text, p - text)) {
+ free(text);
+ return PAM_SESSION_ERR;
+ }
+#else
+ hmac_sha1_generate_file(pamh, &mac, &maclen, TIMESTAMPKEY,
+ ROOT_USER, ROOT_GROUP, text, p - text);
+ if (mac == NULL) {
+ pam_syslog(pamh, LOG_ERR, "failure generating MAC: %m");
+ free(text);
+ return PAM_SESSION_ERR;
+ }
+#endif /* WITH_OPENSSL */
+ memmove(p, mac, maclen);
+ p += maclen;
+ free(mac);
+
+ /* Open the file. */
+ fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+ if (fd == -1) {
+ pam_syslog(pamh, LOG_ERR, "unable to open `%s': %m", path);
+ free(text);
+ return PAM_SESSION_ERR;
+ }
+
+ /* Attempt to set the owner to the superuser. */
+ if (fchown(fd, 0, 0) != 0) {
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "error setting ownership of `%s': %m",
+ path);
+ }
+ close(fd);
+ free(text);
+ return PAM_SESSION_ERR;
+ }
+
+
+ /* Write the timestamp to the file. */
+ if (write(fd, text, p - text) != p - text) {
+ pam_syslog(pamh, LOG_ERR, "unable to write to `%s': %m", path);
+ close(fd);
+ free(text);
+ return PAM_SESSION_ERR;
+ }
+
+ /* Close the file and return successfully. */
+ close(fd);
+ free(text);
+ pam_syslog(pamh, LOG_DEBUG, "updated timestamp file `%s'", path);
+ return PAM_SUCCESS;
+}
+
+int
+pam_sm_close_session(pam_handle_t *pamh UNUSED, int flags UNUSED, int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
+
+#else /* PAM_TIMESTAMP_MAIN */
+
+#define USAGE "Usage: %s [[-k] | [-d]] [target user]\n"
+#define CHECK_INTERVAL 7
+
+int
+main(int argc, char **argv)
+{
+ int i, retval = 0, dflag = 0, kflag = 0;
+ const char *target_user = NULL, *user = NULL, *tty = NULL;
+ struct passwd *pwd;
+ struct timeval tv;
+ fd_set write_fds;
+ char path[BUFLEN];
+ struct stat st;
+
+ /* Check that there's nothing funny going on with stdio. */
+ if ((fstat(STDIN_FILENO, &st) == -1) ||
+ (fstat(STDOUT_FILENO, &st) == -1) ||
+ (fstat(STDERR_FILENO, &st) == -1)) {
+ /* Appropriate the "no controlling tty" error code. */
+ return 3;
+ }
+
+ /* Parse arguments. */
+ while ((i = getopt(argc, argv, "dk")) != -1) {
+ switch (i) {
+ case 'd':
+ dflag++;
+ break;
+ case 'k':
+ kflag++;
+ break;
+ default:
+ fprintf(stderr, USAGE, argv[0]);
+ return 1;
+ break;
+ }
+ }
+
+ /* Bail if both -k and -d are given together. */
+ if ((kflag + dflag) > 1) {
+ fprintf(stderr, USAGE, argv[0]);
+ return 1;
+ }
+
+ /* Check that we're setuid. */
+ if (geteuid() != 0) {
+ fprintf(stderr, "%s must be setuid root\n",
+ argv[0]);
+ retval = 2;
+ }
+
+ /* Check that we have a controlling tty. */
+ tty = ttyname(STDIN_FILENO);
+ if ((tty == NULL) || (strlen(tty) == 0)) {
+ tty = ttyname(STDOUT_FILENO);
+ }
+ if ((tty == NULL) || (strlen(tty) == 0)) {
+ tty = ttyname(STDERR_FILENO);
+ }
+ if ((tty == NULL) || (strlen(tty) == 0)) {
+ tty = "unknown";
+ }
+
+ /* Get the name of the invoking (requesting) user. */
+ pwd = getpwuid(getuid());
+ if (pwd == NULL) {
+ retval = 4;
+ }
+
+ /* Get the name of the target user. */
+ user = strdup(pwd->pw_name);
+ if (user == NULL) {
+ retval = 4;
+ } else {
+ target_user = (optind < argc) ? argv[optind] : user;
+ if ((strchr(target_user, '.') != NULL) ||
+ (strchr(target_user, '/') != NULL) ||
+ (strchr(target_user, '%') != NULL)) {
+ fprintf(stderr, "unknown user: %s\n",
+ target_user);
+ retval = 4;
+ }
+ }
+
+ /* Sanity check the tty to make sure we should be checking
+ * for timestamps which pertain to it. */
+ if (retval == 0) {
+ tty = check_tty(tty);
+ if (tty == NULL) {
+ fprintf(stderr, "invalid tty\n");
+ retval = 6;
+ }
+ }
+
+ do {
+ /* Sanity check the timestamp directory itself. */
+ if (retval == 0) {
+ if (check_dir_perms(NULL, TIMESTAMPDIR) != PAM_SUCCESS) {
+ retval = 5;
+ }
+ }
+
+ if (retval == 0) {
+ /* Generate the name of the timestamp file. */
+ format_timestamp_name(path, sizeof(path), TIMESTAMPDIR,
+ tty, user, target_user);
+ }
+
+ if (retval == 0) {
+ if (kflag) {
+ /* Remove the timestamp. */
+ if (lstat(path, &st) != -1) {
+ retval = unlink(path);
+ }
+ } else {
+ /* Check the timestamp. */
+ if (lstat(path, &st) != -1) {
+ /* Check oldest login against timestamp */
+ if (check_login_time(user, st.st_mtime) != PAM_SUCCESS) {
+ retval = 7;
+ } else if (timestamp_good(st.st_mtime, time(NULL),
+ DEFAULT_TIMESTAMP_TIMEOUT) != PAM_SUCCESS) {
+ retval = 7;
+ }
+ } else {
+ retval = 7;
+ }
+ }
+ }
+
+ if (dflag > 0) {
+ struct timeval now;
+ /* Send the would-be-returned value to our parent. */
+ signal(SIGPIPE, SIG_DFL);
+ fprintf(stdout, "%d\n", retval);
+ fflush(stdout);
+ /* Wait. */
+ gettimeofday(&now, NULL);
+ tv.tv_sec = CHECK_INTERVAL;
+ /* round the sleep time to get woken up on a whole second */
+ tv.tv_usec = 1000000 - now.tv_usec;
+ if (now.tv_usec < 500000)
+ tv.tv_sec--;
+ FD_ZERO(&write_fds);
+ FD_SET(STDOUT_FILENO, &write_fds);
+ select(STDOUT_FILENO + 1,
+ NULL, NULL, &write_fds,
+ &tv);
+ retval = 0;
+ }
+ } while (dflag > 0);
+
+ return retval;
+}
+
+#endif
diff --git a/modules/pam_timestamp/pam_timestamp_check.8 b/modules/pam_timestamp/pam_timestamp_check.8
new file mode 100644
index 0000000..a037375
--- /dev/null
+++ b/modules/pam_timestamp/pam_timestamp_check.8
@@ -0,0 +1,133 @@
+'\" t
+.\" Title: pam_timestamp_check
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_TIMESTAMP_CHECK" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_timestamp_check \- Check to see if the default timestamp is valid
+.SH "SYNOPSIS"
+.HP \w'\fBpam_timestamp_check\fR\ 'u
+\fBpam_timestamp_check\fR [\-k] [\-d] [\fItarget_user\fR]
+.SH "DESCRIPTION"
+.PP
+With no arguments
+\fBpam_timestamp_check\fR
+will check to see if the default timestamp is valid, or optionally remove it\&.
+.SH "OPTIONS"
+.PP
+\fB\-k\fR
+.RS 4
+Instead of checking the validity of a timestamp, remove it\&. This is analogous to sudo\*(Aqs
+\fI\-k\fR
+option\&.
+.RE
+.PP
+\fB\-d\fR
+.RS 4
+Instead of returning validity using an exit status, loop indefinitely, polling regularly and printing the status on standard output\&.
+.RE
+.PP
+\fB\fItarget_user\fR\fR
+.RS 4
+By default
+\fBpam_timestamp_check\fR
+checks or removes timestamps generated by
+\fIpam_timestamp\fR
+when the user authenticates as herself\&. When the user authenticates as a different user, the name of the timestamp file changes to accommodate this\&.
+\fItarget_user\fR
+allows one to specify this user name\&.
+.RE
+.SH "RETURN VALUES"
+.PP
+0
+.RS 4
+The timestamp is valid\&.
+.RE
+.PP
+2
+.RS 4
+The binary is not setuid root\&.
+.RE
+.PP
+3
+.RS 4
+Invalid invocation\&.
+.RE
+.PP
+4
+.RS 4
+User is unknown\&.
+.RE
+.PP
+5
+.RS 4
+Permissions error\&.
+.RE
+.PP
+6
+.RS 4
+Invalid controlling tty\&.
+.RE
+.PP
+7
+.RS 4
+Timestamp is not valid\&.
+.RE
+.SH "NOTES"
+.PP
+Users can get confused when they are not always asked for passwords when running a given program\&. Some users reflexively begin typing information before noticing that it is not being asked for\&.
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+auth sufficient pam_timestamp\&.so verbose
+auth required pam_unix\&.so
+
+session required pam_unix\&.so
+session optional pam_timestamp\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "FILES"
+.PP
+/var/run/sudo/\&.\&.\&.
+.RS 4
+timestamp files and directories
+.RE
+.SH "SEE ALSO"
+.PP
+\fBpam_timestamp_check\fR(8),
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_timestamp was written by Nalin Dahyabhai\&.
diff --git a/modules/pam_timestamp/pam_timestamp_check.8.xml b/modules/pam_timestamp/pam_timestamp_check.8.xml
new file mode 100644
index 0000000..3a65d7e
--- /dev/null
+++ b/modules/pam_timestamp/pam_timestamp_check.8.xml
@@ -0,0 +1,207 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_timestamp_check">
+
+ <refmeta>
+ <refentrytitle>pam_timestamp_check</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_timestamp_check-name">
+ <refname>pam_timestamp_check</refname>
+ <refpurpose>Check to see if the default timestamp is valid</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_timestamp_check-cmdsynopsis">
+ <command>pam_timestamp_check</command>
+ <arg choice="opt">
+ -k
+ </arg>
+ <arg choice="opt">
+ -d
+ </arg>
+ <arg choice="opt">
+ <replaceable>target_user</replaceable>
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_timestamp_check-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ With no arguments <command>pam_timestamp_check</command> will check to
+see if the default timestamp is valid, or optionally remove it.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_timestamp_check-options">
+
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>-k</option>
+ </term>
+ <listitem>
+ <para>
+ Instead of checking the validity of a timestamp, remove it.
+ This is analogous to sudo's <emphasis>-k</emphasis> option.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>-d</option>
+ </term>
+ <listitem>
+ <para>
+ Instead of returning validity using an exit status,
+ loop indefinitely, polling regularly and printing the status on
+ standard output.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option><replaceable>target_user</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ By default <command>pam_timestamp_check</command> checks or removes
+ timestamps generated by <emphasis>pam_timestamp</emphasis> when
+ the user authenticates as herself. When the user authenticates as a
+ different user, the name of the timestamp file changes to
+ accommodate this. <replaceable>target_user</replaceable> allows
+ one to specify this user name.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_timestamp_check-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>0</term>
+ <listitem>
+ <para>
+ The timestamp is valid.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>2</term>
+ <listitem>
+ <para>
+ The binary is not setuid root.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>3</term>
+ <listitem>
+ <para>
+ Invalid invocation.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>4</term>
+ <listitem>
+ <para>
+ User is unknown.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>5</term>
+ <listitem>
+ <para>
+ Permissions error.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>6</term>
+ <listitem>
+ <para>
+ Invalid controlling tty.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>7</term>
+ <listitem>
+ <para>
+ Timestamp is not valid.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_timestamp-notes'>
+ <title>NOTES</title>
+ <para>
+ Users can get confused when they are not always asked for passwords when
+running a given program. Some users reflexively begin typing information before
+noticing that it is not being asked for.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_timestamp-examples'>
+ <title>EXAMPLES</title>
+ <programlisting>
+auth sufficient pam_timestamp.so verbose
+auth required pam_unix.so
+
+session required pam_unix.so
+session optional pam_timestamp.so
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id="pam_timestamp-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/var/run/sudo/...</filename></term>
+ <listitem>
+ <para>timestamp files and directories</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_timestamp-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam_timestamp_check</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_timestamp-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_timestamp was written by Nalin Dahyabhai.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_timestamp/pam_timestamp_check.c b/modules/pam_timestamp/pam_timestamp_check.c
new file mode 100644
index 0000000..52b5a95
--- /dev/null
+++ b/modules/pam_timestamp/pam_timestamp_check.c
@@ -0,0 +1,42 @@
+/******************************************************************************
+ * A module for Linux-PAM that will cache authentication results, inspired by
+ * (and implemented with an eye toward being mixable with) sudo.
+ *
+ * Copyright (c) 2002 Red Hat, Inc.
+ * Written by Nalin Dahyabhai <nalin@redhat.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#define PAM_TIMESTAMP_MAIN 1
+#include "pam_timestamp.c"
diff --git a/modules/pam_timestamp/sha1.c b/modules/pam_timestamp/sha1.c
new file mode 100644
index 0000000..d713aed
--- /dev/null
+++ b/modules/pam_timestamp/sha1.c
@@ -0,0 +1,253 @@
+/* Yet another SHA-1 implementation.
+ *
+ * Copyright (c) 2003 Red Hat, Inc.
+ * Written by Nalin Dahyabhai <nalin@redhat.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/* See http://www.itl.nist.gov/fipspubs/fip180-1.htm for descriptions. */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <endian.h>
+#include <unistd.h>
+#include "sha1.h"
+
+static unsigned char
+padding[SHA1_BLOCK_SIZE] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static uint32_t
+F(uint32_t b, uint32_t c, uint32_t d)
+{
+ return (b & c) | ((~b) & d);
+}
+
+static uint32_t
+G(uint32_t b, uint32_t c, uint32_t d)
+{
+ return b ^ c ^ d;
+}
+
+static uint32_t
+H(uint32_t b, uint32_t c, uint32_t d)
+{
+ return (b & c) | (b & d) | (c & d);
+}
+
+static uint32_t
+RL(uint32_t n, uint32_t s)
+{
+ return (n << s) | (n >> (32 - s));
+}
+
+static uint32_t
+sha1_round(uint32_t (*FUNC)(uint32_t, uint32_t, uint32_t),
+ uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e,
+ uint32_t i, uint32_t n)
+{
+ return RL(a, 5) + FUNC(b, c, d) + e + i + n;
+}
+
+void
+sha1_init(struct sha1_context *ctx)
+{
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->a = 0x67452301;
+ ctx->b = 0xefcdab89;
+ ctx->c = 0x98badcfe;
+ ctx->d = 0x10325476;
+ ctx->e = 0xc3d2e1f0;
+}
+
+static void
+sha1_process(struct sha1_context *ctx, uint32_t buffer[SHA1_BLOCK_SIZE / 4])
+{
+ uint32_t a, b, c, d, e, temp;
+ uint32_t data[80];
+ int i;
+
+ for (i = 0; i < 16; i++) {
+ data[i] = htonl(buffer[i]);
+ }
+ for (i = 16; i < 80; i++) {
+ data[i] = RL(data[i - 3] ^ data[i - 8] ^ data[i - 14] ^ data[i - 16], 1);
+ }
+
+ a = ctx->a;
+ b = ctx->b;
+ c = ctx->c;
+ d = ctx->d;
+ e = ctx->e;
+
+ for (i = 0; i < 20; i++) {
+ temp = sha1_round(F, a, b, c, d, e, data[i], 0x5a827999);
+ e = d; d = c; c = RL(b, 30); b = a; a = temp;
+ }
+ for (i = 20; i < 40; i++) {
+ temp = sha1_round(G, a, b, c, d, e, data[i], 0x6ed9eba1);
+ e = d; d = c; c = RL(b, 30); b = a; a = temp;
+ }
+ for (i = 40; i < 60; i++) {
+ temp = sha1_round(H, a, b, c, d, e, data[i], 0x8f1bbcdc);
+ e = d; d = c; c = RL(b, 30); b = a; a = temp;
+ }
+ for (i = 60; i < 80; i++) {
+ temp = sha1_round(G, a, b, c, d, e, data[i], 0xca62c1d6);
+ e = d; d = c; c = RL(b, 30); b = a; a = temp;
+ }
+
+ ctx->a += a;
+ ctx->b += b;
+ ctx->c += c;
+ ctx->d += d;
+ ctx->e += e;
+
+ memset(buffer, 0, sizeof(buffer[0]) * SHA1_BLOCK_SIZE / 4);
+ memset(data, 0, sizeof(data));
+}
+
+void
+sha1_update(struct sha1_context *ctx, const unsigned char *data, size_t length)
+{
+ size_t i = 0, l = length, c, t;
+ uint32_t count = 0;
+
+ /* Process any pending + data blocks. */
+ while (l + ctx->pending_count >= SHA1_BLOCK_SIZE) {
+ c = ctx->pending_count;
+ t = SHA1_BLOCK_SIZE - c;
+ memcpy(ctx->pending.c + c, &data[i], t);
+ sha1_process(ctx, ctx->pending.i);
+ i += t;
+ l -= t;
+ ctx->pending_count = 0;
+ }
+
+ /* Save what's left of the data block as a pending data block. */
+ c = ctx->pending_count;
+ memcpy(ctx->pending.c + c, &data[i], l);
+ ctx->pending_count += l;
+
+ /* Update the message length. */
+ ctx->count += length;
+
+ /* Update our internal counts. */
+ if (length != 0) {
+ count = ctx->counts[0];
+ ctx->counts[0] += length;
+ if (count >= ctx->counts[0]) {
+ ctx->counts[1]++;
+ }
+ }
+}
+
+size_t
+sha1_output(struct sha1_context *ctx, unsigned char *out)
+{
+ struct sha1_context ctx2;
+
+ /* Output the sum. */
+ if (out != NULL) {
+ uint32_t c;
+ memcpy(&ctx2, ctx, sizeof(ctx2));
+
+ /* Pad this block. */
+ c = ctx2.pending_count;
+ memcpy(ctx2.pending.c + c,
+ padding, SHA1_BLOCK_SIZE - c);
+
+ /* Do we need to process two blocks now? */
+ if (c >= (SHA1_BLOCK_SIZE - (sizeof(uint32_t) * 2))) {
+ /* Process this block. */
+ sha1_process(&ctx2, ctx2.pending.i);
+ /* Set up another block. */
+ ctx2.pending_count = 0;
+ memset(ctx2.pending.c, 0, SHA1_BLOCK_SIZE);
+ ctx2.pending.c[0] =
+ (c == SHA1_BLOCK_SIZE) ? 0x80 : 0;
+ }
+
+ /* Process the final block. */
+ ctx2.counts[1] <<= 3;
+ if (ctx2.counts[0] >> 29) {
+ ctx2.counts[1] |=
+ (ctx2.counts[0] >> 29);
+ }
+ ctx2.counts[0] <<= 3;
+ ctx2.counts[0] = htonl(ctx2.counts[0]);
+ ctx2.counts[1] = htonl(ctx2.counts[1]);
+ memcpy(ctx2.pending.c + 56,
+ &ctx2.counts[1], sizeof(uint32_t));
+ memcpy(ctx2.pending.c + 60,
+ &ctx2.counts[0], sizeof(uint32_t));
+ sha1_process(&ctx2, ctx2.pending.i);
+
+ /* Output the data. */
+ out[ 3] = (ctx2.a >> 0) & 0xff;
+ out[ 2] = (ctx2.a >> 8) & 0xff;
+ out[ 1] = (ctx2.a >> 16) & 0xff;
+ out[ 0] = (ctx2.a >> 24) & 0xff;
+
+ out[ 7] = (ctx2.b >> 0) & 0xff;
+ out[ 6] = (ctx2.b >> 8) & 0xff;
+ out[ 5] = (ctx2.b >> 16) & 0xff;
+ out[ 4] = (ctx2.b >> 24) & 0xff;
+
+ out[11] = (ctx2.c >> 0) & 0xff;
+ out[10] = (ctx2.c >> 8) & 0xff;
+ out[ 9] = (ctx2.c >> 16) & 0xff;
+ out[ 8] = (ctx2.c >> 24) & 0xff;
+
+ out[15] = (ctx2.d >> 0) & 0xff;
+ out[14] = (ctx2.d >> 8) & 0xff;
+ out[13] = (ctx2.d >> 16) & 0xff;
+ out[12] = (ctx2.d >> 24) & 0xff;
+
+ out[19] = (ctx2.e >> 0) & 0xff;
+ out[18] = (ctx2.e >> 8) & 0xff;
+ out[17] = (ctx2.e >> 16) & 0xff;
+ out[16] = (ctx2.e >> 24) & 0xff;
+ }
+
+ return SHA1_OUTPUT_SIZE;
+}
diff --git a/modules/pam_timestamp/sha1.h b/modules/pam_timestamp/sha1.h
new file mode 100644
index 0000000..69f432e
--- /dev/null
+++ b/modules/pam_timestamp/sha1.h
@@ -0,0 +1,65 @@
+/* Yet another SHA-1 implementation.
+ *
+ * Copyright (c) 2003 Red Hat, Inc.
+ * Written by Nalin Dahyabhai <nalin@redhat.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef pam_timestamp_sha1_h
+#define pam_timestamp_sha1_h
+
+#include <stdint.h>
+#include <sys/types.h>
+#include "pam_cc_compat.h"
+
+#define SHA1_BLOCK_SIZE 64
+
+struct sha1_context {
+ size_t count;
+ union {
+ unsigned char c[SHA1_BLOCK_SIZE];
+ uint32_t i[SHA1_BLOCK_SIZE / sizeof(uint32_t)];
+ } pending;
+ uint32_t counts[2];
+ size_t pending_count;
+ uint32_t a, b, c, d, e;
+};
+
+#define SHA1_OUTPUT_SIZE 20
+
+void sha1_init(struct sha1_context *ctx);
+void sha1_update(struct sha1_context *ctx,
+ const unsigned char *data, size_t length);
+size_t sha1_output(struct sha1_context *ctx, unsigned char *out);
+
+#endif
diff --git a/modules/pam_timestamp/tst-pam_timestamp b/modules/pam_timestamp/tst-pam_timestamp
new file mode 100755
index 0000000..1d425b8
--- /dev/null
+++ b/modules/pam_timestamp/tst-pam_timestamp
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_timestamp.so
diff --git a/modules/pam_tty_audit/Makefile.am b/modules/pam_tty_audit/Makefile.am
new file mode 100644
index 0000000..e774c57
--- /dev/null
+++ b/modules/pam_tty_audit/Makefile.am
@@ -0,0 +1,32 @@
+#
+# Copyright (c) 2005, 2006, 2009, 2010 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_tty_audit.8
+endif
+XMLS = README.xml pam_tty_audit.8.xml
+dist_check_SCRIPTS = tst-pam_tty_audit
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+pam_tty_audit_la_LIBADD = $(top_builddir)/libpam/libpam.la
+securelib_LTLIBRARIES = pam_tty_audit.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_tty_audit/Makefile.in b/modules/pam_tty_audit/Makefile.in
new file mode 100644
index 0000000..124a811
--- /dev/null
+++ b/modules/pam_tty_audit/Makefile.in
@@ -0,0 +1,1149 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009, 2010 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_tty_audit
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_tty_audit_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_tty_audit_la_SOURCES = pam_tty_audit.c
+pam_tty_audit_la_OBJECTS = pam_tty_audit.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_tty_audit.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_tty_audit.c
+DIST_SOURCES = pam_tty_audit.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_tty_audit.8
+XMLS = README.xml pam_tty_audit.8.xml
+dist_check_SCRIPTS = tst-pam_tty_audit
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+pam_tty_audit_la_LIBADD = $(top_builddir)/libpam/libpam.la
+securelib_LTLIBRARIES = pam_tty_audit.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_tty_audit/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_tty_audit/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_tty_audit.la: $(pam_tty_audit_la_OBJECTS) $(pam_tty_audit_la_DEPENDENCIES) $(EXTRA_pam_tty_audit_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_tty_audit_la_OBJECTS) $(pam_tty_audit_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_tty_audit.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_tty_audit.log: tst-pam_tty_audit
+ @p='tst-pam_tty_audit'; \
+ b='tst-pam_tty_audit'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_tty_audit.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_tty_audit.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_tty_audit/README b/modules/pam_tty_audit/README
new file mode 100644
index 0000000..91ea9ce
--- /dev/null
+++ b/modules/pam_tty_audit/README
@@ -0,0 +1,70 @@
+pam_tty_audit — Enable or disable TTY auditing for specified users
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+The pam_tty_audit PAM module is used to enable or disable TTY auditing. By
+default, the kernel does not audit input on any TTY.
+
+OPTIONS
+
+disable=patterns
+
+ For each user matching patterns, disable TTY auditing. This overrides any
+ previous enable option matching the same user name on the command line. See
+ NOTES for further description of patterns.
+
+enable=patterns
+
+ For each user matching patterns, enable TTY auditing. This overrides any
+ previous disable option matching the same user name on the command line.
+ See NOTES for further description of patterns.
+
+open_only
+
+ Set the TTY audit flag when opening the session, but do not restore it when
+ closing the session. Using this option is necessary for some services that
+ don't fork() to run the authenticated session, such as sudo.
+
+log_passwd
+
+ Log keystrokes when ECHO mode is off but ICANON mode is active. This is the
+ mode in which the tty is placed during password entry. By default,
+ passwords are not logged. This option may not be available on older kernels
+ (3.9?).
+
+NOTES
+
+When TTY auditing is enabled, it is inherited by all processes started by that
+user. In particular, daemons restarted by a user will still have TTY auditing
+enabled, and audit TTY input even by other users unless auditing for these
+users is explicitly disabled. Therefore, it is recommended to use disable=* as
+the first option for most daemons using PAM.
+
+To view the data that was logged by the kernel to audit use the command
+aureport --tty.
+
+The patterns are comma separated lists of glob patterns or ranges of uids. A
+range is specified as min_uid:max_uid where one of these values can be empty.
+If min_uid is empty only user with the uid max_uid will be matched. If max_uid
+is empty users with the uid greater than or equal to min_uid will be matched.
+
+Please note that passwords in some circumstances may be logged by TTY auditing
+even if the log_passwd is not used. For example, all input to an ssh session
+will be logged - even if there is a password being typed into some software
+running at the remote host because only the local TTY state affects the local
+TTY auditing.
+
+EXAMPLES
+
+Audit all administrative actions.
+
+session required pam_tty_audit.so disable=* enable=root
+
+
+AUTHOR
+
+pam_tty_audit was written by Miloslav Trmač <mitr@redhat.com>. The log_passwd
+option was added by Richard Guy Briggs <rgb@redhat.com>.
+
diff --git a/modules/pam_tty_audit/README.xml b/modules/pam_tty_audit/README.xml
new file mode 100644
index 0000000..4dad6bb
--- /dev/null
+++ b/modules/pam_tty_audit/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd">
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_tty_audit.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_tty_audit-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_tty_audit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tty_audit-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_tty_audit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tty_audit-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_tty_audit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tty_audit-notes"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_tty_audit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tty_audit-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_tty_audit.8.xml" xpointer='xpointer(//refsect1[@id = "pam_tty_audit-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_tty_audit/pam_tty_audit.8 b/modules/pam_tty_audit/pam_tty_audit.8
new file mode 100644
index 0000000..628cec4
--- /dev/null
+++ b/modules/pam_tty_audit/pam_tty_audit.8
@@ -0,0 +1,135 @@
+'\" t
+.\" Title: pam_tty_audit
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_TTY_AUDIT" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_tty_audit \- Enable or disable TTY auditing for specified users
+.SH "SYNOPSIS"
+.HP \w'\fBpam_tty_audit\&.so\fR\ 'u
+\fBpam_tty_audit\&.so\fR [disable=\fIpatterns\fR] [enable=\fIpatterns\fR]
+.SH "DESCRIPTION"
+.PP
+The pam_tty_audit PAM module is used to enable or disable TTY auditing\&. By default, the kernel does not audit input on any TTY\&.
+.SH "OPTIONS"
+.PP
+\fBdisable=\fR\fB\fIpatterns\fR\fR
+.RS 4
+For each user matching
+\fB\fIpatterns\fR\fR, disable TTY auditing\&. This overrides any previous
+\fBenable\fR
+option matching the same user name on the command line\&. See NOTES for further description of
+\fB\fIpatterns\fR\fR\&.
+.RE
+.PP
+\fBenable=\fR\fB\fIpatterns\fR\fR
+.RS 4
+For each user matching
+\fB\fIpatterns\fR\fR, enable TTY auditing\&. This overrides any previous
+\fBdisable\fR
+option matching the same user name on the command line\&. See NOTES for further description of
+\fB\fIpatterns\fR\fR\&.
+.RE
+.PP
+\fBopen_only\fR
+.RS 4
+Set the TTY audit flag when opening the session, but do not restore it when closing the session\&. Using this option is necessary for some services that don\*(Aqt
+\fBfork()\fR
+to run the authenticated session, such as
+\fBsudo\fR\&.
+.RE
+.PP
+\fBlog_passwd\fR
+.RS 4
+Log keystrokes when ECHO mode is off but ICANON mode is active\&. This is the mode in which the tty is placed during password entry\&. By default, passwords are not logged\&. This option may not be available on older kernels (3\&.9?)\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+Only the
+\fBsession\fR
+type is supported\&.
+.SH "RETURN VALUES"
+.PP
+PAM_SESSION_ERR
+.RS 4
+Error reading or modifying the TTY audit flag\&. See the system log for more details\&.
+.RE
+.PP
+PAM_SUCCESS
+.RS 4
+Success\&.
+.RE
+.SH "NOTES"
+.PP
+When TTY auditing is enabled, it is inherited by all processes started by that user\&. In particular, daemons restarted by a user will still have TTY auditing enabled, and audit TTY input even by other users unless auditing for these users is explicitly disabled\&. Therefore, it is recommended to use
+\fBdisable=*\fR
+as the first option for most daemons using PAM\&.
+.PP
+To view the data that was logged by the kernel to audit use the command
+\fBaureport \-\-tty\fR\&.
+.PP
+The
+\fB\fIpatterns\fR\fR
+are comma separated lists of glob patterns or ranges of uids\&. A range is specified as
+\fImin_uid\fR:\fImax_uid\fR
+where one of these values can be empty\&. If
+\fImin_uid\fR
+is empty only user with the uid
+\fImax_uid\fR
+will be matched\&. If
+\fImax_uid\fR
+is empty users with the uid greater than or equal to
+\fImin_uid\fR
+will be matched\&.
+.PP
+Please note that passwords in some circumstances may be logged by TTY auditing even if the
+\fBlog_passwd\fR
+is not used\&. For example, all input to an ssh session will be logged \- even if there is a password being typed into some software running at the remote host because only the local TTY state affects the local TTY auditing\&.
+.SH "EXAMPLES"
+.PP
+Audit all administrative actions\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+session required pam_tty_audit\&.so disable=* enable=root
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.PP
+\fBaureport\fR(8),
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_tty_audit was written by Miloslav Trmač <mitr@redhat\&.com>\&. The log_passwd option was added by Richard Guy Briggs <rgb@redhat\&.com>\&.
diff --git a/modules/pam_tty_audit/pam_tty_audit.8.xml b/modules/pam_tty_audit/pam_tty_audit.8.xml
new file mode 100644
index 0000000..1c0ba5c
--- /dev/null
+++ b/modules/pam_tty_audit/pam_tty_audit.8.xml
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_tty_audit">
+
+ <refmeta>
+ <refentrytitle>pam_tty_audit</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_tty_audit-name">
+ <refname>pam_tty_audit</refname>
+ <refpurpose>Enable or disable TTY auditing for specified users</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_tty_audit-cmdsynopsis">
+ <command>pam_tty_audit.so</command>
+ <arg choice="opt">
+ disable=<replaceable>patterns</replaceable>
+ </arg>
+ <arg choice="opt">
+ enable=<replaceable>patterns</replaceable>
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_tty_audit-description">
+ <title>DESCRIPTION</title>
+ <para>
+ The pam_tty_audit PAM module is used to enable or disable TTY auditing.
+ By default, the kernel does not audit input on any TTY.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_tty_audit-options">
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>disable=<replaceable>patterns</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ For each user matching <option><replaceable>patterns</replaceable></option>,
+ disable TTY auditing. This overrides any previous <option>enable</option>
+ option matching the same user name on the command line. See NOTES
+ for further description of <option><replaceable>patterns</replaceable></option>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>enable=<replaceable>patterns</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ For each user matching <option><replaceable>patterns</replaceable></option>,
+ enable TTY auditing. This overrides any previous <option>disable</option>
+ option matching the same user name on the command line. See NOTES
+ for further description of <option><replaceable>patterns</replaceable></option>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>open_only</option>
+ </term>
+ <listitem>
+ <para>
+ Set the TTY audit flag when opening the session, but do not restore
+ it when closing the session. Using this option is necessary for
+ some services that don't <function>fork()</function> to run the
+ authenticated session, such as <command>sudo</command>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>log_passwd</option>
+ </term>
+ <listitem>
+ <para>
+ Log keystrokes when ECHO mode is off but ICANON mode is active.
+ This is the mode in which the tty is placed during password entry.
+ By default, passwords are not logged. This option may not be
+ available on older kernels (3.9?).
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_tty_audit-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ Only the <emphasis remap='B'>session</emphasis> type is supported.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_tty_audit-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_SESSION_ERR</term>
+ <listitem>
+ <para>
+ Error reading or modifying the TTY audit flag. See the system log
+ for more details.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Success.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_tty_audit-notes'>
+ <title>NOTES</title>
+ <para>
+ When TTY auditing is enabled, it is inherited by all processes started by
+ that user. In particular, daemons restarted by a user will still have
+ TTY auditing enabled, and audit TTY input even by other users unless
+ auditing for these users is explicitly disabled. Therefore, it is
+ recommended to use <option>disable=*</option> as the first option for
+ most daemons using PAM.
+ </para>
+ <para>
+ To view the data that was logged by the kernel to audit use
+ the command <command>aureport --tty</command>.
+ </para>
+ <para>
+ The <option><replaceable>patterns</replaceable></option> are comma separated
+ lists of glob patterns or ranges of uids. A range is specified as
+ <replaceable>min_uid</replaceable>:<replaceable>max_uid</replaceable> where
+ one of these values can be empty. If <replaceable>min_uid</replaceable> is
+ empty only user with the uid <replaceable>max_uid</replaceable> will be
+ matched. If <replaceable>max_uid</replaceable> is empty users with the uid
+ greater than or equal to <replaceable>min_uid</replaceable> will be
+ matched.
+ </para>
+ <para>
+ Please note that passwords in some circumstances may be logged by TTY auditing
+ even if the <option>log_passwd</option> is not used. For example, all input to
+ an ssh session will be logged - even if there is a password being typed into
+ some software running at the remote host because only the local TTY state
+ affects the local TTY auditing.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_tty_audit-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ Audit all administrative actions.
+ <programlisting>
+session required pam_tty_audit.so disable=* enable=root
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_tty_audit-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>aureport</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_tty_audit-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_tty_audit was written by Miloslav Trma&ccaron;
+ &lt;mitr@redhat.com&gt;.
+ The log_passwd option was added by Richard Guy Briggs
+ &lt;rgb@redhat.com&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_tty_audit/pam_tty_audit.c b/modules/pam_tty_audit/pam_tty_audit.c
new file mode 100644
index 0000000..15fb910
--- /dev/null
+++ b/modules/pam_tty_audit/pam_tty_audit.c
@@ -0,0 +1,450 @@
+/* Copyright © 2007, 2008 Red Hat, Inc. All rights reserved.
+ Red Hat author: Miloslav Trmač <mitr@redhat.com>
+
+ Redistribution and use in source and binary forms of Linux-PAM, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+
+ 1. Redistributions of source code must retain any existing copyright
+ notice, and this entire permission notice in its entirety,
+ including the disclaimer of warranties.
+
+ 2. Redistributions in binary form must reproduce all prior and current
+ copyright notices, this list of conditions, and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+ 3. The name of any author may not be used to endorse or promote
+ products derived from this software without their specific prior
+ written permission.
+
+ ALTERNATIVELY, this product may be distributed under the terms of the
+ GNU General Public License, in which case the provisions of the GNU
+ GPL are required INSTEAD OF the above restrictions. (This clause is
+ necessary due to a potential conflict between the GNU GPL and the
+ restrictions contained in a BSD-style copyright.)
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGE. */
+
+#include "config.h"
+#include <errno.h>
+#include <fnmatch.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <libaudit.h>
+#include <linux/netlink.h>
+
+#include <security/pam_ext.h>
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+
+#include "pam_cc_compat.h"
+#include "pam_inline.h"
+
+#define DATANAME "pam_tty_audit_last_state"
+
+/* Open an audit netlink socket */
+static int
+nl_open (void)
+{
+ return socket (AF_NETLINK, SOCK_RAW, NETLINK_AUDIT);
+}
+
+static int
+nl_send (int fd, unsigned type, unsigned flags, const void *data, size_t size)
+{
+ struct sockaddr_nl addr;
+ struct msghdr msg;
+ struct nlmsghdr nlm;
+ struct iovec iov[2];
+ ssize_t res;
+
+ nlm.nlmsg_len = NLMSG_LENGTH (size);
+ nlm.nlmsg_type = type;
+ nlm.nlmsg_flags = NLM_F_REQUEST | flags;
+ nlm.nlmsg_seq = 0;
+ nlm.nlmsg_pid = 0;
+ iov[0].iov_base = &nlm;
+ iov[0].iov_len = sizeof (nlm);
+ DIAG_PUSH_IGNORE_CAST_QUAL;
+ iov[1].iov_base = (void *)data;
+ DIAG_POP_IGNORE_CAST_QUAL;
+ iov[1].iov_len = size;
+ addr.nl_family = AF_NETLINK;
+ addr.nl_pid = 0;
+ addr.nl_groups = 0;
+ msg.msg_name = &addr;
+ msg.msg_namelen = sizeof (addr);
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 2;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+ res = sendmsg (fd, &msg, 0);
+ if (res == -1)
+ return -1;
+ if ((size_t)res != nlm.nlmsg_len)
+ {
+ errno = EIO;
+ return -1;
+ }
+ return 0;
+}
+
+static int
+nl_recv (int fd, unsigned type, void *buf, size_t size)
+{
+ struct sockaddr_nl addr;
+ struct msghdr msg;
+ struct nlmsghdr nlm;
+ struct iovec iov[2];
+ ssize_t res, resdiff;
+
+ again:
+ iov[0].iov_base = &nlm;
+ iov[0].iov_len = sizeof (nlm);
+ msg.msg_name = &addr;
+ msg.msg_namelen = sizeof (addr);
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+ if (type != NLMSG_ERROR)
+ {
+ res = recvmsg (fd, &msg, MSG_PEEK);
+ if (res == -1)
+ return -1;
+ if (res != NLMSG_LENGTH (0))
+ {
+ errno = EIO;
+ return -1;
+ }
+ if (nlm.nlmsg_type == NLMSG_ERROR)
+ {
+ struct nlmsgerr err;
+
+ iov[1].iov_base = &err;
+ iov[1].iov_len = sizeof (err);
+ msg.msg_iovlen = 2;
+ res = recvmsg (fd, &msg, 0);
+ if (res == -1)
+ return -1;
+ if ((size_t)res != NLMSG_LENGTH (sizeof (err))
+ || nlm.nlmsg_type != NLMSG_ERROR)
+ {
+ errno = EIO;
+ return -1;
+ }
+ if (err.error == 0)
+ goto again;
+ errno = -err.error;
+ return -1;
+ }
+ }
+ if (size != 0)
+ {
+ iov[1].iov_base = buf;
+ iov[1].iov_len = size;
+ msg.msg_iovlen = 2;
+ }
+ res = recvmsg (fd, &msg, 0);
+ if (res == -1)
+ return -1;
+ resdiff = NLMSG_LENGTH(size) - (size_t)res;
+ if (resdiff < 0
+ || nlm.nlmsg_type != type)
+ {
+ errno = EIO;
+ return -1;
+ }
+ else if (resdiff > 0)
+ {
+ memset((char *)buf + size - resdiff, 0, resdiff);
+ }
+ return 0;
+}
+
+static int
+nl_recv_ack (int fd)
+{
+ struct nlmsgerr err;
+
+ if (nl_recv (fd, NLMSG_ERROR, &err, sizeof (err)) != 0)
+ return -1;
+ if (err.error != 0)
+ {
+ errno = -err.error;
+ return -1;
+ }
+ return 0;
+}
+
+static void
+cleanup_old_status (pam_handle_t *pamh, void *data, int error_status)
+{
+ (void)pamh;
+ (void)error_status;
+ free (data);
+}
+
+enum uid_range { UID_RANGE_NONE, UID_RANGE_MM, UID_RANGE_MIN,
+ UID_RANGE_ONE, UID_RANGE_ERR };
+
+static enum uid_range
+parse_uid_range(pam_handle_t *pamh, const char *s,
+ uid_t *min_uid, uid_t *max_uid)
+{
+ const char *range = s;
+ const char *pmax;
+ char *endptr;
+ enum uid_range rv = UID_RANGE_MM;
+
+ if ((pmax=strchr(range, ':')) == NULL)
+ return UID_RANGE_NONE;
+ ++pmax;
+
+ if (range[0] == ':')
+ rv = UID_RANGE_ONE;
+ else {
+ errno = 0;
+ *min_uid = strtoul (range, &endptr, 10);
+ if (errno != 0 || (range == endptr) || *endptr != ':') {
+ pam_syslog(pamh, LOG_DEBUG,
+ "wrong min_uid value in '%s'", s);
+ return UID_RANGE_ERR;
+ }
+ }
+
+ if (*pmax == '\0') {
+ if (rv == UID_RANGE_ONE)
+ return UID_RANGE_ERR;
+
+ return UID_RANGE_MIN;
+ }
+
+ errno = 0;
+ *max_uid = strtoul (pmax, &endptr, 10);
+ if (errno != 0 || (pmax == endptr) || *endptr != '\0') {
+ pam_syslog(pamh, LOG_DEBUG,
+ "wrong max_uid value in '%s'", s);
+ return UID_RANGE_ERR;
+ }
+
+ if (rv == UID_RANGE_ONE)
+ *min_uid = *max_uid;
+ return rv;
+}
+
+int
+pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ enum command { CMD_NONE, CMD_ENABLE, CMD_DISABLE };
+
+ enum command command;
+ struct audit_tty_status *old_status, new_status;
+ const char *user;
+ int i, fd, open_only;
+ struct passwd *pwd;
+#ifdef HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD
+ int log_passwd;
+#endif /* HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD */
+
+ (void)flags;
+
+ if (pam_get_user (pamh, &user, NULL) != PAM_SUCCESS)
+ {
+ pam_syslog(pamh, LOG_NOTICE, "cannot determine user name");
+ return PAM_SESSION_ERR;
+ }
+
+ pwd = pam_modutil_getpwnam(pamh, user);
+ if (pwd == NULL)
+ {
+ pam_syslog(pamh, LOG_NOTICE,
+ "open_session unknown user '%s'", user);
+ return PAM_SESSION_ERR;
+ }
+
+ command = CMD_NONE;
+ open_only = 0;
+#ifdef HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD
+ log_passwd = 0;
+#endif /* HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD */
+ for (i = 0; i < argc; i++)
+ {
+ const char *str;
+
+ if ((str = pam_str_skip_prefix(argv[i], "enable=")) != NULL
+ || (str = pam_str_skip_prefix(argv[i], "disable=")) != NULL)
+ {
+ enum command this_command;
+ char *copy, *tok_data, *tok;
+
+ this_command = *argv[i] == 'e' ? CMD_ENABLE : CMD_DISABLE;
+ copy = strdup (str);
+ if (copy == NULL)
+ return PAM_SESSION_ERR;
+ for (tok = strtok_r (copy, ",", &tok_data);
+ tok != NULL && command != this_command;
+ tok = strtok_r (NULL, ",", &tok_data))
+ {
+ uid_t min_uid = 0, max_uid = 0;
+ switch (parse_uid_range(pamh, tok, &min_uid, &max_uid))
+ {
+ case UID_RANGE_NONE:
+ if (fnmatch (tok, user, 0) == 0)
+ command = this_command;
+ break;
+ case UID_RANGE_MM:
+ if (pwd->pw_uid >= min_uid && pwd->pw_uid <= max_uid)
+ command = this_command;
+ break;
+ case UID_RANGE_MIN:
+ if (pwd->pw_uid >= min_uid)
+ command = this_command;
+ break;
+ case UID_RANGE_ONE:
+ if (pwd->pw_uid == max_uid)
+ command = this_command;
+ break;
+ case UID_RANGE_ERR:
+ break;
+ }
+ }
+ free (copy);
+ }
+ else if (strcmp (argv[i], "open_only") == 0)
+ open_only = 1;
+ else if (strcmp (argv[i], "log_passwd") == 0)
+#ifdef HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD
+ log_passwd = 1;
+#else /* HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD */
+ pam_syslog (pamh, LOG_WARNING,
+ "The log_passwd option was not available at compile time.");
+#warning "pam_tty_audit: The log_passwd option is not available. Please upgrade your headers/kernel."
+#endif /* HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD */
+ else
+ {
+ pam_syslog (pamh, LOG_ERR, "unknown option `%s'", argv[i]);
+ }
+ }
+ if (command == CMD_NONE)
+ return PAM_SUCCESS;
+
+ old_status = malloc (sizeof (*old_status));
+ if (old_status == NULL)
+ return PAM_SESSION_ERR;
+
+ fd = nl_open ();
+ if (fd == -1
+ && errno == EPROTONOSUPPORT)
+ {
+ pam_syslog (pamh, LOG_WARNING, "unable to open audit socket, audit not "
+ "supported; tty_audit skipped");
+ free (old_status);
+ return PAM_IGNORE;
+ }
+ else if (fd == -1
+ || nl_send (fd, AUDIT_TTY_GET, 0, NULL, 0) != 0
+ || nl_recv (fd, AUDIT_TTY_GET, old_status, sizeof (*old_status)) != 0)
+ {
+ pam_syslog (pamh, LOG_ERR, "error reading current audit status: %m");
+ if (fd != -1)
+ close (fd);
+ free (old_status);
+ return PAM_SESSION_ERR;
+ }
+
+ memcpy(&new_status, old_status, sizeof(new_status));
+
+ new_status.enabled = (command == CMD_ENABLE ? 1 : 0);
+#ifdef HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD
+ new_status.log_passwd = log_passwd;
+#endif /* HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD */
+ if (old_status->enabled == new_status.enabled
+#ifdef HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD
+ && old_status->log_passwd == new_status.log_passwd
+#endif /* HAVE_STRUCT_AUDIT_TTY_STATUS_LOG_PASSWD */
+ )
+ {
+ open_only = 1; /* to clean up old_status */
+ goto ok_fd;
+ }
+
+ if (open_only == 0
+ && pam_set_data (pamh, DATANAME, old_status, cleanup_old_status)
+ != PAM_SUCCESS)
+ {
+ pam_syslog (pamh, LOG_ERR, "error saving old audit status");
+ close (fd);
+ free (old_status);
+ return PAM_SESSION_ERR;
+ }
+
+ if (nl_send (fd, AUDIT_TTY_SET, NLM_F_ACK, &new_status,
+ sizeof (new_status)) != 0
+ || nl_recv_ack (fd) != 0)
+ {
+ pam_syslog (pamh, LOG_ERR, "error setting current audit status: %m");
+ close (fd);
+ if (open_only != 0)
+ free (old_status);
+ return PAM_SESSION_ERR;
+ }
+ /* Fall through */
+ ok_fd:
+ close (fd);
+ pam_syslog (pamh, LOG_DEBUG, "changed status from %d to %d",
+ old_status->enabled, new_status.enabled);
+ if (open_only != 0)
+ free (old_status);
+ return PAM_SUCCESS;
+}
+
+int
+pam_sm_close_session (pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ const void *status_;
+
+ (void)flags;
+ (void)argc;
+ (void)argv;
+ if (pam_get_data (pamh, DATANAME, &status_) == PAM_SUCCESS)
+ {
+ const struct audit_tty_status *status;
+ int fd;
+
+ status = status_;
+
+ fd = nl_open ();
+ if (fd == -1
+ || nl_send (fd, AUDIT_TTY_SET, NLM_F_ACK, status,
+ sizeof (*status)) != 0
+ || nl_recv_ack (fd) != 0)
+ {
+ pam_syslog (pamh, LOG_ERR, "error restoring audit status: %m");
+ if (fd != -1)
+ close (fd);
+ return PAM_SESSION_ERR;
+ }
+ close (fd);
+ pam_syslog (pamh, LOG_DEBUG, "restored status to %d", status->enabled);
+ }
+ return PAM_SUCCESS;
+}
diff --git a/modules/pam_tty_audit/tst-pam_tty_audit b/modules/pam_tty_audit/tst-pam_tty_audit
new file mode 100755
index 0000000..2b8ab4b
--- /dev/null
+++ b/modules/pam_tty_audit/tst-pam_tty_audit
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_tty_audit.so
diff --git a/modules/pam_umask/Makefile.am b/modules/pam_umask/Makefile.am
new file mode 100644
index 0000000..b8c506e
--- /dev/null
+++ b/modules/pam_umask/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_umask.8
+endif
+XMLS = README.xml pam_umask.8.xml
+dist_check_SCRIPTS = tst-pam_umask
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_umask.la
+pam_umask_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_umask/Makefile.in b/modules/pam_umask/Makefile.in
new file mode 100644
index 0000000..b4d72c9
--- /dev/null
+++ b/modules/pam_umask/Makefile.in
@@ -0,0 +1,1150 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_umask
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_umask_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_umask_la_SOURCES = pam_umask.c
+pam_umask_la_OBJECTS = pam_umask.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_umask.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_umask.c
+DIST_SOURCES = pam_umask.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_umask.8
+XMLS = README.xml pam_umask.8.xml
+dist_check_SCRIPTS = tst-pam_umask
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_umask.la
+pam_umask_la_LIBADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_umask/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_umask/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_umask.la: $(pam_umask_la_OBJECTS) $(pam_umask_la_DEPENDENCIES) $(EXTRA_pam_umask_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_umask_la_OBJECTS) $(pam_umask_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_umask.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_umask.log: tst-pam_umask
+ @p='tst-pam_umask'; \
+ b='tst-pam_umask'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_umask.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_umask.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_umask/README b/modules/pam_umask/README
new file mode 100644
index 0000000..ddde8c2
--- /dev/null
+++ b/modules/pam_umask/README
@@ -0,0 +1,65 @@
+pam_umask — PAM module to set the file mode creation mask
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+pam_umask is a PAM module to set the file mode creation mask of the current
+environment. The umask affects the default permissions assigned to newly
+created files.
+
+The PAM module tries to get the umask value from the following places in the
+following order:
+
+ • umask= entry in the user's GECOS field
+
+ • umask= argument
+
+ • UMASK entry from /etc/login.defs
+
+ • UMASK= entry from /etc/default/login
+
+The GECOS field is split on comma ',' characters. The module also in addition
+to the umask= entry recognizes pri= entry, which sets the nice priority value
+for the session, and ulimit= entry, which sets the maximum size of files the
+processes in the session can create.
+
+OPTIONS
+
+debug
+
+ Print debug information.
+
+silent
+
+ Don't print informative messages.
+
+usergroups
+
+ If the user is not root and the username is the same as primary group name,
+ the umask group bits are set to be the same as owner bits (examples: 022 ->
+ 002, 077 -> 007).
+
+nousergroups
+
+ This is the direct opposite of the usergroups option described above, which
+ can be useful in case pam_umask has been compiled with usergroups enabled
+ by default and you want to disable it at runtime.
+
+umask=mask
+
+ Sets the calling process's file mode creation mask (umask) to mask & 0777.
+ The value is interpreted as Octal.
+
+EXAMPLES
+
+Add the following line to /etc/pam.d/login to set the user specific umask at
+login:
+
+ session optional pam_umask.so umask=0022
+
+
+AUTHOR
+
+pam_umask was written by Thorsten Kukuk <kukuk@thkukuk.de>.
+
diff --git a/modules/pam_umask/README.xml b/modules/pam_umask/README.xml
new file mode 100644
index 0000000..9afbe54
--- /dev/null
+++ b/modules/pam_umask/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_umask.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_umask.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_umask-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_umask.8.xml" xpointer='xpointer(//refsect1[@id = "pam_umask-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_umask.8.xml" xpointer='xpointer(//refsect1[@id = "pam_umask-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_umask.8.xml" xpointer='xpointer(//refsect1[@id = "pam_umask-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_umask.8.xml" xpointer='xpointer(//refsect1[@id = "pam_umask-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_umask/pam_umask.8 b/modules/pam_umask/pam_umask.8
new file mode 100644
index 0000000..73a609f
--- /dev/null
+++ b/modules/pam_umask/pam_umask.8
@@ -0,0 +1,176 @@
+'\" t
+.\" Title: pam_umask
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_UMASK" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_umask \- PAM module to set the file mode creation mask
+.SH "SYNOPSIS"
+.HP \w'\fBpam_umask\&.so\fR\ 'u
+\fBpam_umask\&.so\fR [debug] [silent] [usergroups] [nousergroups] [umask=\fImask\fR]
+.SH "DESCRIPTION"
+.PP
+pam_umask is a PAM module to set the file mode creation mask of the current environment\&. The umask affects the default permissions assigned to newly created files\&.
+.PP
+The PAM module tries to get the umask value from the following places in the following order:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+umask= entry in the user\*(Aqs GECOS field
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+umask= argument
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+UMASK entry from /etc/login\&.defs
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+UMASK= entry from /etc/default/login
+.RE
+.PP
+The GECOS field is split on comma \*(Aq,\*(Aq characters\&. The module also in addition to the umask= entry recognizes pri= entry, which sets the nice priority value for the session, and ulimit= entry, which sets the maximum size of files the processes in the session can create\&.
+.SH "OPTIONS"
+.PP
+.PP
+\fBdebug\fR
+.RS 4
+Print debug information\&.
+.RE
+.PP
+\fBsilent\fR
+.RS 4
+Don\*(Aqt print informative messages\&.
+.RE
+.PP
+\fBusergroups\fR
+.RS 4
+If the user is not root and the username is the same as primary group name, the umask group bits are set to be the same as owner bits (examples: 022 \-> 002, 077 \-> 007)\&.
+.RE
+.PP
+\fBnousergroups\fR
+.RS 4
+This is the direct opposite of the usergroups option described above, which can be useful in case pam_umask has been compiled with usergroups enabled by default and you want to disable it at runtime\&.
+.RE
+.PP
+\fBumask=\fR\fB\fImask\fR\fR
+.RS 4
+Sets the calling process\*(Aqs file mode creation mask (umask) to
+\fBmask\fR
+& 0777\&. The value is interpreted as Octal\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+Only the
+\fBsession\fR
+type is provided\&.
+.SH "RETURN VALUES"
+.PP
+.PP
+PAM_SUCCESS
+.RS 4
+The new umask was set successfully\&.
+.RE
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_CONV_ERR
+.RS 4
+The conversation method supplied by the application failed to obtain the username\&.
+.RE
+.PP
+PAM_INCOMPLETE
+.RS 4
+The conversation method supplied by the application returned PAM_CONV_AGAIN\&.
+.RE
+.PP
+PAM_SERVICE_ERR
+.RS 4
+No username was given\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+User not known\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Add the following line to
+/etc/pam\&.d/login
+to set the user specific umask at login:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+ session optional pam_umask\&.so umask=0022
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.PP
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_umask was written by Thorsten Kukuk <kukuk@thkukuk\&.de>\&.
diff --git a/modules/pam_umask/pam_umask.8.xml b/modules/pam_umask/pam_umask.8.xml
new file mode 100644
index 0000000..7c4a310
--- /dev/null
+++ b/modules/pam_umask/pam_umask.8.xml
@@ -0,0 +1,261 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_umask">
+
+ <refmeta>
+ <refentrytitle>pam_umask</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_umask-name">
+ <refname>pam_umask</refname>
+ <refpurpose>PAM module to set the file mode creation mask</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_umask-cmdsynopsis">
+ <command>pam_umask.so</command>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ silent
+ </arg>
+ <arg choice="opt">
+ usergroups
+ </arg>
+ <arg choice="opt">
+ nousergroups
+ </arg>
+ <arg choice="opt">
+ umask=<replaceable>mask</replaceable>
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_umask-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ pam_umask is a PAM module to set the file mode creation mask
+ of the current environment. The umask affects the default
+ permissions assigned to newly created files.
+ </para>
+ <para>
+ The PAM module tries to get the umask value from the
+ following places in the following order:
+ <itemizedlist>
+ <listitem>
+ <para>
+ umask= entry in the user's GECOS field
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ umask= argument
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ UMASK entry from /etc/login.defs
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ UMASK= entry from /etc/default/login
+ </para>
+ </listitem>
+ </itemizedlist>
+ </para>
+ <para>
+ The GECOS field is split on comma ',' characters. The module
+ also in addition to the umask= entry recognizes pri= entry,
+ which sets the nice priority value for the session, and
+ ulimit= entry, which sets the maximum size of files the processes
+ in the session can create.
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="pam_umask-options">
+
+ <title>OPTIONS</title>
+ <para>
+ <variablelist>
+
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Print debug information.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>silent</option>
+ </term>
+ <listitem>
+ <para>
+ Don't print informative messages.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>usergroups</option>
+ </term>
+ <listitem>
+ <para>
+ If the user is not root and the username is the same as
+ primary group name, the umask group bits are set to be the
+ same as owner bits (examples: 022 -> 002, 077 -> 007).
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>nousergroups</option>
+ </term>
+ <listitem>
+ <para>
+ This is the direct opposite of the usergroups option described above,
+ which can be useful in case pam_umask has been compiled with
+ usergroups enabled by default and you want to disable it at runtime.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>umask=<replaceable>mask</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Sets the calling process's file mode creation mask (umask)
+ to <option>mask</option> &amp; 0777. The value is interpreted
+ as Octal.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_umask-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ Only the <option>session</option> type is provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_umask-return_values'>
+ <title>RETURN VALUES</title>
+ <para>
+ <variablelist>
+
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ The new umask was set successfully.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory buffer error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_CONV_ERR</term>
+ <listitem>
+ <para>
+ The conversation method supplied by the application
+ failed to obtain the username.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_INCOMPLETE</term>
+ <listitem>
+ <para>
+ The conversation method supplied by the application
+ returned PAM_CONV_AGAIN.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ No username was given.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ User not known.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_umask-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ Add the following line to <filename>/etc/pam.d/login</filename> to
+ set the user specific umask at login:
+ <programlisting>
+ session optional pam_umask.so umask=0022
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_umask-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_umask-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_umask was written by Thorsten Kukuk &lt;kukuk@thkukuk.de&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_umask/pam_umask.c b/modules/pam_umask/pam_umask.c
new file mode 100644
index 0000000..72b10e9
--- /dev/null
+++ b/modules/pam_umask/pam_umask.c
@@ -0,0 +1,238 @@
+/*
+ * pam_umask module
+ *
+ * Copyright (c) 2005, 2006, 2007, 2010, 2013 Thorsten Kukuk <kukuk@thkukuk.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License V2, in which case the provisions of the GPL
+ * are required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <pwd.h>
+#include <grp.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <syslog.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+#include "pam_inline.h"
+
+#define LOGIN_DEFS "/etc/login.defs"
+#define LOGIN_CONF "/etc/default/login"
+
+struct options_t {
+ int debug;
+ int usergroups;
+ int silent;
+ const char *umask;
+ char *login_umask;
+};
+typedef struct options_t options_t;
+
+static void
+parse_option (const pam_handle_t *pamh, const char *argv, options_t *options)
+{
+ const char *str;
+
+ if (argv == NULL || argv[0] == '\0')
+ return;
+
+ if (strcasecmp (argv, "debug") == 0)
+ options->debug = 1;
+ else if ((str = pam_str_skip_icase_prefix (argv, "umask=")) != NULL)
+ options->umask = str;
+ else if (strcasecmp (argv, "usergroups") == 0)
+ options->usergroups = 1;
+ else if (strcasecmp (argv, "nousergroups") == 0)
+ options->usergroups = 0;
+ else if (strcasecmp (argv, "silent") == 0)
+ options->silent = 1;
+ else
+ pam_syslog (pamh, LOG_ERR, "Unknown option: `%s'", argv);
+}
+
+static int
+get_options (pam_handle_t *pamh, options_t *options,
+ int argc, const char **argv)
+{
+ memset (options, 0, sizeof (options_t));
+
+ options->usergroups = DEFAULT_USERGROUPS_SETTING;
+
+ /* Parse parameters for module */
+ for ( ; argc-- > 0; argv++)
+ parse_option (pamh, *argv, options);
+
+ if (options->umask == NULL) {
+ options->login_umask = pam_modutil_search_key (pamh, LOGIN_DEFS, "UMASK");
+ if (options->login_umask == NULL)
+ options->login_umask = pam_modutil_search_key (pamh, LOGIN_CONF, "UMASK");
+ options->umask = options->login_umask;
+ }
+
+ return 0;
+}
+
+static void
+set_umask (const char *value)
+{
+ const char *value_orig = value;
+ mode_t mask;
+ char *endptr;
+
+ mask = strtoul (value, &endptr, 8) & 0777;
+ if (((mask == 0) && (value_orig == endptr)) ||
+ ((mask == UINT_MAX) && (errno == ERANGE)))
+ return;
+ umask (mask);
+ return;
+}
+
+/* Set the process nice, ulimit, and umask from the
+ password file entry. */
+static void
+setup_limits_from_gecos (pam_handle_t *pamh, options_t *options,
+ struct passwd *pw)
+{
+ char *cp;
+
+ if (options->usergroups)
+ {
+ /* if not root and username is the same as primary group name,
+ set umask group bits to be the same as owner bits
+ (examples: 022 -> 002, 077 -> 007). */
+ if (pw->pw_uid != 0)
+ {
+ struct group *grp = pam_modutil_getgrgid (pamh, pw->pw_gid);
+ if (grp && (strcmp (pw->pw_name, grp->gr_name) == 0))
+ {
+ mode_t oldmask = umask (0777);
+ umask ((oldmask & ~070) | ((oldmask >> 3) & 070));
+ }
+ }
+ }
+
+ /* See if the GECOS field contains values for NICE, UMASK or ULIMIT. */
+ for (cp = pw->pw_gecos; cp != NULL; cp = strchr (cp, ','))
+ {
+ const char *str;
+
+ if (*cp == ',')
+ cp++;
+
+ if ((str = pam_str_skip_icase_prefix (cp, "umask=")) != NULL)
+ umask (strtol (str, NULL, 8) & 0777);
+ else if ((str = pam_str_skip_icase_prefix (cp, "pri=")) != NULL)
+ {
+ errno = 0;
+ if (nice (strtol (str, NULL, 10)) == -1 && errno != 0)
+ {
+ if (!options->silent || options->debug)
+ pam_error (pamh, "nice failed: %m\n");
+ pam_syslog (pamh, LOG_ERR, "nice failed: %m");
+ }
+ }
+ else if ((str = pam_str_skip_icase_prefix (cp, "ulimit=")) != NULL)
+ {
+ struct rlimit rlimit_fsize;
+ rlimit_fsize.rlim_cur = 512L * strtol (str, NULL, 10);
+ rlimit_fsize.rlim_max = rlimit_fsize.rlim_cur;
+ if (setrlimit (RLIMIT_FSIZE, &rlimit_fsize) == -1)
+ {
+ if (!options->silent || options->debug)
+ pam_error (pamh, "setrlimit failed: %m\n");
+ pam_syslog (pamh, LOG_ERR, "setrlimit failed: %m");
+ }
+ }
+ }
+}
+
+
+int
+pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ struct passwd *pw;
+ options_t options;
+ const char *name;
+ int retval = PAM_SUCCESS;
+
+ get_options (pamh, &options, argc, argv);
+ if (flags & PAM_SILENT)
+ options.silent = 1;
+
+ /* get the user name. */
+ if ((retval = pam_get_user (pamh, &name, NULL)) != PAM_SUCCESS)
+ {
+ pam_syslog(pamh, LOG_NOTICE, "cannot determine user name: %s",
+ pam_strerror(pamh, retval));
+ return (retval == PAM_CONV_AGAIN ? PAM_INCOMPLETE:retval);
+ }
+
+ pw = pam_modutil_getpwnam (pamh, name);
+ if (pw == NULL)
+ {
+ pam_syslog (pamh, LOG_NOTICE, "account for %s not found", name);
+ return PAM_USER_UNKNOWN;
+ }
+
+ if (options.umask != NULL)
+ {
+ set_umask (options.umask);
+ free (options.login_umask);
+ options.umask = options.login_umask = NULL;
+ }
+
+ setup_limits_from_gecos (pamh, &options, pw);
+
+ return retval;
+}
+
+int
+pam_sm_close_session (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
+
+/* end of module definition */
diff --git a/modules/pam_umask/tst-pam_umask b/modules/pam_umask/tst-pam_umask
new file mode 100755
index 0000000..3608a9d
--- /dev/null
+++ b/modules/pam_umask/tst-pam_umask
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_umask.so
diff --git a/modules/pam_unix/CHANGELOG b/modules/pam_unix/CHANGELOG
new file mode 100644
index 0000000..f8f70f5
--- /dev/null
+++ b/modules/pam_unix/CHANGELOG
@@ -0,0 +1,54 @@
+$Id$
+
+* Mon Aug 16 1999 Jan Rękorajski <baggins@pld.org.pl>
+- fixed reentrancy problems
+
+* Sun Jul 4 21:03:42 PDT 1999
+
+- temporarily removed the crypt16 stuff. I'm really paranoid about
+ crypto stuff and exporting it, and there are a few too many 's-box'
+ references in the code for my liking..
+
+* Wed Jun 30 1999 Steve Langasek <vorlon@netexpress.net>
+- further NIS+ fixes
+
+* Sun Jun 27 1999 Steve Langasek <vorlon@netexpress.net>
+- fix to uid-handling code for NIS+
+
+* Sat Jun 26 1999 Jan Rękorajski <baggins@mimuw.edu.pl>
+- merged MD5 fix and early failure syslog
+ by Andrey Vladimirovich Savochkin <saw@msu.ru>
+- minor fixes
+- added signal handler to unix_chkpwd
+
+* Fri Jun 25 1999 Stephen Langasek <vorlon@netexpress.net>
+- reorganized the code to let it build as separate C files
+
+* Sun Jun 20 1999 Jan Rękorajski <baggins@mimuw.edu.pl>
+- fixes in pam_unix_auth, it incorrectly saved and restored return
+ value when likeauth option was used
+
+* Tue Jun 15 1999 Jan Rękorajski <baggins@mimuw.edu.pl>
+- added NIS+ support
+
+* Mon Jun 14 1999 Jan Rękorajski <baggins@mimuw.edu.pl>
+- total rewrite based on pam_pwdb module, now there is ONE pam_unix.so
+ module, it accepts the same options as pam_pwdb - all of them correctly ;)
+ (pam_pwdb dosn't understand what DISALLOW_NULL_AUTHTOK means)
+
+* Tue Apr 20 1999 Jan Rękorajski <baggins@mimuw.edu.pl>
+- Arghhh, pam_unix_passwd was not updating /etc/shadow when used with
+ pam_cracklib.
+
+* Mon Apr 19 1999 Jan Rękorajski <baggins@mimuw.edu.pl>
+- added "remember=XXX" option that means 'remember XXX old passwords'
+ Old passwords are stored in /etc/security/opasswd, there can be
+ maximum of 400 passwords per user.
+
+* Sat Mar 27 1999 Jan Rękorajski <baggins@mimuw.edu.pl>
+- added crypt16 to pam_unix_auth and pam_unix_passwd (check only, this algorithm
+ is too lame to use it in real life)
+
+* Sun Mar 21 1999 Jan Rękorajski <baggins@mimuw.edu.pl>
+- pam_unix_auth now correctly behave when user has NULL AUTHTOK
+- pam_unix_auth returns PAM_PERM_DENIED when seteuid fails
diff --git a/modules/pam_unix/Makefile.am b/modules/pam_unix/Makefile.am
new file mode 100644
index 0000000..1658735
--- /dev/null
+++ b/modules/pam_unix/Makefile.am
@@ -0,0 +1,63 @@
+#
+# Copyright (c) 2005, 2006, 2009, 2011 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = md5.c md5_crypt.c lckpwdf.-c $(XMLS) CHANGELOG
+
+if HAVE_DOC
+dist_man_MANS = pam_unix.8 unix_chkpwd.8 unix_update.8
+endif
+XMLS = README.xml pam_unix.8.xml unix_chkpwd.8.xml unix_update.8.xml
+dist_check_SCRIPTS = tst-pam_unix
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DCHKPWD_HELPER=\"$(sbindir)/unix_chkpwd\" \
+ -DUPDATE_HELPER=\"$(sbindir)/unix_update\" \
+ @TIRPC_CFLAGS@ @NSL_CFLAGS@ $(WARN_CFLAGS)
+
+pam_unix_la_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ pam_unix_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+pam_unix_la_LIBADD = $(top_builddir)/libpam/libpam.la \
+ @LIBCRYPT@ @LIBSELINUX@ @TIRPC_LIBS@ @NSL_LIBS@
+
+securelib_LTLIBRARIES = pam_unix.la
+
+noinst_HEADERS = md5.h support.h yppasswd.h bigcrypt.h passverify.h
+
+sbin_PROGRAMS = unix_chkpwd unix_update
+
+noinst_PROGRAMS = bigcrypt
+
+pam_unix_la_SOURCES = bigcrypt.c pam_unix_acct.c \
+ pam_unix_auth.c pam_unix_passwd.c pam_unix_sess.c support.c \
+ passverify.c yppasswd_xdr.c md5_good.c md5_broken.c
+
+bigcrypt_SOURCES = bigcrypt.c bigcrypt_main.c
+bigcrypt_CFLAGS = $(AM_CFLAGS)
+bigcrypt_LDADD = @LIBCRYPT@
+
+unix_chkpwd_SOURCES = unix_chkpwd.c md5_good.c md5_broken.c bigcrypt.c \
+ passverify.c
+unix_chkpwd_CFLAGS = $(AM_CFLAGS) @EXE_CFLAGS@ -DHELPER_COMPILE=\"unix_chkpwd\"
+unix_chkpwd_LDFLAGS = @EXE_LDFLAGS@
+unix_chkpwd_LDADD = @LIBCRYPT@ @LIBSELINUX@ @LIBAUDIT@
+
+unix_update_SOURCES = unix_update.c md5_good.c md5_broken.c bigcrypt.c \
+ passverify.c
+unix_update_CFLAGS = $(AM_CFLAGS) @EXE_CFLAGS@ -DHELPER_COMPILE=\"unix_update\"
+unix_update_LDFLAGS = @EXE_LDFLAGS@
+unix_update_LDADD = @LIBCRYPT@ @LIBSELINUX@
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_unix/Makefile.in b/modules/pam_unix/Makefile.in
new file mode 100644
index 0000000..4dcfdf6
--- /dev/null
+++ b/modules/pam_unix/Makefile.in
@@ -0,0 +1,1537 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009, 2011 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+sbin_PROGRAMS = unix_chkpwd$(EXEEXT) unix_update$(EXEEXT)
+noinst_PROGRAMS = bigcrypt$(EXEEXT)
+subdir = modules/pam_unix
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(noinst_HEADERS) \
+ $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(securelibdir)" \
+ "$(DESTDIR)$(man8dir)"
+PROGRAMS = $(noinst_PROGRAMS) $(sbin_PROGRAMS)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_unix_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+am_pam_unix_la_OBJECTS = bigcrypt.lo pam_unix_acct.lo pam_unix_auth.lo \
+ pam_unix_passwd.lo pam_unix_sess.lo support.lo passverify.lo \
+ yppasswd_xdr.lo md5_good.lo md5_broken.lo
+pam_unix_la_OBJECTS = $(am_pam_unix_la_OBJECTS)
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+pam_unix_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(pam_unix_la_LDFLAGS) $(LDFLAGS) -o $@
+am_bigcrypt_OBJECTS = bigcrypt-bigcrypt.$(OBJEXT) \
+ bigcrypt-bigcrypt_main.$(OBJEXT)
+bigcrypt_OBJECTS = $(am_bigcrypt_OBJECTS)
+bigcrypt_DEPENDENCIES =
+bigcrypt_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(bigcrypt_CFLAGS) \
+ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_unix_chkpwd_OBJECTS = unix_chkpwd-unix_chkpwd.$(OBJEXT) \
+ unix_chkpwd-md5_good.$(OBJEXT) \
+ unix_chkpwd-md5_broken.$(OBJEXT) \
+ unix_chkpwd-bigcrypt.$(OBJEXT) \
+ unix_chkpwd-passverify.$(OBJEXT)
+unix_chkpwd_OBJECTS = $(am_unix_chkpwd_OBJECTS)
+unix_chkpwd_DEPENDENCIES =
+unix_chkpwd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(unix_chkpwd_CFLAGS) \
+ $(CFLAGS) $(unix_chkpwd_LDFLAGS) $(LDFLAGS) -o $@
+am_unix_update_OBJECTS = unix_update-unix_update.$(OBJEXT) \
+ unix_update-md5_good.$(OBJEXT) \
+ unix_update-md5_broken.$(OBJEXT) \
+ unix_update-bigcrypt.$(OBJEXT) \
+ unix_update-passverify.$(OBJEXT)
+unix_update_OBJECTS = $(am_unix_update_OBJECTS)
+unix_update_DEPENDENCIES =
+unix_update_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(unix_update_CFLAGS) \
+ $(CFLAGS) $(unix_update_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/bigcrypt-bigcrypt.Po \
+ ./$(DEPDIR)/bigcrypt-bigcrypt_main.Po ./$(DEPDIR)/bigcrypt.Plo \
+ ./$(DEPDIR)/md5_broken.Plo ./$(DEPDIR)/md5_good.Plo \
+ ./$(DEPDIR)/pam_unix_acct.Plo ./$(DEPDIR)/pam_unix_auth.Plo \
+ ./$(DEPDIR)/pam_unix_passwd.Plo ./$(DEPDIR)/pam_unix_sess.Plo \
+ ./$(DEPDIR)/passverify.Plo ./$(DEPDIR)/support.Plo \
+ ./$(DEPDIR)/unix_chkpwd-bigcrypt.Po \
+ ./$(DEPDIR)/unix_chkpwd-md5_broken.Po \
+ ./$(DEPDIR)/unix_chkpwd-md5_good.Po \
+ ./$(DEPDIR)/unix_chkpwd-passverify.Po \
+ ./$(DEPDIR)/unix_chkpwd-unix_chkpwd.Po \
+ ./$(DEPDIR)/unix_update-bigcrypt.Po \
+ ./$(DEPDIR)/unix_update-md5_broken.Po \
+ ./$(DEPDIR)/unix_update-md5_good.Po \
+ ./$(DEPDIR)/unix_update-passverify.Po \
+ ./$(DEPDIR)/unix_update-unix_update.Po \
+ ./$(DEPDIR)/yppasswd_xdr.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = $(pam_unix_la_SOURCES) $(bigcrypt_SOURCES) \
+ $(unix_chkpwd_SOURCES) $(unix_update_SOURCES)
+DIST_SOURCES = $(pam_unix_la_SOURCES) $(bigcrypt_SOURCES) \
+ $(unix_chkpwd_SOURCES) $(unix_update_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = md5.c md5_crypt.c lckpwdf.-c $(XMLS) CHANGELOG
+@HAVE_DOC_TRUE@dist_man_MANS = pam_unix.8 unix_chkpwd.8 unix_update.8
+XMLS = README.xml pam_unix.8.xml unix_chkpwd.8.xml unix_update.8.xml
+dist_check_SCRIPTS = tst-pam_unix
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DCHKPWD_HELPER=\"$(sbindir)/unix_chkpwd\" \
+ -DUPDATE_HELPER=\"$(sbindir)/unix_update\" \
+ @TIRPC_CFLAGS@ @NSL_CFLAGS@ $(WARN_CFLAGS)
+
+pam_unix_la_LDFLAGS = -no-undefined -avoid-version -module \
+ $(am__append_1)
+pam_unix_la_LIBADD = $(top_builddir)/libpam/libpam.la \
+ @LIBCRYPT@ @LIBSELINUX@ @TIRPC_LIBS@ @NSL_LIBS@
+
+securelib_LTLIBRARIES = pam_unix.la
+noinst_HEADERS = md5.h support.h yppasswd.h bigcrypt.h passverify.h
+pam_unix_la_SOURCES = bigcrypt.c pam_unix_acct.c \
+ pam_unix_auth.c pam_unix_passwd.c pam_unix_sess.c support.c \
+ passverify.c yppasswd_xdr.c md5_good.c md5_broken.c
+
+bigcrypt_SOURCES = bigcrypt.c bigcrypt_main.c
+bigcrypt_CFLAGS = $(AM_CFLAGS)
+bigcrypt_LDADD = @LIBCRYPT@
+unix_chkpwd_SOURCES = unix_chkpwd.c md5_good.c md5_broken.c bigcrypt.c \
+ passverify.c
+
+unix_chkpwd_CFLAGS = $(AM_CFLAGS) @EXE_CFLAGS@ -DHELPER_COMPILE=\"unix_chkpwd\"
+unix_chkpwd_LDFLAGS = @EXE_LDFLAGS@
+unix_chkpwd_LDADD = @LIBCRYPT@ @LIBSELINUX@ @LIBAUDIT@
+unix_update_SOURCES = unix_update.c md5_good.c md5_broken.c bigcrypt.c \
+ passverify.c
+
+unix_update_CFLAGS = $(AM_CFLAGS) @EXE_CFLAGS@ -DHELPER_COMPILE=\"unix_update\"
+unix_update_LDFLAGS = @EXE_LDFLAGS@
+unix_update_LDADD = @LIBCRYPT@ @LIBSELINUX@
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_unix/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_unix/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
+ fi; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p \
+ || test -f $$p1 \
+ ; then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' \
+ -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' \
+ `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(sbindir)" && rm -f $$files
+
+clean-sbinPROGRAMS:
+ @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_unix.la: $(pam_unix_la_OBJECTS) $(pam_unix_la_DEPENDENCIES) $(EXTRA_pam_unix_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(pam_unix_la_LINK) -rpath $(securelibdir) $(pam_unix_la_OBJECTS) $(pam_unix_la_LIBADD) $(LIBS)
+
+bigcrypt$(EXEEXT): $(bigcrypt_OBJECTS) $(bigcrypt_DEPENDENCIES) $(EXTRA_bigcrypt_DEPENDENCIES)
+ @rm -f bigcrypt$(EXEEXT)
+ $(AM_V_CCLD)$(bigcrypt_LINK) $(bigcrypt_OBJECTS) $(bigcrypt_LDADD) $(LIBS)
+
+unix_chkpwd$(EXEEXT): $(unix_chkpwd_OBJECTS) $(unix_chkpwd_DEPENDENCIES) $(EXTRA_unix_chkpwd_DEPENDENCIES)
+ @rm -f unix_chkpwd$(EXEEXT)
+ $(AM_V_CCLD)$(unix_chkpwd_LINK) $(unix_chkpwd_OBJECTS) $(unix_chkpwd_LDADD) $(LIBS)
+
+unix_update$(EXEEXT): $(unix_update_OBJECTS) $(unix_update_DEPENDENCIES) $(EXTRA_unix_update_DEPENDENCIES)
+ @rm -f unix_update$(EXEEXT)
+ $(AM_V_CCLD)$(unix_update_LINK) $(unix_update_OBJECTS) $(unix_update_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bigcrypt-bigcrypt.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bigcrypt-bigcrypt_main.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bigcrypt.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5_broken.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5_good.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_unix_acct.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_unix_auth.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_unix_passwd.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_unix_sess.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/passverify.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/support.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_chkpwd-bigcrypt.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_chkpwd-md5_broken.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_chkpwd-md5_good.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_chkpwd-passverify.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_chkpwd-unix_chkpwd.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_update-bigcrypt.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_update-md5_broken.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_update-md5_good.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_update-passverify.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix_update-unix_update.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/yppasswd_xdr.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+bigcrypt-bigcrypt.o: bigcrypt.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bigcrypt_CFLAGS) $(CFLAGS) -MT bigcrypt-bigcrypt.o -MD -MP -MF $(DEPDIR)/bigcrypt-bigcrypt.Tpo -c -o bigcrypt-bigcrypt.o `test -f 'bigcrypt.c' || echo '$(srcdir)/'`bigcrypt.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bigcrypt-bigcrypt.Tpo $(DEPDIR)/bigcrypt-bigcrypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bigcrypt.c' object='bigcrypt-bigcrypt.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bigcrypt_CFLAGS) $(CFLAGS) -c -o bigcrypt-bigcrypt.o `test -f 'bigcrypt.c' || echo '$(srcdir)/'`bigcrypt.c
+
+bigcrypt-bigcrypt.obj: bigcrypt.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bigcrypt_CFLAGS) $(CFLAGS) -MT bigcrypt-bigcrypt.obj -MD -MP -MF $(DEPDIR)/bigcrypt-bigcrypt.Tpo -c -o bigcrypt-bigcrypt.obj `if test -f 'bigcrypt.c'; then $(CYGPATH_W) 'bigcrypt.c'; else $(CYGPATH_W) '$(srcdir)/bigcrypt.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bigcrypt-bigcrypt.Tpo $(DEPDIR)/bigcrypt-bigcrypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bigcrypt.c' object='bigcrypt-bigcrypt.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bigcrypt_CFLAGS) $(CFLAGS) -c -o bigcrypt-bigcrypt.obj `if test -f 'bigcrypt.c'; then $(CYGPATH_W) 'bigcrypt.c'; else $(CYGPATH_W) '$(srcdir)/bigcrypt.c'; fi`
+
+bigcrypt-bigcrypt_main.o: bigcrypt_main.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bigcrypt_CFLAGS) $(CFLAGS) -MT bigcrypt-bigcrypt_main.o -MD -MP -MF $(DEPDIR)/bigcrypt-bigcrypt_main.Tpo -c -o bigcrypt-bigcrypt_main.o `test -f 'bigcrypt_main.c' || echo '$(srcdir)/'`bigcrypt_main.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bigcrypt-bigcrypt_main.Tpo $(DEPDIR)/bigcrypt-bigcrypt_main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bigcrypt_main.c' object='bigcrypt-bigcrypt_main.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bigcrypt_CFLAGS) $(CFLAGS) -c -o bigcrypt-bigcrypt_main.o `test -f 'bigcrypt_main.c' || echo '$(srcdir)/'`bigcrypt_main.c
+
+bigcrypt-bigcrypt_main.obj: bigcrypt_main.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bigcrypt_CFLAGS) $(CFLAGS) -MT bigcrypt-bigcrypt_main.obj -MD -MP -MF $(DEPDIR)/bigcrypt-bigcrypt_main.Tpo -c -o bigcrypt-bigcrypt_main.obj `if test -f 'bigcrypt_main.c'; then $(CYGPATH_W) 'bigcrypt_main.c'; else $(CYGPATH_W) '$(srcdir)/bigcrypt_main.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/bigcrypt-bigcrypt_main.Tpo $(DEPDIR)/bigcrypt-bigcrypt_main.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bigcrypt_main.c' object='bigcrypt-bigcrypt_main.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(bigcrypt_CFLAGS) $(CFLAGS) -c -o bigcrypt-bigcrypt_main.obj `if test -f 'bigcrypt_main.c'; then $(CYGPATH_W) 'bigcrypt_main.c'; else $(CYGPATH_W) '$(srcdir)/bigcrypt_main.c'; fi`
+
+unix_chkpwd-unix_chkpwd.o: unix_chkpwd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -MT unix_chkpwd-unix_chkpwd.o -MD -MP -MF $(DEPDIR)/unix_chkpwd-unix_chkpwd.Tpo -c -o unix_chkpwd-unix_chkpwd.o `test -f 'unix_chkpwd.c' || echo '$(srcdir)/'`unix_chkpwd.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unix_chkpwd-unix_chkpwd.Tpo $(DEPDIR)/unix_chkpwd-unix_chkpwd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix_chkpwd.c' object='unix_chkpwd-unix_chkpwd.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -c -o unix_chkpwd-unix_chkpwd.o `test -f 'unix_chkpwd.c' || echo '$(srcdir)/'`unix_chkpwd.c
+
+unix_chkpwd-unix_chkpwd.obj: unix_chkpwd.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -MT unix_chkpwd-unix_chkpwd.obj -MD -MP -MF $(DEPDIR)/unix_chkpwd-unix_chkpwd.Tpo -c -o unix_chkpwd-unix_chkpwd.obj `if test -f 'unix_chkpwd.c'; then $(CYGPATH_W) 'unix_chkpwd.c'; else $(CYGPATH_W) '$(srcdir)/unix_chkpwd.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unix_chkpwd-unix_chkpwd.Tpo $(DEPDIR)/unix_chkpwd-unix_chkpwd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix_chkpwd.c' object='unix_chkpwd-unix_chkpwd.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -c -o unix_chkpwd-unix_chkpwd.obj `if test -f 'unix_chkpwd.c'; then $(CYGPATH_W) 'unix_chkpwd.c'; else $(CYGPATH_W) '$(srcdir)/unix_chkpwd.c'; fi`
+
+unix_chkpwd-md5_good.o: md5_good.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -MT unix_chkpwd-md5_good.o -MD -MP -MF $(DEPDIR)/unix_chkpwd-md5_good.Tpo -c -o unix_chkpwd-md5_good.o `test -f 'md5_good.c' || echo '$(srcdir)/'`md5_good.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unix_chkpwd-md5_good.Tpo $(DEPDIR)/unix_chkpwd-md5_good.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md5_good.c' object='unix_chkpwd-md5_good.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -c -o unix_chkpwd-md5_good.o `test -f 'md5_good.c' || echo '$(srcdir)/'`md5_good.c
+
+unix_chkpwd-md5_good.obj: md5_good.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -MT unix_chkpwd-md5_good.obj -MD -MP -MF $(DEPDIR)/unix_chkpwd-md5_good.Tpo -c -o unix_chkpwd-md5_good.obj `if test -f 'md5_good.c'; then $(CYGPATH_W) 'md5_good.c'; else $(CYGPATH_W) '$(srcdir)/md5_good.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unix_chkpwd-md5_good.Tpo $(DEPDIR)/unix_chkpwd-md5_good.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md5_good.c' object='unix_chkpwd-md5_good.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -c -o unix_chkpwd-md5_good.obj `if test -f 'md5_good.c'; then $(CYGPATH_W) 'md5_good.c'; else $(CYGPATH_W) '$(srcdir)/md5_good.c'; fi`
+
+unix_chkpwd-md5_broken.o: md5_broken.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -MT unix_chkpwd-md5_broken.o -MD -MP -MF $(DEPDIR)/unix_chkpwd-md5_broken.Tpo -c -o unix_chkpwd-md5_broken.o `test -f 'md5_broken.c' || echo '$(srcdir)/'`md5_broken.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unix_chkpwd-md5_broken.Tpo $(DEPDIR)/unix_chkpwd-md5_broken.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md5_broken.c' object='unix_chkpwd-md5_broken.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -c -o unix_chkpwd-md5_broken.o `test -f 'md5_broken.c' || echo '$(srcdir)/'`md5_broken.c
+
+unix_chkpwd-md5_broken.obj: md5_broken.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -MT unix_chkpwd-md5_broken.obj -MD -MP -MF $(DEPDIR)/unix_chkpwd-md5_broken.Tpo -c -o unix_chkpwd-md5_broken.obj `if test -f 'md5_broken.c'; then $(CYGPATH_W) 'md5_broken.c'; else $(CYGPATH_W) '$(srcdir)/md5_broken.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unix_chkpwd-md5_broken.Tpo $(DEPDIR)/unix_chkpwd-md5_broken.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md5_broken.c' object='unix_chkpwd-md5_broken.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -c -o unix_chkpwd-md5_broken.obj `if test -f 'md5_broken.c'; then $(CYGPATH_W) 'md5_broken.c'; else $(CYGPATH_W) '$(srcdir)/md5_broken.c'; fi`
+
+unix_chkpwd-bigcrypt.o: bigcrypt.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -MT unix_chkpwd-bigcrypt.o -MD -MP -MF $(DEPDIR)/unix_chkpwd-bigcrypt.Tpo -c -o unix_chkpwd-bigcrypt.o `test -f 'bigcrypt.c' || echo '$(srcdir)/'`bigcrypt.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unix_chkpwd-bigcrypt.Tpo $(DEPDIR)/unix_chkpwd-bigcrypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bigcrypt.c' object='unix_chkpwd-bigcrypt.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -c -o unix_chkpwd-bigcrypt.o `test -f 'bigcrypt.c' || echo '$(srcdir)/'`bigcrypt.c
+
+unix_chkpwd-bigcrypt.obj: bigcrypt.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -MT unix_chkpwd-bigcrypt.obj -MD -MP -MF $(DEPDIR)/unix_chkpwd-bigcrypt.Tpo -c -o unix_chkpwd-bigcrypt.obj `if test -f 'bigcrypt.c'; then $(CYGPATH_W) 'bigcrypt.c'; else $(CYGPATH_W) '$(srcdir)/bigcrypt.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unix_chkpwd-bigcrypt.Tpo $(DEPDIR)/unix_chkpwd-bigcrypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bigcrypt.c' object='unix_chkpwd-bigcrypt.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -c -o unix_chkpwd-bigcrypt.obj `if test -f 'bigcrypt.c'; then $(CYGPATH_W) 'bigcrypt.c'; else $(CYGPATH_W) '$(srcdir)/bigcrypt.c'; fi`
+
+unix_chkpwd-passverify.o: passverify.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -MT unix_chkpwd-passverify.o -MD -MP -MF $(DEPDIR)/unix_chkpwd-passverify.Tpo -c -o unix_chkpwd-passverify.o `test -f 'passverify.c' || echo '$(srcdir)/'`passverify.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unix_chkpwd-passverify.Tpo $(DEPDIR)/unix_chkpwd-passverify.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='passverify.c' object='unix_chkpwd-passverify.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -c -o unix_chkpwd-passverify.o `test -f 'passverify.c' || echo '$(srcdir)/'`passverify.c
+
+unix_chkpwd-passverify.obj: passverify.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -MT unix_chkpwd-passverify.obj -MD -MP -MF $(DEPDIR)/unix_chkpwd-passverify.Tpo -c -o unix_chkpwd-passverify.obj `if test -f 'passverify.c'; then $(CYGPATH_W) 'passverify.c'; else $(CYGPATH_W) '$(srcdir)/passverify.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unix_chkpwd-passverify.Tpo $(DEPDIR)/unix_chkpwd-passverify.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='passverify.c' object='unix_chkpwd-passverify.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_chkpwd_CFLAGS) $(CFLAGS) -c -o unix_chkpwd-passverify.obj `if test -f 'passverify.c'; then $(CYGPATH_W) 'passverify.c'; else $(CYGPATH_W) '$(srcdir)/passverify.c'; fi`
+
+unix_update-unix_update.o: unix_update.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_update_CFLAGS) $(CFLAGS) -MT unix_update-unix_update.o -MD -MP -MF $(DEPDIR)/unix_update-unix_update.Tpo -c -o unix_update-unix_update.o `test -f 'unix_update.c' || echo '$(srcdir)/'`unix_update.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unix_update-unix_update.Tpo $(DEPDIR)/unix_update-unix_update.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix_update.c' object='unix_update-unix_update.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_update_CFLAGS) $(CFLAGS) -c -o unix_update-unix_update.o `test -f 'unix_update.c' || echo '$(srcdir)/'`unix_update.c
+
+unix_update-unix_update.obj: unix_update.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_update_CFLAGS) $(CFLAGS) -MT unix_update-unix_update.obj -MD -MP -MF $(DEPDIR)/unix_update-unix_update.Tpo -c -o unix_update-unix_update.obj `if test -f 'unix_update.c'; then $(CYGPATH_W) 'unix_update.c'; else $(CYGPATH_W) '$(srcdir)/unix_update.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unix_update-unix_update.Tpo $(DEPDIR)/unix_update-unix_update.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='unix_update.c' object='unix_update-unix_update.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_update_CFLAGS) $(CFLAGS) -c -o unix_update-unix_update.obj `if test -f 'unix_update.c'; then $(CYGPATH_W) 'unix_update.c'; else $(CYGPATH_W) '$(srcdir)/unix_update.c'; fi`
+
+unix_update-md5_good.o: md5_good.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_update_CFLAGS) $(CFLAGS) -MT unix_update-md5_good.o -MD -MP -MF $(DEPDIR)/unix_update-md5_good.Tpo -c -o unix_update-md5_good.o `test -f 'md5_good.c' || echo '$(srcdir)/'`md5_good.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unix_update-md5_good.Tpo $(DEPDIR)/unix_update-md5_good.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md5_good.c' object='unix_update-md5_good.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_update_CFLAGS) $(CFLAGS) -c -o unix_update-md5_good.o `test -f 'md5_good.c' || echo '$(srcdir)/'`md5_good.c
+
+unix_update-md5_good.obj: md5_good.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_update_CFLAGS) $(CFLAGS) -MT unix_update-md5_good.obj -MD -MP -MF $(DEPDIR)/unix_update-md5_good.Tpo -c -o unix_update-md5_good.obj `if test -f 'md5_good.c'; then $(CYGPATH_W) 'md5_good.c'; else $(CYGPATH_W) '$(srcdir)/md5_good.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unix_update-md5_good.Tpo $(DEPDIR)/unix_update-md5_good.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md5_good.c' object='unix_update-md5_good.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_update_CFLAGS) $(CFLAGS) -c -o unix_update-md5_good.obj `if test -f 'md5_good.c'; then $(CYGPATH_W) 'md5_good.c'; else $(CYGPATH_W) '$(srcdir)/md5_good.c'; fi`
+
+unix_update-md5_broken.o: md5_broken.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_update_CFLAGS) $(CFLAGS) -MT unix_update-md5_broken.o -MD -MP -MF $(DEPDIR)/unix_update-md5_broken.Tpo -c -o unix_update-md5_broken.o `test -f 'md5_broken.c' || echo '$(srcdir)/'`md5_broken.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unix_update-md5_broken.Tpo $(DEPDIR)/unix_update-md5_broken.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md5_broken.c' object='unix_update-md5_broken.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_update_CFLAGS) $(CFLAGS) -c -o unix_update-md5_broken.o `test -f 'md5_broken.c' || echo '$(srcdir)/'`md5_broken.c
+
+unix_update-md5_broken.obj: md5_broken.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_update_CFLAGS) $(CFLAGS) -MT unix_update-md5_broken.obj -MD -MP -MF $(DEPDIR)/unix_update-md5_broken.Tpo -c -o unix_update-md5_broken.obj `if test -f 'md5_broken.c'; then $(CYGPATH_W) 'md5_broken.c'; else $(CYGPATH_W) '$(srcdir)/md5_broken.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unix_update-md5_broken.Tpo $(DEPDIR)/unix_update-md5_broken.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='md5_broken.c' object='unix_update-md5_broken.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_update_CFLAGS) $(CFLAGS) -c -o unix_update-md5_broken.obj `if test -f 'md5_broken.c'; then $(CYGPATH_W) 'md5_broken.c'; else $(CYGPATH_W) '$(srcdir)/md5_broken.c'; fi`
+
+unix_update-bigcrypt.o: bigcrypt.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_update_CFLAGS) $(CFLAGS) -MT unix_update-bigcrypt.o -MD -MP -MF $(DEPDIR)/unix_update-bigcrypt.Tpo -c -o unix_update-bigcrypt.o `test -f 'bigcrypt.c' || echo '$(srcdir)/'`bigcrypt.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unix_update-bigcrypt.Tpo $(DEPDIR)/unix_update-bigcrypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bigcrypt.c' object='unix_update-bigcrypt.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_update_CFLAGS) $(CFLAGS) -c -o unix_update-bigcrypt.o `test -f 'bigcrypt.c' || echo '$(srcdir)/'`bigcrypt.c
+
+unix_update-bigcrypt.obj: bigcrypt.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_update_CFLAGS) $(CFLAGS) -MT unix_update-bigcrypt.obj -MD -MP -MF $(DEPDIR)/unix_update-bigcrypt.Tpo -c -o unix_update-bigcrypt.obj `if test -f 'bigcrypt.c'; then $(CYGPATH_W) 'bigcrypt.c'; else $(CYGPATH_W) '$(srcdir)/bigcrypt.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unix_update-bigcrypt.Tpo $(DEPDIR)/unix_update-bigcrypt.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bigcrypt.c' object='unix_update-bigcrypt.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_update_CFLAGS) $(CFLAGS) -c -o unix_update-bigcrypt.obj `if test -f 'bigcrypt.c'; then $(CYGPATH_W) 'bigcrypt.c'; else $(CYGPATH_W) '$(srcdir)/bigcrypt.c'; fi`
+
+unix_update-passverify.o: passverify.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_update_CFLAGS) $(CFLAGS) -MT unix_update-passverify.o -MD -MP -MF $(DEPDIR)/unix_update-passverify.Tpo -c -o unix_update-passverify.o `test -f 'passverify.c' || echo '$(srcdir)/'`passverify.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unix_update-passverify.Tpo $(DEPDIR)/unix_update-passverify.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='passverify.c' object='unix_update-passverify.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_update_CFLAGS) $(CFLAGS) -c -o unix_update-passverify.o `test -f 'passverify.c' || echo '$(srcdir)/'`passverify.c
+
+unix_update-passverify.obj: passverify.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_update_CFLAGS) $(CFLAGS) -MT unix_update-passverify.obj -MD -MP -MF $(DEPDIR)/unix_update-passverify.Tpo -c -o unix_update-passverify.obj `if test -f 'passverify.c'; then $(CYGPATH_W) 'passverify.c'; else $(CYGPATH_W) '$(srcdir)/passverify.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/unix_update-passverify.Tpo $(DEPDIR)/unix_update-passverify.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='passverify.c' object='unix_update-passverify.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(unix_update_CFLAGS) $(CFLAGS) -c -o unix_update-passverify.obj `if test -f 'passverify.c'; then $(CYGPATH_W) 'passverify.c'; else $(CYGPATH_W) '$(srcdir)/passverify.c'; fi`
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_unix.log: tst-pam_unix
+ @p='tst-pam_unix'; \
+ b='tst-pam_unix'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) $(MANS) $(DATA) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \
+ clean-sbinPROGRAMS clean-securelibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/bigcrypt-bigcrypt.Po
+ -rm -f ./$(DEPDIR)/bigcrypt-bigcrypt_main.Po
+ -rm -f ./$(DEPDIR)/bigcrypt.Plo
+ -rm -f ./$(DEPDIR)/md5_broken.Plo
+ -rm -f ./$(DEPDIR)/md5_good.Plo
+ -rm -f ./$(DEPDIR)/pam_unix_acct.Plo
+ -rm -f ./$(DEPDIR)/pam_unix_auth.Plo
+ -rm -f ./$(DEPDIR)/pam_unix_passwd.Plo
+ -rm -f ./$(DEPDIR)/pam_unix_sess.Plo
+ -rm -f ./$(DEPDIR)/passverify.Plo
+ -rm -f ./$(DEPDIR)/support.Plo
+ -rm -f ./$(DEPDIR)/unix_chkpwd-bigcrypt.Po
+ -rm -f ./$(DEPDIR)/unix_chkpwd-md5_broken.Po
+ -rm -f ./$(DEPDIR)/unix_chkpwd-md5_good.Po
+ -rm -f ./$(DEPDIR)/unix_chkpwd-passverify.Po
+ -rm -f ./$(DEPDIR)/unix_chkpwd-unix_chkpwd.Po
+ -rm -f ./$(DEPDIR)/unix_update-bigcrypt.Po
+ -rm -f ./$(DEPDIR)/unix_update-md5_broken.Po
+ -rm -f ./$(DEPDIR)/unix_update-md5_good.Po
+ -rm -f ./$(DEPDIR)/unix_update-passverify.Po
+ -rm -f ./$(DEPDIR)/unix_update-unix_update.Po
+ -rm -f ./$(DEPDIR)/yppasswd_xdr.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-sbinPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/bigcrypt-bigcrypt.Po
+ -rm -f ./$(DEPDIR)/bigcrypt-bigcrypt_main.Po
+ -rm -f ./$(DEPDIR)/bigcrypt.Plo
+ -rm -f ./$(DEPDIR)/md5_broken.Plo
+ -rm -f ./$(DEPDIR)/md5_good.Plo
+ -rm -f ./$(DEPDIR)/pam_unix_acct.Plo
+ -rm -f ./$(DEPDIR)/pam_unix_auth.Plo
+ -rm -f ./$(DEPDIR)/pam_unix_passwd.Plo
+ -rm -f ./$(DEPDIR)/pam_unix_sess.Plo
+ -rm -f ./$(DEPDIR)/passverify.Plo
+ -rm -f ./$(DEPDIR)/support.Plo
+ -rm -f ./$(DEPDIR)/unix_chkpwd-bigcrypt.Po
+ -rm -f ./$(DEPDIR)/unix_chkpwd-md5_broken.Po
+ -rm -f ./$(DEPDIR)/unix_chkpwd-md5_good.Po
+ -rm -f ./$(DEPDIR)/unix_chkpwd-passverify.Po
+ -rm -f ./$(DEPDIR)/unix_chkpwd-unix_chkpwd.Po
+ -rm -f ./$(DEPDIR)/unix_update-bigcrypt.Po
+ -rm -f ./$(DEPDIR)/unix_update-md5_broken.Po
+ -rm -f ./$(DEPDIR)/unix_update-md5_good.Po
+ -rm -f ./$(DEPDIR)/unix_update-passverify.Po
+ -rm -f ./$(DEPDIR)/unix_update-unix_update.Po
+ -rm -f ./$(DEPDIR)/yppasswd_xdr.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-sbinPROGRAMS \
+ uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-noinstPROGRAMS clean-sbinPROGRAMS \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am install-sbinPROGRAMS \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-sbinPROGRAMS \
+ uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_unix/README b/modules/pam_unix/README
new file mode 100644
index 0000000..67a2d21
--- /dev/null
+++ b/modules/pam_unix/README
@@ -0,0 +1,206 @@
+pam_unix — Module for traditional password authentication
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+This is the standard Unix authentication module. It uses standard calls from
+the system's libraries to retrieve and set account information as well as
+authentication. Usually this is obtained from the /etc/passwd and the /etc/
+shadow file as well if shadow is enabled.
+
+The account component performs the task of establishing the status of the
+user's account and password based on the following shadow elements: expire,
+last_change, max_change, min_change, warn_change. In the case of the latter, it
+may offer advice to the user on changing their password or, through the
+PAM_AUTHTOKEN_REQD return, delay giving service to the user until they have
+established a new password. The entries listed above are documented in the
+shadow(5) manual page. Should the user's record not contain one or more of
+these entries, the corresponding shadow check is not performed.
+
+The authentication component performs the task of checking the users
+credentials (password). The default action of this module is to not permit the
+user access to a service if their official password is blank.
+
+A helper binary, unix_chkpwd(8), is provided to check the user's password when
+it is stored in a read protected database. This binary is very simple and will
+only check the password of the user invoking it. It is called transparently on
+behalf of the user by the authenticating component of this module. In this way
+it is possible for applications like xlock(1) to work without being
+setuid-root. The module, by default, will temporarily turn off SIGCHLD handling
+for the duration of execution of the helper binary. This is generally the right
+thing to do, as many applications are not prepared to handle this signal from a
+child they didn't know was fork()d. The noreap module argument can be used to
+suppress this temporary shielding and may be needed for use with certain
+applications.
+
+The maximum length of a password supported by the pam_unix module via the
+helper binary is PAM_MAX_RESP_SIZE - currently 512 bytes. The rest of the
+password provided by the conversation function to the module will be ignored.
+
+The password component of this module performs the task of updating the user's
+password. The default encryption hash is taken from the ENCRYPT_METHOD variable
+from /etc/login.defs
+
+The session component of this module logs when a user logins or leave the
+system.
+
+Remaining arguments, supported by others functions of this module, are silently
+ignored. Other arguments are logged as errors through syslog(3).
+
+OPTIONS
+
+debug
+
+ Turns on debugging via syslog(3).
+
+audit
+
+ A little more extreme than debug.
+
+quiet
+
+ Turns off informational messages namely messages about session open and
+ close via syslog(3).
+
+nullok
+
+ The default action of this module is to not permit the user access to a
+ service if their official password is blank. The nullok argument overrides
+ this default.
+
+nullresetok
+
+ Allow users to authenticate with blank password if password reset is
+ enforced even if nullok is not set. If password reset is not required and
+ nullok is not set the authentication with blank password will be denied.
+
+try_first_pass
+
+ Before prompting the user for their password, the module first tries the
+ previous stacked module's password in case that satisfies this module as
+ well.
+
+use_first_pass
+
+ The argument use_first_pass forces the module to use a previous stacked
+ modules password and will never prompt the user - if no password is
+ available or the password is not appropriate, the user will be denied
+ access.
+
+nodelay
+
+ This argument can be used to discourage the authentication component from
+ requesting a delay should the authentication as a whole fail. The default
+ action is for the module to request a delay-on-failure of the order of two
+ second.
+
+use_authtok
+
+ When password changing enforce the module to set the new password to the
+ one provided by a previously stacked password module (this is used in the
+ example of the stacking of the pam_passwdqc module documented below).
+
+authtok_type=type
+
+ This argument can be used to modify the password prompt when changing
+ passwords to include the type of the password. Empty by default.
+
+nis
+
+ NIS RPC is used for setting new passwords.
+
+remember=n
+
+ The last n passwords for each user are saved in /etc/security/opasswd in
+ order to force password change history and keep the user from alternating
+ between the same password too frequently. The MD5 password hash algorithm
+ is used for storing the old passwords. Instead of this option the
+ pam_pwhistory module should be used.
+
+shadow
+
+ Try to maintain a shadow based system.
+
+md5
+
+ When a user changes their password next, encrypt it with the MD5 algorithm.
+
+bigcrypt
+
+ When a user changes their password next, encrypt it with the DEC C2
+ algorithm.
+
+sha256
+
+ When a user changes their password next, encrypt it with the SHA256
+ algorithm. The SHA256 algorithm must be supported by the crypt(3) function.
+
+sha512
+
+ When a user changes their password next, encrypt it with the SHA512
+ algorithm. The SHA512 algorithm must be supported by the crypt(3) function.
+
+blowfish
+
+ When a user changes their password next, encrypt it with the blowfish
+ algorithm. The blowfish algorithm must be supported by the crypt(3)
+ function.
+
+gost_yescrypt
+
+ When a user changes their password next, encrypt it with the gost-yescrypt
+ algorithm. The gost-yescrypt algorithm must be supported by the crypt(3)
+ function.
+
+yescrypt
+
+ When a user changes their password next, encrypt it with the yescrypt
+ algorithm. The yescrypt algorithm must be supported by the crypt(3)
+ function.
+
+rounds=n
+
+ Set the optional number of rounds of the SHA256, SHA512, blowfish,
+ gost-yescrypt, and yescrypt password hashing algorithms to n.
+
+broken_shadow
+
+ Ignore errors reading shadow information for users in the account
+ management module.
+
+minlen=n
+
+ Set a minimum password length of n characters. The max. for DES crypt based
+ passwords are 8 characters.
+
+no_pass_expiry
+
+ When set ignore password expiration as defined by the shadow entry of the
+ user. The option has an effect only in case pam_unix was not used for the
+ authentication or it returned authentication failure meaning that other
+ authentication source or method succeeded. The example can be public key
+ authentication in sshd. The module will return PAM_SUCCESS instead of
+ eventual PAM_NEW_AUTHTOK_REQD or PAM_AUTHTOK_EXPIRED.
+
+Invalid arguments are logged with syslog(3).
+
+EXAMPLES
+
+An example usage for /etc/pam.d/login would be:
+
+# Authenticate the user
+auth required pam_unix.so
+# Ensure users account and password are still active
+account required pam_unix.so
+# Change the user's password, but at first check the strength
+# with pam_passwdqc(8)
+password required pam_passwdqc.so config=/etc/passwdqc.conf
+password required pam_unix.so use_authtok nullok yescrypt
+session required pam_unix.so
+
+
+AUTHOR
+
+pam_unix was written by various people.
+
diff --git a/modules/pam_unix/README.xml b/modules/pam_unix/README.xml
new file mode 100644
index 0000000..7fd340b
--- /dev/null
+++ b/modules/pam_unix/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_unix.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_unix.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_unix-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_unix.8.xml" xpointer='xpointer(//refsect1[@id = "pam_unix-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_unix.8.xml" xpointer='xpointer(//refsect1[@id = "pam_unix-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_unix.8.xml" xpointer='xpointer(//refsect1[@id = "pam_unix-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_unix.8.xml" xpointer='xpointer(//refsect1[@id = "pam_unix-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_unix/bigcrypt.c b/modules/pam_unix/bigcrypt.c
new file mode 100644
index 0000000..d8d61a4
--- /dev/null
+++ b/modules/pam_unix/bigcrypt.c
@@ -0,0 +1,163 @@
+/*
+ * This function implements the "bigcrypt" algorithm specifically for
+ * Linux-PAM.
+ *
+ * This algorithm is algorithm 0 (default) shipped with the C2 secure
+ * implementation of Digital UNIX.
+ *
+ * Disclaimer: This work is not based on the source code to Digital
+ * UNIX, nor am I connected to Digital Equipment Corp, in any way
+ * other than as a customer. This code is based on published
+ * interfaces and reasonable guesswork.
+ *
+ * Description: The cleartext is divided into blocks of SEGMENT_SIZE=8
+ * characters or less. Each block is encrypted using the standard UNIX
+ * libc crypt function. The result of the encryption for one block
+ * provides the salt for the succeeding block.
+ *
+ * Restrictions: The buffer used to hold the encrypted result is
+ * statically allocated. (see MAX_PASS_LEN below). This is necessary,
+ * as the returned pointer points to "static data that are overwritten
+ * by each call", (XPG3: XSI System Interface + Headers pg 109), and
+ * this is a drop in replacement for crypt();
+ *
+ * Andy Phillips <atp@mssl.ucl.ac.uk>
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <security/_pam_macros.h>
+#ifdef HAVE_CRYPT_H
+#include <crypt.h>
+#endif
+
+#include "bigcrypt.h"
+
+/*
+ * Max cleartext password length in segments of 8 characters this
+ * function can deal with (16 segments of 8 chars= max 128 character
+ * password).
+ */
+
+#define MAX_PASS_LEN 16
+#define SEGMENT_SIZE 8
+#define SALT_SIZE 2
+#define KEYBUF_SIZE ((MAX_PASS_LEN*SEGMENT_SIZE)+SALT_SIZE)
+#define ESEGMENT_SIZE 11
+#define CBUF_SIZE ((MAX_PASS_LEN*ESEGMENT_SIZE)+SALT_SIZE+1)
+
+char *bigcrypt(const char *key, const char *salt)
+{
+ char *dec_c2_cryptbuf;
+#ifdef HAVE_CRYPT_R
+ struct crypt_data *cdata;
+#endif
+ unsigned long int keylen, n_seg, j;
+ char *cipher_ptr, *plaintext_ptr, *tmp_ptr, *salt_ptr;
+ char keybuf[KEYBUF_SIZE + 1];
+
+ D(("called with key='%s', salt='%s'.", key, salt));
+
+ /* reset arrays */
+ dec_c2_cryptbuf = malloc(CBUF_SIZE);
+ if (!dec_c2_cryptbuf) {
+ return NULL;
+ }
+#ifdef HAVE_CRYPT_R
+ cdata = malloc(sizeof(*cdata));
+ if(!cdata) {
+ free(dec_c2_cryptbuf);
+ return NULL;
+ }
+ cdata->initialized = 0;
+#endif
+ memset(keybuf, 0, KEYBUF_SIZE + 1);
+ memset(dec_c2_cryptbuf, 0, CBUF_SIZE);
+
+ /* fill KEYBUF_SIZE with key */
+ strncpy(keybuf, key, KEYBUF_SIZE);
+
+ /* deal with case that we are doing a password check for a
+ conventially encrypted password: the salt will be
+ SALT_SIZE+ESEGMENT_SIZE long. */
+ if (strlen(salt) == (SALT_SIZE + ESEGMENT_SIZE))
+ keybuf[SEGMENT_SIZE] = '\0'; /* terminate password early(?) */
+
+ keylen = strlen(keybuf);
+
+ if (!keylen) {
+ n_seg = 1;
+ } else {
+ /* work out how many segments */
+ n_seg = 1 + ((keylen - 1) / SEGMENT_SIZE);
+ }
+
+ if (n_seg > MAX_PASS_LEN)
+ n_seg = MAX_PASS_LEN; /* truncate at max length */
+
+ /* set up some pointers */
+ cipher_ptr = dec_c2_cryptbuf;
+ plaintext_ptr = keybuf;
+
+ /* do the first block with supplied salt */
+#ifdef HAVE_CRYPT_R
+ tmp_ptr = crypt_r(plaintext_ptr, salt, cdata); /* libc crypt_r() */
+#else
+ tmp_ptr = crypt(plaintext_ptr, salt); /* libc crypt() */
+#endif
+ if (tmp_ptr == NULL) {
+ free(dec_c2_cryptbuf);
+#ifdef HAVE_CRYPT_R
+ free(cdata);
+#endif
+ return NULL;
+ }
+ /* and place in the static area */
+ strncpy(cipher_ptr, tmp_ptr, 13);
+ cipher_ptr += ESEGMENT_SIZE + SALT_SIZE;
+ plaintext_ptr += SEGMENT_SIZE; /* first block of SEGMENT_SIZE */
+
+ /* change the salt (1st 2 chars of previous block) - this was found
+ by dowsing */
+
+ salt_ptr = cipher_ptr - ESEGMENT_SIZE;
+
+ /* so far this is identical to "return crypt(key, salt);", if
+ there is more than one block encrypt them... */
+
+ if (n_seg > 1) {
+ for (j = 2; j <= n_seg; j++) {
+
+#ifdef HAVE_CRYPT_R
+ tmp_ptr = crypt_r(plaintext_ptr, salt_ptr, cdata);
+#else
+ tmp_ptr = crypt(plaintext_ptr, salt_ptr);
+#endif
+ if (tmp_ptr == NULL) {
+ _pam_overwrite(dec_c2_cryptbuf);
+ free(dec_c2_cryptbuf);
+#ifdef HAVE_CRYPT_R
+ free(cdata);
+#endif
+ return NULL;
+ }
+
+ /* skip the salt for seg!=0 */
+ strncpy(cipher_ptr, (tmp_ptr + SALT_SIZE), ESEGMENT_SIZE);
+
+ cipher_ptr += ESEGMENT_SIZE;
+ plaintext_ptr += SEGMENT_SIZE;
+ salt_ptr = cipher_ptr - ESEGMENT_SIZE;
+ }
+ }
+ D(("key=|%s|, salt=|%s|\nbuf=|%s|\n", key, salt, dec_c2_cryptbuf));
+
+#ifdef HAVE_CRYPT_R
+ free(cdata);
+#endif
+
+ /* this is the <NUL> terminated encrypted password */
+ return dec_c2_cryptbuf;
+}
diff --git a/modules/pam_unix/bigcrypt.h b/modules/pam_unix/bigcrypt.h
new file mode 100644
index 0000000..a66a96e
--- /dev/null
+++ b/modules/pam_unix/bigcrypt.h
@@ -0,0 +1 @@
+extern char *bigcrypt(const char *key, const char *salt);
diff --git a/modules/pam_unix/bigcrypt_main.c b/modules/pam_unix/bigcrypt_main.c
new file mode 100644
index 0000000..fab212d
--- /dev/null
+++ b/modules/pam_unix/bigcrypt_main.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <string.h>
+
+#include "bigcrypt.h"
+
+int
+main(int argc, char **argv)
+{
+ if (argc < 3) {
+ fprintf(stderr, "Usage: %s password salt\n",
+ strchr(argv[0], '/') ?
+ (strchr(argv[0], '/') + 1) :
+ argv[0]);
+ return 0;
+ }
+ fprintf(stdout, "%s\n", bigcrypt(argv[1], argv[2]));
+ return 0;
+}
diff --git a/modules/pam_unix/lckpwdf.-c b/modules/pam_unix/lckpwdf.-c
new file mode 100644
index 0000000..c3e6315
--- /dev/null
+++ b/modules/pam_unix/lckpwdf.-c
@@ -0,0 +1,142 @@
+/*
+ * This is a hack, but until libc and glibc both include this function
+ * by default (libc only includes it if nys is not being used, at the
+ * moment, and glibc doesn't appear to have it at all) we need to have
+ * it here, too. :-(
+ *
+ * This should not become an official part of PAM.
+ *
+ * BEGIN_HACK
+ */
+
+/*
+ * lckpwdf.c -- prevent simultaneous updates of password files
+ *
+ * Before modifying any of the password files, call lckpwdf(). It may block
+ * for up to 15 seconds trying to get the lock. Return value is 0 on success
+ * or -1 on failure. When you are done, call ulckpwdf() to release the lock.
+ * The lock is also released automatically when the process exits. Only one
+ * process at a time may hold the lock.
+ *
+ * These functions are supposed to be conformant with AT&T SVID Issue 3.
+ *
+ * Written by Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>,
+ * public domain.
+ */
+
+#include <fcntl.h>
+#include <signal.h>
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#endif
+
+#define LOCKFILE "/etc/.pwd.lock"
+#define TIMEOUT 15
+
+static int lockfd = -1;
+
+static int set_close_on_exec(int fd)
+{
+ int flags = fcntl(fd, F_GETFD, 0);
+ if (flags == -1)
+ return -1;
+ flags |= FD_CLOEXEC;
+ return fcntl(fd, F_SETFD, flags);
+}
+
+static int do_lock(int fd)
+{
+ struct flock fl;
+
+ memset(&fl, 0, sizeof fl);
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+ return fcntl(fd, F_SETLKW, &fl);
+}
+
+static void alarm_catch(int sig)
+{
+/* does nothing, but fcntl F_SETLKW will fail with EINTR */
+}
+
+static int lckpwdf(void)
+{
+ struct sigaction act, oldact;
+ sigset_t set, oldset;
+
+ if (lockfd != -1)
+ return -1;
+
+#ifdef WITH_SELINUX
+ if(is_selinux_enabled()>0)
+ {
+ lockfd = open(LOCKFILE, O_WRONLY);
+ if(lockfd == -1 && errno == ENOENT)
+ {
+ char *create_context_raw;
+ int rc;
+
+ if(getfilecon_raw("/etc/passwd", &create_context_raw))
+ return -1;
+ rc = setfscreatecon_raw(create_context_raw);
+ freecon(create_context_raw);
+ if(rc)
+ return -1;
+ lockfd = open(LOCKFILE, O_CREAT | O_WRONLY, 0600);
+ if(setfscreatecon_raw(NULL))
+ return -1;
+ }
+ }
+ else
+#endif
+ lockfd = open(LOCKFILE, O_CREAT | O_WRONLY, 0600);
+ if (lockfd == -1)
+ return -1;
+ if (set_close_on_exec(lockfd) == -1)
+ goto cleanup_fd;
+
+ memset(&act, 0, sizeof act);
+ act.sa_handler = alarm_catch;
+ act.sa_flags = 0;
+ sigfillset(&act.sa_mask);
+ if (sigaction(SIGALRM, &act, &oldact) == -1)
+ goto cleanup_fd;
+
+ sigemptyset(&set);
+ sigaddset(&set, SIGALRM);
+ if (sigprocmask(SIG_UNBLOCK, &set, &oldset) == -1)
+ goto cleanup_sig;
+
+ alarm(TIMEOUT);
+ if (do_lock(lockfd) == -1)
+ goto cleanup_alarm;
+ alarm(0);
+ sigprocmask(SIG_SETMASK, &oldset, NULL);
+ sigaction(SIGALRM, &oldact, NULL);
+ return 0;
+
+ cleanup_alarm:
+ alarm(0);
+ sigprocmask(SIG_SETMASK, &oldset, NULL);
+ cleanup_sig:
+ sigaction(SIGALRM, &oldact, NULL);
+ cleanup_fd:
+ close(lockfd);
+ lockfd = -1;
+ return -1;
+}
+
+static int ulckpwdf(void)
+{
+ unlink(LOCKFILE);
+ if (lockfd == -1)
+ return -1;
+
+ if (close(lockfd) == -1) {
+ lockfd = -1;
+ return -1;
+ }
+ lockfd = -1;
+ return 0;
+}
+/* END_HACK */
diff --git a/modules/pam_unix/md5.c b/modules/pam_unix/md5.c
new file mode 100644
index 0000000..593d6dc
--- /dev/null
+++ b/modules/pam_unix/md5.c
@@ -0,0 +1,258 @@
+/*
+ * $Id$
+ *
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ *
+ */
+
+#include <string.h>
+#include "md5.h"
+
+#ifndef HIGHFIRST
+#define byteReverse(buf, len) /* Nothing */
+#else
+
+typedef unsigned char PAM_ATTRIBUTE_ALIGNED(4) uint8_aligned;
+
+static void byteReverse(uint8_aligned *buf, unsigned longs);
+
+#ifndef ASM_MD5
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+static void byteReverse(uint8_aligned *buf, unsigned longs)
+{
+ uint32 t;
+ do {
+ t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
+ ((unsigned) buf[1] << 8 | buf[0]);
+ *(uint32 *) buf = t;
+ buf += 4;
+ } while (--longs);
+}
+#endif
+#endif
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void MD5Name(MD5Init)(struct MD5Context *ctx)
+{
+ ctx->buf.i[0] = 0x67452301U;
+ ctx->buf.i[1] = 0xefcdab89U;
+ ctx->buf.i[2] = 0x98badcfeU;
+ ctx->buf.i[3] = 0x10325476U;
+
+ ctx->bits[0] = 0;
+ ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void MD5Name(MD5Update)(struct MD5Context *ctx, unsigned const char *buf, unsigned len)
+{
+ uint32 t;
+
+ /* Update bitcount */
+
+ t = ctx->bits[0];
+ if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
+ ctx->bits[1]++; /* Carry from low to high */
+ ctx->bits[1] += len >> 29;
+
+ t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
+
+ /* Handle any leading odd-sized chunks */
+
+ if (t) {
+ unsigned char *p = ctx->in.c + t;
+
+ t = 64 - t;
+ if (len < t) {
+ memcpy(p, buf, len);
+ return;
+ }
+ memcpy(p, buf, t);
+ byteReverse(ctx->in.c, 16);
+ MD5Name(MD5Transform)(ctx->buf.i, ctx->in.i);
+ buf += t;
+ len -= t;
+ }
+ /* Process data in 64-byte chunks */
+
+ while (len >= 64) {
+ memcpy(ctx->in.c, buf, 64);
+ byteReverse(ctx->in.c, 16);
+ MD5Name(MD5Transform)(ctx->buf.i, ctx->in.i);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+
+ memcpy(ctx->in.c, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void MD5Name(MD5Final)(unsigned char digest[16], struct MD5Context *ctx)
+{
+ unsigned count;
+ unsigned char *p;
+
+ /* Compute number of bytes mod 64 */
+ count = (ctx->bits[0] >> 3) & 0x3F;
+
+ /* Set the first char of padding to 0x80. This is safe since there is
+ always at least one byte free */
+ p = ctx->in.c + count;
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 64 bytes */
+ count = 64 - 1 - count;
+
+ /* Pad out to 56 mod 64 */
+ if (count < 8) {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ memset(p, 0, count);
+ byteReverse(ctx->in.c, 16);
+ MD5Name(MD5Transform)(ctx->buf.i, ctx->in.i);
+
+ /* Now fill the next block with 56 bytes */
+ memset(ctx->in.c, 0, 56);
+ } else {
+ /* Pad block to 56 bytes */
+ memset(p, 0, count - 8);
+ }
+ byteReverse(ctx->in.c, 14);
+
+ /* Append length in bits and transform */
+ memcpy(ctx->in.i + 14, ctx->bits, 2*sizeof(uint32));
+
+ MD5Name(MD5Transform)(ctx->buf.i, ctx->in.i);
+ byteReverse(ctx->buf.c, 4);
+ memcpy(digest, ctx->buf.c, 16);
+ memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
+}
+
+#ifndef ASM_MD5
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void MD5Name(MD5Transform)(uint32 buf[4], uint32 const in[16])
+{
+ register uint32 a, b, c, d;
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478U, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756U, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070dbU, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceeeU, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0fafU, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62aU, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613U, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501U, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8U, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7afU, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1U, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7beU, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122U, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193U, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438eU, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821U, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562U, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340U, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51U, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aaU, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105dU, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453U, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681U, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8U, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6U, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6U, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87U, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14edU, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905U, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8U, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9U, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8aU, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942U, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681U, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122U, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380cU, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44U, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9U, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60U, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70U, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6U, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127faU, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085U, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05U, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039U, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5U, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8U, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665U, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244U, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97U, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7U, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039U, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3U, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92U, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47dU, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1U, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4fU, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0U, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314U, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1U, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82U, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235U, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bbU, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391U, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+
+#endif
diff --git a/modules/pam_unix/md5.h b/modules/pam_unix/md5.h
new file mode 100644
index 0000000..3dc54bd
--- /dev/null
+++ b/modules/pam_unix/md5.h
@@ -0,0 +1,39 @@
+
+#ifndef MD5_H
+#define MD5_H
+
+#include "pam_cc_compat.h"
+
+typedef unsigned int uint32;
+
+struct MD5Context {
+ union {
+ uint32 i[4];
+ unsigned char c[16] PAM_ATTRIBUTE_ALIGNED(4);
+ } buf;
+ uint32 bits[2];
+ union {
+ uint32 i[16];
+ unsigned char c[64] PAM_ATTRIBUTE_ALIGNED(4);
+ } in;
+};
+
+void GoodMD5Init(struct MD5Context *);
+void GoodMD5Update(struct MD5Context *, unsigned const char *, unsigned);
+void GoodMD5Final(unsigned char digest[16], struct MD5Context *);
+void GoodMD5Transform(uint32 buf[4], uint32 const in[16]);
+void BrokenMD5Init(struct MD5Context *);
+void BrokenMD5Update(struct MD5Context *, unsigned const char *, unsigned);
+void BrokenMD5Final(unsigned char digest[16], struct MD5Context *);
+void BrokenMD5Transform(uint32 buf[4], uint32 const in[16]);
+
+char *Goodcrypt_md5(const char *pw, const char *salt);
+char *Brokencrypt_md5(const char *pw, const char *salt);
+
+/*
+ * This is needed to make RSAREF happy on some MS-DOS compilers.
+ */
+
+typedef struct MD5Context MD5_CTX;
+
+#endif /* MD5_H */
diff --git a/modules/pam_unix/md5_broken.c b/modules/pam_unix/md5_broken.c
new file mode 100644
index 0000000..193daeb
--- /dev/null
+++ b/modules/pam_unix/md5_broken.c
@@ -0,0 +1,4 @@
+#define MD5Name(x) Broken##x
+
+#include "md5.c"
+#include "md5_crypt.c"
diff --git a/modules/pam_unix/md5_crypt.c b/modules/pam_unix/md5_crypt.c
new file mode 100644
index 0000000..94f7b43
--- /dev/null
+++ b/modules/pam_unix/md5_crypt.c
@@ -0,0 +1,157 @@
+/*
+ * $Id$
+ *
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * Origin: Id: crypt.c,v 1.3 1995/05/30 05:42:22 rgrimes Exp
+ *
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include "md5.h"
+#include "pam_inline.h"
+
+static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static void to64(char *s, unsigned long v, int n)
+{
+ while (--n >= 0) {
+ *s++ = itoa64[v & 0x3f];
+ v >>= 6;
+ }
+}
+
+/*
+ * UNIX password
+ *
+ * Use MD5 for what it is best at...
+ */
+
+char *MD5Name(crypt_md5)(const char *pw, const char *salt)
+{
+ const char *magic = "$1$";
+ /* This string is magic for this algorithm. Having
+ * it this way, we can get get better later on */
+ char *passwd, *p;
+ const char *sp, *ep;
+ unsigned char final[16];
+ int sl, pl, i, j;
+ MD5_CTX ctx, ctx1;
+ unsigned long l;
+
+ /* Refine the Salt first */
+ sp = salt;
+
+ /* TODO: now that we're using malloc'ed memory, get rid of the
+ strange constant buffer size. */
+ passwd = malloc(120);
+ if (passwd == NULL)
+ return NULL;
+
+ /* If it starts with the magic string, then skip that */
+ if ((ep = pam_str_skip_prefix_len(sp, magic, strlen(magic))) != NULL)
+ sp = ep;
+
+ /* It stops at the first '$', max 8 chars */
+ for (ep = sp; *ep && *ep != '$' && ep < (sp + 8); ep++)
+ continue;
+
+ /* get the length of the true salt */
+ sl = ep - sp;
+
+ MD5Name(MD5Init)(&ctx);
+
+ /* The password first, since that is what is most unknown */
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)pw,strlen(pw));
+
+ /* Then our magic string */
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)magic,strlen(magic));
+
+ /* Then the raw salt */
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)sp,sl);
+
+ /* Then just as many characters of the MD5(pw,salt,pw) */
+ MD5Name(MD5Init)(&ctx1);
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)sp,sl);
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Final)(final,&ctx1);
+ for (pl = strlen(pw); pl > 0; pl -= 16)
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)final,pl>16 ? 16 : pl);
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final, 0, sizeof final);
+
+ /* Then something really weird... */
+ for (j = 0, i = strlen(pw); i; i >>= 1)
+ if (i & 1)
+ MD5Name(MD5Update)(&ctx, (unsigned const char *)final+j, 1);
+ else
+ MD5Name(MD5Update)(&ctx, (unsigned const char *)pw+j, 1);
+
+ /* Now make the output string */
+ strcpy(passwd, magic);
+ strncat(passwd, sp, sl);
+ strcat(passwd, "$");
+
+ MD5Name(MD5Final)(final,&ctx);
+
+ /*
+ * and now, just to make sure things don't run too fast
+ * On a 60 Mhz Pentium this takes 34 msec, so you would
+ * need 30 seconds to build a 1000 entry dictionary...
+ */
+ for (i = 0; i < 1000; i++) {
+ MD5Name(MD5Init)(&ctx1);
+ if (i & 1)
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+ else
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)final,16);
+
+ if (i % 3)
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)sp,sl);
+
+ if (i % 7)
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+
+ if (i & 1)
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)final,16);
+ else
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Final)(final,&ctx1);
+ }
+
+ p = passwd + strlen(passwd);
+
+ l = (final[0] << 16) | (final[6] << 8) | final[12];
+ to64(p, l, 4);
+ p += 4;
+ l = (final[1] << 16) | (final[7] << 8) | final[13];
+ to64(p, l, 4);
+ p += 4;
+ l = (final[2] << 16) | (final[8] << 8) | final[14];
+ to64(p, l, 4);
+ p += 4;
+ l = (final[3] << 16) | (final[9] << 8) | final[15];
+ to64(p, l, 4);
+ p += 4;
+ l = (final[4] << 16) | (final[10] << 8) | final[5];
+ to64(p, l, 4);
+ p += 4;
+ l = final[11];
+ to64(p, l, 2);
+ p += 2;
+ *p = '\0';
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final, 0, sizeof final);
+
+ return passwd;
+}
diff --git a/modules/pam_unix/md5_good.c b/modules/pam_unix/md5_good.c
new file mode 100644
index 0000000..131e451
--- /dev/null
+++ b/modules/pam_unix/md5_good.c
@@ -0,0 +1,5 @@
+#define HIGHFIRST
+#define MD5Name(x) Good##x
+
+#include "md5.c"
+#include "md5_crypt.c"
diff --git a/modules/pam_unix/pam_unix.8 b/modules/pam_unix/pam_unix.8
new file mode 100644
index 0000000..d9cdea5
--- /dev/null
+++ b/modules/pam_unix/pam_unix.8
@@ -0,0 +1,285 @@
+'\" t
+.\" Title: pam_unix
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_UNIX" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_unix \- Module for traditional password authentication
+.SH "SYNOPSIS"
+.HP \w'\fBpam_unix\&.so\fR\ 'u
+\fBpam_unix\&.so\fR [\&.\&.\&.]
+.SH "DESCRIPTION"
+.PP
+This is the standard Unix authentication module\&. It uses standard calls from the system\*(Aqs libraries to retrieve and set account information as well as authentication\&. Usually this is obtained from the /etc/passwd and the /etc/shadow file as well if shadow is enabled\&.
+.PP
+The account component performs the task of establishing the status of the user\*(Aqs account and password based on the following
+\fIshadow\fR
+elements: expire, last_change, max_change, min_change, warn_change\&. In the case of the latter, it may offer advice to the user on changing their password or, through the
+\fBPAM_AUTHTOKEN_REQD\fR
+return, delay giving service to the user until they have established a new password\&. The entries listed above are documented in the
+\fBshadow\fR(5)
+manual page\&. Should the user\*(Aqs record not contain one or more of these entries, the corresponding
+\fIshadow\fR
+check is not performed\&.
+.PP
+The authentication component performs the task of checking the users credentials (password)\&. The default action of this module is to not permit the user access to a service if their official password is blank\&.
+.PP
+A helper binary,
+\fBunix_chkpwd\fR(8), is provided to check the user\*(Aqs password when it is stored in a read protected database\&. This binary is very simple and will only check the password of the user invoking it\&. It is called transparently on behalf of the user by the authenticating component of this module\&. In this way it is possible for applications like
+\fBxlock\fR(1)
+to work without being setuid\-root\&. The module, by default, will temporarily turn off SIGCHLD handling for the duration of execution of the helper binary\&. This is generally the right thing to do, as many applications are not prepared to handle this signal from a child they didn\*(Aqt know was
+\fBfork()\fRd\&. The
+\fBnoreap\fR
+module argument can be used to suppress this temporary shielding and may be needed for use with certain applications\&.
+.PP
+The maximum length of a password supported by the pam_unix module via the helper binary is
+\fIPAM_MAX_RESP_SIZE\fR
+\- currently 512 bytes\&. The rest of the password provided by the conversation function to the module will be ignored\&.
+.PP
+The password component of this module performs the task of updating the user\*(Aqs password\&. The default encryption hash is taken from the
+\fBENCRYPT_METHOD\fR
+variable from
+\fI/etc/login\&.defs\fR
+.PP
+The session component of this module logs when a user logins or leave the system\&.
+.PP
+Remaining arguments, supported by others functions of this module, are silently ignored\&. Other arguments are logged as errors through
+\fBsyslog\fR(3)\&.
+.SH "OPTIONS"
+.PP
+\fBdebug\fR
+.RS 4
+Turns on debugging via
+\fBsyslog\fR(3)\&.
+.RE
+.PP
+\fBaudit\fR
+.RS 4
+A little more extreme than debug\&.
+.RE
+.PP
+\fBquiet\fR
+.RS 4
+Turns off informational messages namely messages about session open and close via
+\fBsyslog\fR(3)\&.
+.RE
+.PP
+\fBnullok\fR
+.RS 4
+The default action of this module is to not permit the user access to a service if their official password is blank\&. The
+\fBnullok\fR
+argument overrides this default\&.
+.RE
+.PP
+\fBnullresetok\fR
+.RS 4
+Allow users to authenticate with blank password if password reset is enforced even if
+\fBnullok\fR
+is not set\&. If password reset is not required and
+\fBnullok\fR
+is not set the authentication with blank password will be denied\&.
+.RE
+.PP
+\fBtry_first_pass\fR
+.RS 4
+Before prompting the user for their password, the module first tries the previous stacked module\*(Aqs password in case that satisfies this module as well\&.
+.RE
+.PP
+\fBuse_first_pass\fR
+.RS 4
+The argument
+\fBuse_first_pass\fR
+forces the module to use a previous stacked modules password and will never prompt the user \- if no password is available or the password is not appropriate, the user will be denied access\&.
+.RE
+.PP
+\fBnodelay\fR
+.RS 4
+This argument can be used to discourage the authentication component from requesting a delay should the authentication as a whole fail\&. The default action is for the module to request a delay\-on\-failure of the order of two second\&.
+.RE
+.PP
+\fBuse_authtok\fR
+.RS 4
+When password changing enforce the module to set the new password to the one provided by a previously stacked
+\fBpassword\fR
+module (this is used in the example of the stacking of the
+\fBpam_passwdqc\fR
+module documented below)\&.
+.RE
+.PP
+\fBauthtok_type=\fR\fB\fItype\fR\fR
+.RS 4
+This argument can be used to modify the password prompt when changing passwords to include the type of the password\&. Empty by default\&.
+.RE
+.PP
+\fBnis\fR
+.RS 4
+NIS RPC is used for setting new passwords\&.
+.RE
+.PP
+\fBremember=\fR\fB\fIn\fR\fR
+.RS 4
+The last
+\fIn\fR
+passwords for each user are saved in
+/etc/security/opasswd
+in order to force password change history and keep the user from alternating between the same password too frequently\&. The MD5 password hash algorithm is used for storing the old passwords\&. Instead of this option the
+\fBpam_pwhistory\fR
+module should be used\&.
+.RE
+.PP
+\fBshadow\fR
+.RS 4
+Try to maintain a shadow based system\&.
+.RE
+.PP
+\fBmd5\fR
+.RS 4
+When a user changes their password next, encrypt it with the MD5 algorithm\&.
+.RE
+.PP
+\fBbigcrypt\fR
+.RS 4
+When a user changes their password next, encrypt it with the DEC C2 algorithm\&.
+.RE
+.PP
+\fBsha256\fR
+.RS 4
+When a user changes their password next, encrypt it with the SHA256 algorithm\&. The SHA256 algorithm must be supported by the
+\fBcrypt\fR(3)
+function\&.
+.RE
+.PP
+\fBsha512\fR
+.RS 4
+When a user changes their password next, encrypt it with the SHA512 algorithm\&. The SHA512 algorithm must be supported by the
+\fBcrypt\fR(3)
+function\&.
+.RE
+.PP
+\fBblowfish\fR
+.RS 4
+When a user changes their password next, encrypt it with the blowfish algorithm\&. The blowfish algorithm must be supported by the
+\fBcrypt\fR(3)
+function\&.
+.RE
+.PP
+\fBgost_yescrypt\fR
+.RS 4
+When a user changes their password next, encrypt it with the gost\-yescrypt algorithm\&. The gost\-yescrypt algorithm must be supported by the
+\fBcrypt\fR(3)
+function\&.
+.RE
+.PP
+\fByescrypt\fR
+.RS 4
+When a user changes their password next, encrypt it with the yescrypt algorithm\&. The yescrypt algorithm must be supported by the
+\fBcrypt\fR(3)
+function\&.
+.RE
+.PP
+\fBrounds=\fR\fB\fIn\fR\fR
+.RS 4
+Set the optional number of rounds of the SHA256, SHA512, blowfish, gost\-yescrypt, and yescrypt password hashing algorithms to
+\fIn\fR\&.
+.RE
+.PP
+\fBbroken_shadow\fR
+.RS 4
+Ignore errors reading shadow information for users in the account management module\&.
+.RE
+.PP
+\fBminlen=\fR\fB\fIn\fR\fR
+.RS 4
+Set a minimum password length of
+\fIn\fR
+characters\&. The max\&. for DES crypt based passwords are 8 characters\&.
+.RE
+.PP
+\fBno_pass_expiry\fR
+.RS 4
+When set ignore password expiration as defined by the
+\fIshadow\fR
+entry of the user\&. The option has an effect only in case
+\fIpam_unix\fR
+was not used for the authentication or it returned authentication failure meaning that other authentication source or method succeeded\&. The example can be public key authentication in
+\fIsshd\fR\&. The module will return
+\fBPAM_SUCCESS\fR
+instead of eventual
+\fBPAM_NEW_AUTHTOK_REQD\fR
+or
+\fBPAM_AUTHTOK_EXPIRED\fR\&.
+.RE
+.PP
+Invalid arguments are logged with
+\fBsyslog\fR(3)\&.
+.SH "MODULE TYPES PROVIDED"
+.PP
+All module types (\fBaccount\fR,
+\fBauth\fR,
+\fBpassword\fR
+and
+\fBsession\fR) are provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_IGNORE
+.RS 4
+Ignore this module\&.
+.RE
+.SH "EXAMPLES"
+.PP
+An example usage for
+/etc/pam\&.d/login
+would be:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# Authenticate the user
+auth required pam_unix\&.so
+# Ensure users account and password are still active
+account required pam_unix\&.so
+# Change the user\*(Aqs password, but at first check the strength
+# with pam_passwdqc(8)
+password required pam_passwdqc\&.so config=/etc/passwdqc\&.conf
+password required pam_unix\&.so use_authtok nullok yescrypt
+session required pam_unix\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.PP
+\fBlogin.defs\fR(5),
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_unix was written by various people\&.
diff --git a/modules/pam_unix/pam_unix.8.xml b/modules/pam_unix/pam_unix.8.xml
new file mode 100644
index 0000000..9f9c818
--- /dev/null
+++ b/modules/pam_unix/pam_unix.8.xml
@@ -0,0 +1,501 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_unix">
+
+ <refmeta>
+ <refentrytitle>pam_unix</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_unix-name">
+ <refname>pam_unix</refname>
+ <refpurpose>Module for traditional password authentication</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_unix-cmdsynopsis">
+ <command>pam_unix.so</command>
+ <arg choice="opt">
+ ...
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_unix-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ This is the standard Unix authentication module. It uses standard
+ calls from the system's libraries to retrieve and set account
+ information as well as authentication. Usually this is obtained
+ from the /etc/passwd and the /etc/shadow file as well if shadow is
+ enabled.
+ </para>
+
+ <para>
+ The account component performs the task of establishing the status
+ of the user's account and password based on the following
+ <emphasis>shadow</emphasis> elements: expire, last_change, max_change,
+ min_change, warn_change. In the case of the latter, it may offer advice
+ to the user on changing their password or, through the
+ <emphasis remap='B'>PAM_AUTHTOKEN_REQD</emphasis> return, delay
+ giving service to the user until they have established a new password.
+ The entries listed above are documented in the <citerefentry>
+ <refentrytitle>shadow</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry> manual page. Should the user's record not contain
+ one or more of these entries, the corresponding
+ <emphasis>shadow</emphasis> check is not performed.
+ </para>
+
+ <para>
+ The authentication component performs the task of checking the
+ users credentials (password). The default action of this module
+ is to not permit the user access to a service if their official
+ password is blank.
+ </para>
+
+ <para>
+ A helper binary, <citerefentry>
+ <refentrytitle>unix_chkpwd</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>, is provided
+ to check the user's password when it is stored in a read
+ protected database. This binary is very simple and will only
+ check the password of the user invoking it. It is called
+ transparently on behalf of the user by the authenticating
+ component of this module. In this way it is possible
+ for applications like <citerefentry>
+ <refentrytitle>xlock</refentrytitle><manvolnum>1</manvolnum>
+ </citerefentry> to work without
+ being setuid-root. The module, by default, will temporarily turn
+ off SIGCHLD handling for the duration of execution of the helper
+ binary. This is generally the right thing to do, as many applications
+ are not prepared to handle this signal from a child they didn't know
+ was <function>fork()</function>d. The <option>noreap</option> module
+ argument can be used to suppress this temporary shielding and may be
+ needed for use with certain applications.
+ </para>
+
+ <para>
+ The maximum length of a password supported by the pam_unix module
+ via the helper binary is <emphasis>PAM_MAX_RESP_SIZE</emphasis>
+ - currently 512 bytes. The rest of the password provided by the
+ conversation function to the module will be ignored.
+ </para>
+
+ <para>
+ The password component of this module performs the task of updating
+ the user's password. The default encryption hash is taken from the
+ <emphasis remap='B'>ENCRYPT_METHOD</emphasis> variable from
+ <emphasis>/etc/login.defs</emphasis>
+ </para>
+
+ <para>
+ The session component of this module logs when a user logins
+ or leave the system.
+ </para>
+
+ <para>
+ Remaining arguments, supported by others functions of this
+ module, are silently ignored. Other arguments are logged as
+ errors through <citerefentry>
+ <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_unix-options">
+
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Turns on debugging via
+ <citerefentry>
+ <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>audit</option>
+ </term>
+ <listitem>
+ <para>
+ A little more extreme than debug.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>quiet</option>
+ </term>
+ <listitem>
+ <para>
+ Turns off informational messages namely messages about
+ session open and close via
+ <citerefentry>
+ <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>nullok</option>
+ </term>
+ <listitem>
+ <para>
+ The default action of this module is to not permit the
+ user access to a service if their official password is blank.
+ The <option>nullok</option> argument overrides this default.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>nullresetok</option>
+ </term>
+ <listitem>
+ <para>
+ Allow users to authenticate with blank password if password reset
+ is enforced even if <option>nullok</option> is not set. If password
+ reset is not required and <option>nullok</option> is not set the
+ authentication with blank password will be denied.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>try_first_pass</option>
+ </term>
+ <listitem>
+ <para>
+ Before prompting the user for their password, the module first
+ tries the previous stacked module's password in case that
+ satisfies this module as well.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>use_first_pass</option>
+ </term>
+ <listitem>
+ <para>
+ The argument <option>use_first_pass</option> forces the module
+ to use a previous stacked modules password and will never prompt
+ the user - if no password is available or the password is not
+ appropriate, the user will be denied access.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>nodelay</option>
+ </term>
+ <listitem>
+ <para>
+ This argument can be used to discourage the authentication
+ component from requesting a delay should the authentication
+ as a whole fail. The default action is for the module to
+ request a delay-on-failure of the order of two second.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>use_authtok</option>
+ </term>
+ <listitem>
+ <para>
+ When password changing enforce the module to set the new
+ password to the one provided by a previously stacked
+ <option>password</option> module (this is used in the
+ example of the stacking of the <command>pam_passwdqc</command>
+ module documented below).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>authtok_type=<replaceable>type</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ This argument can be used to modify the password prompt
+ when changing passwords to include the type of the password.
+ Empty by default.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>nis</option>
+ </term>
+ <listitem>
+ <para>
+ NIS RPC is used for setting new passwords.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>remember=<replaceable>n</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ The last <replaceable>n</replaceable> passwords for each
+ user are saved in <filename>/etc/security/opasswd</filename>
+ in order to force password change history and keep the user
+ from alternating between the same password too frequently.
+ The MD5 password hash algorithm is used for storing the
+ old passwords.
+ Instead of this option the <command>pam_pwhistory</command>
+ module should be used.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>shadow</option>
+ </term>
+ <listitem>
+ <para>
+ Try to maintain a shadow based system.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>md5</option>
+ </term>
+ <listitem>
+ <para>
+ When a user changes their password next, encrypt
+ it with the MD5 algorithm.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>bigcrypt</option>
+ </term>
+ <listitem>
+ <para>
+ When a user changes their password next,
+ encrypt it with the DEC C2 algorithm.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>sha256</option>
+ </term>
+ <listitem>
+ <para>
+ When a user changes their password next,
+ encrypt it with the SHA256 algorithm. The
+ SHA256 algorithm must be supported by the <citerefentry>
+ <refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry> function.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>sha512</option>
+ </term>
+ <listitem>
+ <para>
+ When a user changes their password next,
+ encrypt it with the SHA512 algorithm. The
+ SHA512 algorithm must be supported by the <citerefentry>
+ <refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry> function.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>blowfish</option>
+ </term>
+ <listitem>
+ <para>
+ When a user changes their password next,
+ encrypt it with the blowfish algorithm. The
+ blowfish algorithm must be supported by the <citerefentry>
+ <refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry> function.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>gost_yescrypt</option>
+ </term>
+ <listitem>
+ <para>
+ When a user changes their password next,
+ encrypt it with the gost-yescrypt algorithm. The
+ gost-yescrypt algorithm must be supported by the <citerefentry>
+ <refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry> function.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>yescrypt</option>
+ </term>
+ <listitem>
+ <para>
+ When a user changes their password next,
+ encrypt it with the yescrypt algorithm. The
+ yescrypt algorithm must be supported by the <citerefentry>
+ <refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry> function.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>rounds=<replaceable>n</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Set the optional number of rounds of the SHA256, SHA512,
+ blowfish, gost-yescrypt, and yescrypt password hashing
+ algorithms to
+ <replaceable>n</replaceable>.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>broken_shadow</option>
+ </term>
+ <listitem>
+ <para>
+ Ignore errors reading shadow information for
+ users in the account management module.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>minlen=<replaceable>n</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Set a minimum password length of <replaceable>n</replaceable>
+ characters. The max. for DES crypt based passwords are 8
+ characters.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>no_pass_expiry</option>
+ </term>
+ <listitem>
+ <para>
+ When set ignore password expiration as defined by the
+ <emphasis>shadow</emphasis> entry of the user. The option has an
+ effect only in case <emphasis>pam_unix</emphasis> was not used
+ for the authentication or it returned authentication failure
+ meaning that other authentication source or method succeeded.
+ The example can be public key authentication in
+ <emphasis>sshd</emphasis>. The module will return
+ <emphasis remap='B'>PAM_SUCCESS</emphasis> instead of eventual
+ <emphasis remap='B'>PAM_NEW_AUTHTOK_REQD</emphasis> or
+ <emphasis remap='B'>PAM_AUTHTOK_EXPIRED</emphasis>.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ <para>
+ Invalid arguments are logged with <citerefentry>
+ <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_unix-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ All module types (<option>account</option>, <option>auth</option>,
+ <option>password</option> and <option>session</option>) are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_unix-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ Ignore this module.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_unix-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ An example usage for <filename>/etc/pam.d/login</filename>
+ would be:
+ <programlisting>
+# Authenticate the user
+auth required pam_unix.so
+# Ensure users account and password are still active
+account required pam_unix.so
+# Change the user's password, but at first check the strength
+# with pam_passwdqc(8)
+password required pam_passwdqc.so config=/etc/passwdqc.conf
+password required pam_unix.so use_authtok nullok yescrypt
+session required pam_unix.so
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_unix-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>login.defs</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_unix-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_unix was written by various people.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c
new file mode 100644
index 0000000..8f5ed3e
--- /dev/null
+++ b/modules/pam_unix/pam_unix_acct.c
@@ -0,0 +1,291 @@
+/*
+ * pam_unix account management
+ *
+ * Copyright Elliot Lee, 1996. All rights reserved.
+ * Copyright Jan Rękorajski, 1999. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <syslog.h>
+#include <pwd.h>
+#include <shadow.h>
+#include <time.h> /* for time() */
+#include <errno.h>
+#include <sys/wait.h>
+
+#include <security/_pam_macros.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_ext.h>
+#include <security/pam_modutil.h>
+
+#include "pam_cc_compat.h"
+#include "support.h"
+#include "passverify.h"
+
+int _unix_run_verify_binary(pam_handle_t *pamh, unsigned long long ctrl,
+ const char *user, int *daysleft)
+{
+ int retval=0, child, fds[2];
+ struct sigaction newsa, oldsa;
+ D(("running verify_binary"));
+
+ /* create a pipe for the messages */
+ if (pipe(fds) != 0) {
+ D(("could not make pipe"));
+ pam_syslog(pamh, LOG_ERR, "Could not make pipe: %m");
+ return PAM_AUTH_ERR;
+ }
+ D(("called."));
+
+ if (off(UNIX_NOREAP, ctrl)) {
+ /*
+ * This code arranges that the demise of the child does not cause
+ * the application to receive a signal it is not expecting - which
+ * may kill the application or worse.
+ *
+ * The "noreap" module argument is provided so that the admin can
+ * override this behavior.
+ */
+ memset(&newsa, '\0', sizeof(newsa));
+ newsa.sa_handler = SIG_DFL;
+ sigaction(SIGCHLD, &newsa, &oldsa);
+ }
+
+ /* fork */
+ child = fork();
+ if (child == 0) {
+ static char *envp[] = { NULL };
+ const char *args[] = { NULL, NULL, NULL, NULL };
+
+ /* XXX - should really tidy up PAM here too */
+
+ /* reopen stdout as pipe */
+ if (dup2(fds[1], STDOUT_FILENO) != STDOUT_FILENO) {
+ pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", "stdout");
+ _exit(PAM_AUTHINFO_UNAVAIL);
+ }
+
+ if (pam_modutil_sanitize_helper_fds(pamh, PAM_MODUTIL_PIPE_FD,
+ PAM_MODUTIL_IGNORE_FD,
+ PAM_MODUTIL_PIPE_FD) < 0) {
+ _exit(PAM_AUTHINFO_UNAVAIL);
+ }
+
+ if (geteuid() == 0) {
+ /* must set the real uid to 0 so the helper will not error
+ out if pam is called from setuid binary (su, sudo...) */
+ if (setuid(0) == -1) {
+ pam_syslog(pamh, LOG_ERR, "setuid failed: %m");
+ printf("-1\n");
+ fflush(stdout);
+ _exit(PAM_AUTHINFO_UNAVAIL);
+ }
+ }
+
+ /* exec binary helper */
+ args[0] = CHKPWD_HELPER;
+ args[1] = user;
+ args[2] = "chkexpiry";
+
+ DIAG_PUSH_IGNORE_CAST_QUAL;
+ execve(CHKPWD_HELPER, (char *const *) args, envp);
+ DIAG_POP_IGNORE_CAST_QUAL;
+
+ pam_syslog(pamh, LOG_ERR, "helper binary execve failed: %m");
+ /* should not get here: exit with error */
+ D(("helper binary is not available"));
+ printf("-1\n");
+ fflush(stdout);
+ _exit(PAM_AUTHINFO_UNAVAIL);
+ } else {
+ close(fds[1]);
+ if (child > 0) {
+ char buf[32];
+ int rc=0;
+ /* wait for helper to complete: */
+ while ((rc=waitpid(child, &retval, 0)) < 0 && errno == EINTR);
+ if (rc<0) {
+ pam_syslog(pamh, LOG_ERR, "unix_chkpwd waitpid returned %d: %m", rc);
+ retval = PAM_AUTH_ERR;
+ } else if (!WIFEXITED(retval)) {
+ pam_syslog(pamh, LOG_ERR, "unix_chkpwd abnormal exit: %d", retval);
+ retval = PAM_AUTH_ERR;
+ } else {
+ retval = WEXITSTATUS(retval);
+ rc = pam_modutil_read(fds[0], buf, sizeof(buf) - 1);
+ if(rc > 0) {
+ buf[rc] = '\0';
+ if (sscanf(buf,"%d", daysleft) != 1 )
+ retval = PAM_AUTH_ERR;
+ }
+ else {
+ pam_syslog(pamh, LOG_ERR, "read unix_chkpwd output error %d: %m", rc);
+ retval = PAM_AUTH_ERR;
+ }
+ }
+ } else {
+ pam_syslog(pamh, LOG_ERR, "Fork failed: %m");
+ D(("fork failed"));
+ retval = PAM_AUTH_ERR;
+ }
+ close(fds[0]);
+ }
+
+ if (off(UNIX_NOREAP, ctrl)) {
+ sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */
+ }
+
+ D(("Returning %d",retval));
+ return retval;
+}
+
+/*
+ * PAM framework looks for this entry-point to pass control to the
+ * account management module.
+ */
+
+int
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ unsigned long long ctrl;
+ const void *void_uname;
+ const char *uname;
+ int retval, daysleft = -1;
+ char buf[256];
+
+ D(("called."));
+
+ ctrl = _set_ctrl(pamh, flags, NULL, NULL, NULL, argc, argv);
+
+ retval = pam_get_item(pamh, PAM_USER, &void_uname);
+ uname = void_uname;
+ D(("user = `%s'", uname));
+ if (retval != PAM_SUCCESS || uname == NULL) {
+ pam_syslog(pamh, LOG_ERR,
+ "could not identify user (from uid=%lu)",
+ (unsigned long int)getuid());
+ return PAM_USER_UNKNOWN;
+ }
+
+ retval = _unix_verify_user(pamh, ctrl, uname, &daysleft);
+
+ if (on(UNIX_NO_PASS_EXPIRY, ctrl)) {
+ const void *pretval = NULL;
+ int authrv = PAM_AUTHINFO_UNAVAIL; /* authentication not called */
+
+ if (pam_get_data(pamh, "unix_setcred_return", &pretval) == PAM_SUCCESS
+ && pretval)
+ authrv = *(const int *)pretval;
+
+ if (authrv != PAM_SUCCESS
+ && (retval == PAM_NEW_AUTHTOK_REQD || retval == PAM_AUTHTOK_EXPIRED))
+ retval = PAM_SUCCESS;
+ }
+
+ switch (retval) {
+ case PAM_ACCT_EXPIRED:
+ pam_syslog(pamh, LOG_NOTICE,
+ "account %s has expired (account expired)",
+ uname);
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG,
+ _("Your account has expired; please contact your system administrator."));
+ break;
+ case PAM_NEW_AUTHTOK_REQD:
+ if (daysleft == 0) {
+ pam_syslog(pamh, LOG_NOTICE,
+ "expired password for user %s (root enforced)",
+ uname);
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG,
+ _("You are required to change your password immediately (administrator enforced)."));
+ } else {
+ pam_syslog(pamh, LOG_DEBUG,
+ "expired password for user %s (password aged)",
+ uname);
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG,
+ _("You are required to change your password immediately (password expired)."));
+ }
+ break;
+ case PAM_AUTHTOK_EXPIRED:
+ pam_syslog(pamh, LOG_NOTICE,
+ "account %s has expired (failed to change password)",
+ uname);
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG,
+ _("Your account has expired; please contact your system administrator."));
+ break;
+ case PAM_AUTHTOK_ERR:
+ /*
+ * We ignore "password changed too early" error
+ * as it is relevant only for password change.
+ */
+ retval = PAM_SUCCESS;
+ /* fallthrough */
+ case PAM_SUCCESS:
+ if (daysleft >= 0) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "password for user %s will expire in %d days",
+ uname, daysleft);
+#if defined HAVE_DNGETTEXT && defined ENABLE_NLS
+ snprintf (buf, sizeof (buf),
+ dngettext(PACKAGE,
+ "Warning: your password will expire in %d day.",
+ "Warning: your password will expire in %d days.",
+ daysleft),
+ daysleft);
+#else
+ if (daysleft == 1)
+ snprintf(buf, sizeof (buf),
+ _("Warning: your password will expire in %d day."),
+ daysleft);
+ else
+ snprintf(buf, sizeof (buf),
+ /* TRANSLATORS: only used if dngettext is not supported */
+ _("Warning: your password will expire in %d days."),
+ daysleft);
+#endif
+ _make_remark(pamh, ctrl, PAM_TEXT_INFO, buf);
+ }
+ }
+
+ D(("all done"));
+
+ return retval;
+}
diff --git a/modules/pam_unix/pam_unix_auth.c b/modules/pam_unix/pam_unix_auth.c
new file mode 100644
index 0000000..4eccff8
--- /dev/null
+++ b/modules/pam_unix/pam_unix_auth.c
@@ -0,0 +1,215 @@
+/*
+ * pam_unix authentication management
+ *
+ * Copyright Alexander O. Yuriev, 1996. All rights reserved.
+ * NIS+ support by Thorsten Kukuk <kukuk@weber.uni-paderborn.de>
+ * Copyright Jan Rękorajski, 1999. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <syslog.h>
+
+#include <security/_pam_macros.h>
+#include <security/pam_modules.h>
+#include <security/pam_ext.h>
+
+#include "support.h"
+
+/*
+ * PAM framework looks for these entry-points to pass control to the
+ * authentication module.
+ */
+
+/* Fun starts here :)
+
+ * pam_sm_authenticate() performs UNIX/shadow authentication
+ *
+ * First, if shadow support is available, attempt to perform
+ * authentication using shadow passwords. If shadow is not
+ * available, or user does not have a shadow password, fallback
+ * onto a normal UNIX authentication
+ */
+
+#define AUTH_RETURN \
+do { \
+ D(("recording return code for next time [%d]", \
+ retval)); \
+ *ret_data = retval; \
+ pam_set_data(pamh, "unix_setcred_return", \
+ (void *) ret_data, setcred_free); \
+ D(("done. [%s]", pam_strerror(pamh, retval))); \
+ return retval; \
+} while (0)
+
+
+static void
+setcred_free (pam_handle_t *pamh UNUSED, void *ptr, int err UNUSED)
+{
+ if (ptr)
+ free (ptr);
+}
+
+int
+pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ unsigned long long ctrl;
+ int retval, *ret_data = NULL;
+ const char *name;
+ const char *p;
+
+ D(("called."));
+
+ ctrl = _set_ctrl(pamh, flags, NULL, NULL, NULL, argc, argv);
+
+ /* Get a few bytes so we can pass our return value to
+ pam_sm_setcred() and pam_sm_acct_mgmt(). */
+ ret_data = malloc(sizeof(int));
+ if (!ret_data) {
+ D(("cannot malloc ret_data"));
+ pam_syslog(pamh, LOG_CRIT,
+ "pam_unix_auth: cannot allocate ret_data");
+ return PAM_BUF_ERR;
+ }
+
+ /* get the user'name' */
+
+ retval = pam_get_user(pamh, &name, NULL);
+ if (retval == PAM_SUCCESS) {
+ /*
+ * Various libraries at various times have had bugs related to
+ * '+' or '-' as the first character of a user name. Don't
+ * allow this characters here.
+ */
+ if (name[0] == '-' || name[0] == '+') {
+ pam_syslog(pamh, LOG_NOTICE, "bad username [%s]", name);
+ retval = PAM_USER_UNKNOWN;
+ AUTH_RETURN;
+ }
+ if (on(UNIX_DEBUG, ctrl))
+ pam_syslog(pamh, LOG_DEBUG, "username [%s] obtained", name);
+ } else {
+ if (retval == PAM_CONV_AGAIN) {
+ D(("pam_get_user/conv() function is not ready yet"));
+ /* it is safe to resume this function so we translate this
+ * retval to the value that indicates we're happy to resume.
+ */
+ retval = PAM_INCOMPLETE;
+ } else if (on(UNIX_DEBUG, ctrl)) {
+ pam_syslog(pamh, LOG_DEBUG, "could not obtain username");
+ }
+ AUTH_RETURN;
+ }
+
+ /* if this user does not have a password... */
+
+ if (_unix_blankpasswd(pamh, ctrl, name)) {
+ pam_syslog(pamh, LOG_DEBUG, "user [%s] has blank password; authenticated without it", name);
+ name = NULL;
+ retval = PAM_SUCCESS;
+ AUTH_RETURN;
+ }
+ /* get this user's authentication token */
+
+ retval = pam_get_authtok(pamh, PAM_AUTHTOK, &p , NULL);
+ if (retval != PAM_SUCCESS) {
+ if (retval != PAM_CONV_AGAIN) {
+ pam_syslog(pamh, LOG_CRIT,
+ "auth could not identify password for [%s]", name);
+ } else {
+ D(("conversation function is not ready yet"));
+ /*
+ * it is safe to resume this function so we translate this
+ * retval to the value that indicates we're happy to resume.
+ */
+ retval = PAM_INCOMPLETE;
+ }
+ name = NULL;
+ AUTH_RETURN;
+ }
+ D(("user=%s, password=[%s]", name, p));
+
+ /* verify the password of this user */
+ retval = _unix_verify_password(pamh, name, p, ctrl);
+ name = p = NULL;
+
+ AUTH_RETURN;
+}
+
+
+/*
+ * The only thing _pam_set_credentials_unix() does is initialization of
+ * UNIX group IDs.
+ *
+ * Well, everybody but me on linux-pam is convinced that it should not
+ * initialize group IDs, so I am not doing it but don't say that I haven't
+ * warned you. -- AOY
+ */
+
+int
+pam_sm_setcred (pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ int retval;
+ const void *pretval = NULL;
+ unsigned long long ctrl;
+
+ D(("called."));
+
+ ctrl = _set_ctrl(pamh, flags, NULL, NULL, NULL, argc, argv);
+
+ retval = PAM_SUCCESS;
+
+ D(("recovering return code from auth call"));
+ /* We will only find something here if UNIX_LIKE_AUTH is set --
+ don't worry about an explicit check of argv. */
+ if (on(UNIX_LIKE_AUTH, ctrl)
+ && pam_get_data(pamh, "unix_setcred_return", &pretval) == PAM_SUCCESS
+ && pretval) {
+ retval = *(const int *)pretval;
+ pam_set_data(pamh, "unix_setcred_return", NULL, NULL);
+ D(("recovered data indicates that old retval was %d", retval));
+ }
+
+ return retval;
+}
diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c
new file mode 100644
index 0000000..a20e919
--- /dev/null
+++ b/modules/pam_unix/pam_unix_passwd.c
@@ -0,0 +1,875 @@
+/*
+ * pam_unix password management
+ *
+ * Main coding by Elliot Lee <sopwith@redhat.com>, Red Hat Software.
+ * Copyright (C) 1996.
+ * Copyright (c) Jan Rękorajski, 1999.
+ * Copyright (c) Red Hat, Inc., 2007, 2008.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <malloc.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <syslog.h>
+#include <shadow.h>
+#include <time.h> /* for time() */
+#include <fcntl.h>
+#include <ctype.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/resource.h>
+
+#include <security/_pam_macros.h>
+#include <security/pam_modules.h>
+#include <security/pam_ext.h>
+#include <security/pam_modutil.h>
+
+#include "pam_cc_compat.h"
+#include "md5.h"
+#include "support.h"
+#include "passverify.h"
+#include "bigcrypt.h"
+
+#if (HAVE_YP_GET_DEFAULT_DOMAIN || HAVE_GETDOMAINNAME) && HAVE_YP_MASTER
+# define HAVE_NIS
+#endif
+
+#ifdef HAVE_NIS
+# include <rpc/rpc.h>
+
+# if HAVE_RPCSVC_YP_PROT_H
+# include <rpcsvc/yp_prot.h>
+# endif
+
+# if HAVE_RPCSVC_YPCLNT_H
+# include <rpcsvc/ypclnt.h>
+# endif
+
+# include "yppasswd.h"
+
+# if !HAVE_DECL_GETRPCPORT &&!HAVE_RPCB_GETADDR
+extern int getrpcport(const char *host, unsigned long prognum,
+ unsigned long versnum, unsigned int proto);
+# endif /* GNU libc 2.1 */
+#endif
+
+/*
+ How it works:
+ Gets in username (has to be done) from the calling program
+ Does authentication of user (only if we are not running as root)
+ Gets new password/checks for sanity
+ Sets it.
+ */
+
+#define MAX_PASSWD_TRIES 3
+
+#ifdef HAVE_NIS
+#ifdef HAVE_RPCB_GETADDR
+static unsigned short
+__taddr2port (const struct netconfig *nconf, const struct netbuf *nbuf)
+{
+ unsigned short port = 0;
+ struct __rpc_sockinfo si;
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+ if (!__rpc_nconf2sockinfo(nconf, &si))
+ return 0;
+
+ switch (si.si_af)
+ {
+ case AF_INET:
+ sin = nbuf->buf;
+ port = sin->sin_port;
+ break;
+ case AF_INET6:
+ sin6 = nbuf->buf;
+ port = sin6->sin6_port;
+ break;
+ default:
+ break;
+ }
+
+ return htons (port);
+}
+#endif
+
+static char *getNISserver(pam_handle_t *pamh, unsigned long long ctrl)
+{
+ char *master;
+ char *domainname;
+ int port, err;
+#if defined(HAVE_RPCB_GETADDR)
+ struct netconfig *nconf;
+ struct netbuf svcaddr;
+ char addrbuf[INET6_ADDRSTRLEN];
+ void *handle;
+ int found;
+#endif
+
+
+#ifdef HAVE_YP_GET_DEFAULT_DOMAIN
+ if ((err = yp_get_default_domain(&domainname)) != 0) {
+ pam_syslog(pamh, LOG_WARNING, "can't get local yp domain: %s",
+ yperr_string(err));
+ return NULL;
+ }
+#elif defined(HAVE_GETDOMAINNAME)
+ char domainname_res[256];
+
+ if (getdomainname (domainname_res, sizeof (domainname_res)) == 0)
+ {
+ if (strcmp (domainname_res, "(none)") == 0)
+ {
+ /* If domainname is not set, some systems will return "(none)" */
+ domainname_res[0] = '\0';
+ }
+ domainname = domainname_res;
+ }
+ else domainname = NULL;
+#endif
+
+ if ((err = yp_master(domainname, "passwd.byname", &master)) != 0) {
+ pam_syslog(pamh, LOG_WARNING, "can't find the master ypserver: %s",
+ yperr_string(err));
+ return NULL;
+ }
+#ifdef HAVE_RPCB_GETADDR
+ svcaddr.len = 0;
+ svcaddr.maxlen = sizeof (addrbuf);
+ svcaddr.buf = addrbuf;
+ port = 0;
+ found = 0;
+
+ handle = setnetconfig();
+ while ((nconf = getnetconfig(handle)) != NULL) {
+ if (!strcmp(nconf->nc_proto, "udp")) {
+ if (rpcb_getaddr(YPPASSWDPROG, YPPASSWDPROC_UPDATE,
+ nconf, &svcaddr, master)) {
+ port = __taddr2port (nconf, &svcaddr);
+ endnetconfig (handle);
+ found=1;
+ break;
+ }
+
+ if (rpc_createerr.cf_stat != RPC_UNKNOWNHOST) {
+ clnt_pcreateerror (master);
+ pam_syslog (pamh, LOG_ERR,
+ "rpcb_getaddr (%s) failed!", master);
+ return NULL;
+ }
+ }
+ }
+
+ if (!found) {
+ pam_syslog (pamh, LOG_ERR,
+ "Cannot find suitable transport for protocol 'udp'");
+ return NULL;
+ }
+#else
+ port = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE, IPPROTO_UDP);
+#endif
+ if (port == 0) {
+ pam_syslog(pamh, LOG_WARNING,
+ "yppasswdd not running on NIS master host");
+ return NULL;
+ }
+ if (port >= IPPORT_RESERVED) {
+ pam_syslog(pamh, LOG_WARNING,
+ "yppasswd daemon running on illegal port");
+ return NULL;
+ }
+ if (on(UNIX_DEBUG, ctrl)) {
+ pam_syslog(pamh, LOG_DEBUG, "Use NIS server on %s with port %d",
+ master, port);
+ }
+ return master;
+}
+#endif
+
+#ifdef WITH_SELINUX
+
+static int _unix_run_update_binary(pam_handle_t *pamh, unsigned long long ctrl, const char *user,
+ const char *fromwhat, const char *towhat, int remember)
+{
+ int retval, child, fds[2];
+ struct sigaction newsa, oldsa;
+
+ D(("called."));
+ /* create a pipe for the password */
+ if (pipe(fds) != 0) {
+ D(("could not make pipe"));
+ return PAM_AUTH_ERR;
+ }
+
+ if (off(UNIX_NOREAP, ctrl)) {
+ /*
+ * This code arranges that the demise of the child does not cause
+ * the application to receive a signal it is not expecting - which
+ * may kill the application or worse.
+ *
+ * The "noreap" module argument is provided so that the admin can
+ * override this behavior.
+ */
+ memset(&newsa, '\0', sizeof(newsa));
+ newsa.sa_handler = SIG_DFL;
+ sigaction(SIGCHLD, &newsa, &oldsa);
+ }
+
+ /* fork */
+ child = fork();
+ if (child == 0) {
+ static char *envp[] = { NULL };
+ const char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL };
+ char buffer[16];
+
+ /* XXX - should really tidy up PAM here too */
+
+ /* reopen stdin as pipe */
+ if (dup2(fds[0], STDIN_FILENO) != STDIN_FILENO) {
+ pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", "stdin");
+ _exit(PAM_AUTHINFO_UNAVAIL);
+ }
+
+ if (pam_modutil_sanitize_helper_fds(pamh, PAM_MODUTIL_IGNORE_FD,
+ PAM_MODUTIL_PIPE_FD,
+ PAM_MODUTIL_PIPE_FD) < 0) {
+ _exit(PAM_AUTHINFO_UNAVAIL);
+ }
+
+ /* exec binary helper */
+ args[0] = UPDATE_HELPER;
+ args[1] = user;
+ args[2] = "update";
+ if (on(UNIX_SHADOW, ctrl))
+ args[3] = "1";
+ else
+ args[3] = "0";
+
+ snprintf(buffer, sizeof(buffer), "%d", remember);
+ args[4] = buffer;
+
+ DIAG_PUSH_IGNORE_CAST_QUAL;
+ execve(UPDATE_HELPER, (char *const *) args, envp);
+ DIAG_POP_IGNORE_CAST_QUAL;
+
+ /* should not get here: exit with error */
+ D(("helper binary is not available"));
+ _exit(PAM_AUTHINFO_UNAVAIL);
+ } else if (child > 0) {
+ /* wait for child */
+ /* if the stored password is NULL */
+ int rc=0;
+ if (fromwhat) {
+ int len = strlen(fromwhat);
+
+ if (len > PAM_MAX_RESP_SIZE)
+ len = PAM_MAX_RESP_SIZE;
+ pam_modutil_write(fds[1], fromwhat, len);
+ }
+ pam_modutil_write(fds[1], "", 1);
+ if (towhat) {
+ int len = strlen(towhat);
+
+ if (len > PAM_MAX_RESP_SIZE)
+ len = PAM_MAX_RESP_SIZE;
+ pam_modutil_write(fds[1], towhat, len);
+ }
+ pam_modutil_write(fds[1], "", 1);
+
+ close(fds[0]); /* close here to avoid possible SIGPIPE above */
+ close(fds[1]);
+ /* wait for helper to complete: */
+ while ((rc=waitpid(child, &retval, 0)) < 0 && errno == EINTR);
+ if (rc<0) {
+ pam_syslog(pamh, LOG_ERR, "unix_update waitpid failed: %m");
+ retval = PAM_AUTHTOK_ERR;
+ } else if (!WIFEXITED(retval)) {
+ pam_syslog(pamh, LOG_ERR, "unix_update abnormal exit: %d", retval);
+ retval = PAM_AUTHTOK_ERR;
+ } else {
+ retval = WEXITSTATUS(retval);
+ }
+ } else {
+ D(("fork failed"));
+ close(fds[0]);
+ close(fds[1]);
+ retval = PAM_AUTH_ERR;
+ }
+
+ if (off(UNIX_NOREAP, ctrl)) {
+ sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */
+ }
+
+ return retval;
+}
+#endif
+
+static int check_old_password(const char *forwho, const char *newpass)
+{
+ static char buf[16384];
+ char *s_pas;
+ int retval = PAM_SUCCESS;
+ FILE *opwfile;
+ size_t len = strlen(forwho);
+
+ opwfile = fopen(OLD_PASSWORDS_FILE, "r");
+ if (opwfile == NULL)
+ return PAM_ABORT;
+
+ while (fgets(buf, 16380, opwfile)) {
+ if (!strncmp(buf, forwho, len) && (buf[len] == ':' ||
+ buf[len] == ',')) {
+ char *sptr;
+ buf[strlen(buf) - 1] = '\0';
+ /* s_luser = */ strtok_r(buf, ":,", &sptr);
+ /* s_uid = */ strtok_r(NULL, ":,", &sptr);
+ /* s_npas = */ strtok_r(NULL, ":,", &sptr);
+ s_pas = strtok_r(NULL, ":,", &sptr);
+ while (s_pas != NULL) {
+ char *md5pass = Goodcrypt_md5(newpass, s_pas);
+ if (md5pass == NULL || !strcmp(md5pass, s_pas)) {
+ _pam_delete(md5pass);
+ retval = PAM_AUTHTOK_ERR;
+ break;
+ }
+ s_pas = strtok_r(NULL, ":,", &sptr);
+ _pam_delete(md5pass);
+ }
+ break;
+ }
+ }
+ fclose(opwfile);
+
+ return retval;
+}
+
+static int _do_setpass(pam_handle_t* pamh, const char *forwho,
+ const char *fromwhat,
+ char *towhat, unsigned long long ctrl, int remember)
+{
+ struct passwd *pwd = NULL;
+ int retval = 0;
+ int unlocked = 0;
+
+ D(("called"));
+
+ pwd = getpwnam(forwho);
+
+ if (pwd == NULL) {
+ retval = PAM_AUTHTOK_ERR;
+ goto done;
+ }
+
+ if (on(UNIX_NIS, ctrl) && _unix_comesfromsource(pamh, forwho, 0, 1)) {
+#ifdef HAVE_NIS
+ char *master;
+
+ if ((master=getNISserver(pamh, ctrl)) != NULL) {
+ struct timeval timeout;
+ struct yppasswd yppwd;
+ CLIENT *clnt;
+ int status;
+ enum clnt_stat err;
+
+ /* Unlock passwd file to avoid deadlock */
+ unlock_pwdf();
+ unlocked = 1;
+
+ /* Initialize password information */
+ yppwd.newpw.pw_passwd = pwd->pw_passwd;
+ yppwd.newpw.pw_name = pwd->pw_name;
+ yppwd.newpw.pw_uid = pwd->pw_uid;
+ yppwd.newpw.pw_gid = pwd->pw_gid;
+ yppwd.newpw.pw_gecos = pwd->pw_gecos;
+ yppwd.newpw.pw_dir = pwd->pw_dir;
+ yppwd.newpw.pw_shell = pwd->pw_shell;
+ yppwd.oldpass = fromwhat ? strdup (fromwhat) : strdup ("");
+ yppwd.newpw.pw_passwd = towhat;
+
+ D(("Set password %s for %s", yppwd.newpw.pw_passwd, forwho));
+
+ /* The yppasswd.x file said `unix authentication required',
+ * so I added it. This is the only reason it is in here.
+ * My yppasswdd doesn't use it, but maybe some others out there
+ * do. --okir
+ */
+ clnt = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp");
+ clnt->cl_auth = authunix_create_default();
+ memset((char *) &status, '\0', sizeof(status));
+ timeout.tv_sec = 25;
+ timeout.tv_usec = 0;
+ err = clnt_call(clnt, YPPASSWDPROC_UPDATE,
+ (xdrproc_t) xdr_yppasswd, (char *) &yppwd,
+ (xdrproc_t) xdr_int, (char *) &status,
+ timeout);
+
+ free (yppwd.oldpass);
+
+ if (err) {
+ _make_remark(pamh, ctrl, PAM_TEXT_INFO,
+ clnt_sperrno(err));
+ } else if (status) {
+ D(("Error while changing NIS password.\n"));
+ }
+ D(("The password has%s been changed on %s.",
+ (err || status) ? " not" : "", master));
+ pam_syslog(pamh, LOG_NOTICE, "password%s changed for %s on %s",
+ (err || status) ? " not" : "", pwd->pw_name, master);
+
+ auth_destroy(clnt->cl_auth);
+ clnt_destroy(clnt);
+ if (err || status) {
+ _make_remark(pamh, ctrl, PAM_TEXT_INFO,
+ _("NIS password could not be changed."));
+ retval = PAM_TRY_AGAIN;
+ }
+#ifdef PAM_DEBUG
+ sleep(5);
+#endif
+ } else {
+ retval = PAM_TRY_AGAIN;
+ }
+#else
+ if (on(UNIX_DEBUG, ctrl)) {
+ pam_syslog(pamh, LOG_DEBUG, "No NIS support available");
+ }
+
+ retval = PAM_TRY_AGAIN;
+#endif
+ }
+
+ if (_unix_comesfromsource(pamh, forwho, 1, 0)) {
+ if(unlocked) {
+ if (lock_pwdf() != PAM_SUCCESS) {
+ return PAM_AUTHTOK_LOCK_BUSY;
+ }
+ }
+#ifdef WITH_SELINUX
+ if (unix_selinux_confined())
+ return _unix_run_update_binary(pamh, ctrl, forwho, fromwhat, towhat, remember);
+#endif
+ /* first, save old password */
+ if (save_old_password(pamh, forwho, fromwhat, remember)) {
+ retval = PAM_AUTHTOK_ERR;
+ goto done;
+ }
+ if (on(UNIX_SHADOW, ctrl) || is_pwd_shadowed(pwd)) {
+ retval = unix_update_shadow(pamh, forwho, towhat);
+ if (retval == PAM_SUCCESS)
+ if (!is_pwd_shadowed(pwd))
+ retval = unix_update_passwd(pamh, forwho, "x");
+ } else {
+ retval = unix_update_passwd(pamh, forwho, towhat);
+ }
+ }
+
+
+done:
+ unlock_pwdf();
+
+ return retval;
+}
+
+static int _unix_verify_shadow(pam_handle_t *pamh, const char *user, unsigned long long ctrl)
+{
+ struct passwd *pwent = NULL; /* Password and shadow password */
+ struct spwd *spent = NULL; /* file entries for the user */
+ int daysleft;
+ int retval;
+
+ retval = get_account_info(pamh, user, &pwent, &spent);
+ if (retval == PAM_USER_UNKNOWN) {
+ return retval;
+ }
+
+ if (retval == PAM_SUCCESS && spent == NULL)
+ return PAM_SUCCESS;
+
+ if (retval == PAM_UNIX_RUN_HELPER) {
+ retval = _unix_run_verify_binary(pamh, ctrl, user, &daysleft);
+ if (retval == PAM_AUTH_ERR || retval == PAM_USER_UNKNOWN)
+ return retval;
+ }
+ else if (retval == PAM_SUCCESS)
+ retval = check_shadow_expiry(pamh, spent, &daysleft);
+
+ if (on(UNIX__IAMROOT, ctrl) || retval == PAM_NEW_AUTHTOK_REQD)
+ return PAM_SUCCESS;
+
+ return retval;
+}
+
+static int _pam_unix_approve_pass(pam_handle_t * pamh
+ ,unsigned long long ctrl
+ ,const char *pass_old
+ ,const char *pass_new,
+ int pass_min_len)
+{
+ const void *user;
+ const char *remark = NULL;
+ int retval = PAM_SUCCESS;
+
+ D(("&new=%p, &old=%p", pass_old, pass_new));
+ D(("new=[%s]", pass_new));
+ D(("old=[%s]", pass_old));
+
+ if (pass_new == NULL || (pass_old && !strcmp(pass_old, pass_new))) {
+ if (on(UNIX_DEBUG, ctrl)) {
+ pam_syslog(pamh, LOG_DEBUG, "bad authentication token");
+ }
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG, pass_new == NULL ?
+ _("No password has been supplied.") :
+ _("The password has not been changed."));
+ return PAM_AUTHTOK_ERR;
+ }
+ /*
+ * if one wanted to hardwire authentication token strength
+ * checking this would be the place - AGM
+ */
+
+ retval = pam_get_item(pamh, PAM_USER, &user);
+ if (retval != PAM_SUCCESS) {
+ if (on(UNIX_DEBUG, ctrl)) {
+ pam_syslog(pamh, LOG_ERR, "Can not get username");
+ return PAM_AUTHTOK_ERR;
+ }
+ }
+
+ if (strlen(pass_new) > PAM_MAX_RESP_SIZE) {
+ remark = _("You must choose a shorter password.");
+ D(("length exceeded [%s]", remark));
+ } else if (off(UNIX__IAMROOT, ctrl)) {
+ if ((int)strlen(pass_new) < pass_min_len)
+ remark = _("You must choose a longer password.");
+ D(("length check [%s]", remark));
+ if (on(UNIX_REMEMBER_PASSWD, ctrl)) {
+ if ((retval = check_old_password(user, pass_new)) == PAM_AUTHTOK_ERR)
+ remark = _("Password has been already used. Choose another.");
+ if (retval == PAM_ABORT) {
+ pam_syslog(pamh, LOG_ERR, "can't open %s file to check old passwords",
+ OLD_PASSWORDS_FILE);
+ return retval;
+ }
+ }
+ }
+ if (remark) {
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG, remark);
+ retval = PAM_AUTHTOK_ERR;
+ }
+ return retval;
+}
+
+int
+pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ unsigned long long ctrl, lctrl;
+ int retval;
+ int remember = -1;
+ int rounds = 0;
+ int pass_min_len = 0;
+
+ /* <DO NOT free() THESE> */
+ const char *user;
+ const void *item;
+ const char *pass_old, *pass_new;
+ /* </DO NOT free() THESE> */
+
+ D(("called."));
+
+ ctrl = _set_ctrl(pamh, flags, &remember, &rounds, &pass_min_len,
+ argc, argv);
+
+ /*
+ * First get the name of a user
+ */
+ retval = pam_get_user(pamh, &user, NULL);
+ if (retval == PAM_SUCCESS) {
+ /*
+ * Various libraries at various times have had bugs related to
+ * '+' or '-' as the first character of a user name. Don't
+ * allow them.
+ */
+ if (user[0] == '-' || user[0] == '+') {
+ pam_syslog(pamh, LOG_NOTICE, "bad username [%s]", user);
+ return PAM_USER_UNKNOWN;
+ }
+ if (retval == PAM_SUCCESS && on(UNIX_DEBUG, ctrl))
+ pam_syslog(pamh, LOG_DEBUG, "username [%s] obtained",
+ user);
+ } else {
+ if (on(UNIX_DEBUG, ctrl))
+ pam_syslog(pamh, LOG_DEBUG,
+ "password - could not identify user");
+ return retval;
+ }
+
+ D(("Got username of %s", user));
+
+ /*
+ * Before we do anything else, check to make sure that the user's
+ * info is in one of the databases we can modify from this module,
+ * which currently is 'files' and 'nis'. We have to do this because
+ * getpwnam() doesn't tell you *where* the information it gives you
+ * came from, nor should it. That's our job.
+ */
+ if (_unix_comesfromsource(pamh, user, 1, on(UNIX_NIS, ctrl)) == 0) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "user \"%s\" does not exist in /etc/passwd%s",
+ user, on(UNIX_NIS, ctrl) ? " or NIS" : "");
+ return PAM_USER_UNKNOWN;
+ } else {
+ struct passwd *pwd;
+ _unix_getpwnam(pamh, user, 1, 1, &pwd);
+ if (pwd == NULL) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "user \"%s\" has corrupted passwd entry",
+ user);
+ return PAM_USER_UNKNOWN;
+ }
+ }
+
+ /*
+ * This is not an AUTH module!
+ */
+ if (on(UNIX__NONULL, ctrl))
+ set(UNIX__NULLOK, ctrl);
+
+ if (on(UNIX__PRELIM, ctrl)) {
+ /*
+ * obtain and verify the current password (OLDAUTHTOK) for
+ * the user.
+ */
+ D(("prelim check"));
+
+ if (_unix_blankpasswd(pamh, ctrl, user)) {
+ return PAM_SUCCESS;
+ } else if (off(UNIX__IAMROOT, ctrl) ||
+ (on(UNIX_NIS, ctrl) && _unix_comesfromsource(pamh, user, 0, 1))) {
+ /* instruct user what is happening */
+ if (off(UNIX__QUIET, ctrl)) {
+ retval = pam_info(pamh, _("Changing password for %s."), user);
+ if (retval != PAM_SUCCESS)
+ return retval;
+ }
+ retval = pam_get_authtok(pamh, PAM_OLDAUTHTOK, &pass_old, NULL);
+
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE,
+ "password - (old) token not obtained");
+ return retval;
+ }
+ /* verify that this is the password for this user */
+
+ retval = _unix_verify_password(pamh, user, pass_old, ctrl);
+ } else {
+ D(("process run by root so do nothing this time around"));
+ pass_old = NULL;
+ retval = PAM_SUCCESS; /* root doesn't have too */
+ }
+
+ if (retval != PAM_SUCCESS) {
+ D(("Authentication failed"));
+ pass_old = NULL;
+ return retval;
+ }
+ pass_old = NULL;
+ retval = _unix_verify_shadow(pamh,user, ctrl);
+ if (retval == PAM_AUTHTOK_ERR) {
+ if (off(UNIX__IAMROOT, ctrl))
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG,
+ _("You must wait longer to change your password."));
+ else
+ retval = PAM_SUCCESS;
+ }
+ } else if (on(UNIX__UPDATE, ctrl)) {
+ /*
+ * tpass is used below to store the _pam_md() return; it
+ * should be _pam_delete()'d.
+ */
+
+ char *tpass = NULL;
+ int retry = 0;
+
+ /*
+ * obtain the proposed password
+ */
+
+ D(("do update"));
+
+ /*
+ * get the old token back. NULL was ok only if root [at this
+ * point we assume that this has already been enforced on a
+ * previous call to this function].
+ */
+
+ retval = pam_get_item(pamh, PAM_OLDAUTHTOK, &item);
+
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE, "user not authenticated");
+ return retval;
+ }
+ pass_old = item;
+ D(("pass_old [%s]", pass_old));
+
+ D(("get new password now"));
+
+ lctrl = ctrl;
+
+ if (on(UNIX_USE_AUTHTOK, lctrl)) {
+ set(UNIX_USE_FIRST_PASS, lctrl);
+ }
+ if (on(UNIX_USE_FIRST_PASS, lctrl)) {
+ retry = MAX_PASSWD_TRIES-1;
+ }
+ retval = PAM_AUTHTOK_ERR;
+ while ((retval != PAM_SUCCESS) && (retry++ < MAX_PASSWD_TRIES)) {
+ /*
+ * use_authtok is to force the use of a previously entered
+ * password -- needed for pluggable password strength checking
+ */
+
+ retval = pam_get_authtok(pamh, PAM_AUTHTOK, &pass_new, NULL);
+
+ if (retval != PAM_SUCCESS) {
+ if (on(UNIX_DEBUG, ctrl)) {
+ pam_syslog(pamh, LOG_ERR,
+ "password - new password not obtained");
+ }
+ pass_old = NULL; /* tidy up */
+ return retval;
+ }
+ D(("returned to _unix_chauthtok"));
+
+ /*
+ * At this point we know who the user is and what they
+ * propose as their new password. Verify that the new
+ * password is acceptable.
+ */
+
+ if (*(const char *)pass_new == '\0') { /* "\0" password = NULL */
+ pass_new = NULL;
+ }
+ retval = _pam_unix_approve_pass(pamh, ctrl, pass_old,
+ pass_new, pass_min_len);
+
+ if (retval != PAM_SUCCESS) {
+ pam_set_item(pamh, PAM_AUTHTOK, NULL);
+ }
+ }
+
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE,
+ "new password not acceptable");
+ pass_new = pass_old = NULL; /* tidy up */
+ return retval;
+ }
+ if (lock_pwdf() != PAM_SUCCESS) {
+ return PAM_AUTHTOK_LOCK_BUSY;
+ }
+
+ if (pass_old) {
+ retval = _unix_verify_password(pamh, user, pass_old, ctrl);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE, "user password changed by another process");
+ unlock_pwdf();
+ return retval;
+ }
+ }
+
+ retval = _unix_verify_shadow(pamh, user, ctrl);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE, "user shadow entry expired");
+ unlock_pwdf();
+ return retval;
+ }
+
+ retval = _pam_unix_approve_pass(pamh, ctrl, pass_old, pass_new,
+ pass_min_len);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE,
+ "new password not acceptable 2");
+ pass_new = pass_old = NULL; /* tidy up */
+ unlock_pwdf();
+ return retval;
+ }
+
+ /*
+ * By reaching here we have approved the passwords and must now
+ * rebuild the password database file.
+ */
+
+ /*
+ * First we encrypt the new password.
+ */
+
+ tpass = create_password_hash(pamh, pass_new, ctrl, rounds);
+ if (tpass == NULL) {
+ pam_syslog(pamh, LOG_CRIT,
+ "crypt() failure or out of memory for password");
+ pass_new = pass_old = NULL; /* tidy up */
+ unlock_pwdf();
+ return PAM_BUF_ERR;
+ }
+
+ D(("password processed"));
+
+ /* update the password database(s) -- race conditions..? */
+
+ retval = _do_setpass(pamh, user, pass_old, tpass, ctrl,
+ remember);
+ /* _do_setpass has called unlock_pwdf for us */
+
+ _pam_delete(tpass);
+ pass_old = pass_new = NULL;
+ } else { /* something has broken with the module */
+ pam_syslog(pamh, LOG_CRIT,
+ "password received unknown request");
+ retval = PAM_ABORT;
+ }
+
+ D(("retval was %d", retval));
+
+ return retval;
+}
diff --git a/modules/pam_unix/pam_unix_sess.c b/modules/pam_unix/pam_unix_sess.c
new file mode 100644
index 0000000..3f6a8fb
--- /dev/null
+++ b/modules/pam_unix/pam_unix_sess.c
@@ -0,0 +1,134 @@
+/*
+ * pam_unix session management
+ *
+ * Copyright Alexander O. Yuriev, 1996. All rights reserved.
+ * Copyright Jan Rękorajski, 1999. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <security/_pam_macros.h>
+#include <security/pam_modules.h>
+#include <security/pam_ext.h>
+#include <security/pam_modutil.h>
+
+#include "support.h"
+
+/*
+ * PAM framework looks for these entry-points to pass control to the
+ * session module.
+ */
+
+int
+pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ char *user_name, *service;
+ unsigned long long ctrl;
+ int retval;
+ const char *login_name;
+
+ D(("called."));
+
+ ctrl = _set_ctrl(pamh, flags, NULL, NULL, NULL, argc, argv);
+
+ retval = pam_get_item(pamh, PAM_USER, (void *) &user_name);
+ if (user_name == NULL || *user_name == '\0' || retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR,
+ "open_session - error recovering username");
+ return PAM_SESSION_ERR; /* How did we get authenticated with
+ no username?! */
+ }
+ retval = pam_get_item(pamh, PAM_SERVICE, (void *) &service);
+ if (service == NULL || *service == '\0' || retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_CRIT,
+ "open_session - error recovering service");
+ return PAM_SESSION_ERR;
+ }
+ login_name = pam_modutil_getlogin(pamh);
+ if (login_name == NULL) {
+ login_name = "";
+ }
+ if (off (UNIX_QUIET, ctrl)) {
+ char uid[32];
+ struct passwd *pwd = pam_modutil_getpwnam (pamh, user_name);
+ if (pwd == NULL) {
+ snprintf (uid, 32, "getpwnam error");
+ }
+ else {
+ snprintf (uid, 32, "%u", pwd->pw_uid);
+ }
+ pam_syslog(pamh, LOG_INFO, "session opened for user %s(uid=%s) by %s(uid=%lu)", user_name, uid, login_name, (unsigned long)getuid());
+ }
+ return PAM_SUCCESS;
+}
+
+int
+pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ char *user_name, *service;
+ unsigned long long ctrl;
+ int retval;
+
+ D(("called."));
+
+ ctrl = _set_ctrl(pamh, flags, NULL, NULL, NULL, argc, argv);
+
+ retval = pam_get_item(pamh, PAM_USER, (void *) &user_name);
+ if (user_name == NULL || *user_name == '\0' || retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR,
+ "close_session - error recovering username");
+ return PAM_SESSION_ERR; /* How did we get authenticated with
+ no username?! */
+ }
+ retval = pam_get_item(pamh, PAM_SERVICE, (void *) &service);
+ if (service == NULL || *service == '\0' || retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_CRIT,
+ "close_session - error recovering service");
+ return PAM_SESSION_ERR;
+ }
+ if (off (UNIX_QUIET, ctrl))
+ pam_syslog(pamh, LOG_INFO, "session closed for user %s",
+ user_name);
+
+ return PAM_SUCCESS;
+}
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
new file mode 100644
index 0000000..f2474a5
--- /dev/null
+++ b/modules/pam_unix/passverify.c
@@ -0,0 +1,1211 @@
+/*
+ * Copyright information at end of file.
+ */
+#include "config.h"
+#include <security/_pam_macros.h>
+#include <security/pam_modules.h>
+#include "support.h"
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <shadow.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <signal.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef HAVE_CRYPT_H
+#include <crypt.h>
+#endif
+
+#include "pam_cc_compat.h"
+#include "pam_inline.h"
+#include "md5.h"
+#include "bigcrypt.h"
+#include "passverify.h"
+
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#define SELINUX_ENABLED (is_selinux_enabled()>0)
+#else
+#define SELINUX_ENABLED 0
+#endif
+
+#ifdef HELPER_COMPILE
+#define pam_modutil_getpwnam(h,n) getpwnam(n)
+#define pam_modutil_getspnam(h,n) getspnam(n)
+#define pam_syslog(h,a,b,c) helper_log_err(a,b,c)
+#else
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+#endif
+
+#if defined(USE_LCKPWDF) && !defined(HAVE_LCKPWDF)
+# include "./lckpwdf.-c"
+#endif
+
+static void
+strip_hpux_aging(char *hash)
+{
+ static const char valid[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789./";
+ if ((*hash != '$') && (strlen(hash) > 13)) {
+ for (hash += 13; *hash != '\0'; hash++) {
+ if (strchr(valid, *hash) == NULL) {
+ *hash = '\0';
+ break;
+ }
+ }
+ }
+}
+
+PAMH_ARG_DECL(int verify_pwd_hash,
+ const char *p, char *hash, unsigned int nullok)
+{
+ size_t hash_len;
+ char *pp = NULL;
+ int retval;
+ D(("called"));
+
+ strip_hpux_aging(hash);
+ hash_len = strlen(hash);
+ if (!hash_len) {
+ /* the stored password is NULL */
+ if (nullok) { /* this means we've succeeded */
+ D(("user has empty password - access granted"));
+ retval = PAM_SUCCESS;
+ } else {
+ D(("user has empty password - access denied"));
+ retval = PAM_AUTH_ERR;
+ }
+ } else if (!p || *hash == '*' || *hash == '!') {
+ retval = PAM_AUTH_ERR;
+ } else {
+ if (pam_str_skip_prefix(hash, "$1$") != NULL) {
+ pp = Goodcrypt_md5(p, hash);
+ if (pp && strcmp(pp, hash) != 0) {
+ _pam_delete(pp);
+ pp = Brokencrypt_md5(p, hash);
+ }
+ } else if (*hash != '$' && hash_len >= 13) {
+ pp = bigcrypt(p, hash);
+ if (pp && hash_len == 13 && strlen(pp) > hash_len) {
+ _pam_overwrite(pp + hash_len);
+ }
+ } else {
+ /*
+ * Ok, we don't know the crypt algorithm, but maybe
+ * libcrypt knows about it? We should try it.
+ */
+#if defined(CRYPT_CHECKSALT_AVAILABLE) && CRYPT_CHECKSALT_AVAILABLE
+ /* Get the status of the hash from checksalt */
+ int retval_checksalt = crypt_checksalt(hash);
+
+ /*
+ * Check for hashing methods that are disabled by
+ * libcrypt configuration and/or system preset.
+ */
+ if (retval_checksalt == CRYPT_SALT_METHOD_DISABLED) {
+ /*
+ * pam_syslog() needs a pam handle,
+ * but that's not available here.
+ */
+ pam_syslog(pamh, LOG_ERR,
+ "The support for password hash \"%.6s\" "
+ "has been disabled in libcrypt "
+ "configuration.",
+ hash);
+ }
+ /*
+ * Check for malformed hashes, like descrypt hashes
+ * starting with "$2...", which might have been
+ * generated by unsafe base64 encoding functions
+ * as used in glibc <= 2.16.
+ * Such hashes are likely to be rejected by many
+ * recent implementations of libcrypt.
+ */
+ if (retval_checksalt == CRYPT_SALT_INVALID) {
+ pam_syslog(pamh, LOG_ERR,
+ "The password hash \"%.6s\" is unknown to "
+ "libcrypt.",
+ hash);
+ }
+#else
+#ifndef HELPER_COMPILE
+ (void)pamh;
+#endif
+#endif
+#ifdef HAVE_CRYPT_R
+ struct crypt_data *cdata;
+ cdata = malloc(sizeof(*cdata));
+ if (cdata != NULL) {
+ cdata->initialized = 0;
+ pp = x_strdup(crypt_r(p, hash, cdata));
+ memset(cdata, '\0', sizeof(*cdata));
+ free(cdata);
+ }
+#else
+ pp = x_strdup(crypt(p, hash));
+#endif
+ }
+ p = NULL; /* no longer needed here */
+
+ /* the moment of truth -- do we agree with the password? */
+ D(("comparing state of pp[%s] and hash[%s]", pp, hash));
+
+ if (pp && strcmp(pp, hash) == 0) {
+ retval = PAM_SUCCESS;
+ } else {
+ retval = PAM_AUTH_ERR;
+ }
+ }
+
+ if (pp)
+ _pam_delete(pp);
+ D(("done [%d].", retval));
+
+ return retval;
+}
+
+int
+is_pwd_shadowed(const struct passwd *pwd)
+{
+ if (pwd != NULL) {
+ if (strcmp(pwd->pw_passwd, "x") == 0) {
+ return 1;
+ }
+ if ((pwd->pw_passwd[0] == '#') &&
+ (pwd->pw_passwd[1] == '#') &&
+ (strcmp(pwd->pw_name, pwd->pw_passwd + 2) == 0)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+PAMH_ARG_DECL(int get_account_info,
+ const char *name, struct passwd **pwd, struct spwd **spwdent)
+{
+ /* UNIX passwords area */
+ *pwd = pam_modutil_getpwnam(pamh, name); /* Get password file entry... */
+ *spwdent = NULL;
+
+ if (*pwd != NULL) {
+ if (strcmp((*pwd)->pw_passwd, "*NP*") == 0)
+ { /* NIS+ */
+#ifdef HELPER_COMPILE
+ uid_t save_euid, save_uid;
+
+ save_euid = geteuid();
+ save_uid = getuid();
+ if (save_uid == (*pwd)->pw_uid) {
+ if (setreuid(save_euid, save_uid))
+ return PAM_CRED_INSUFFICIENT;
+ } else {
+ if (setreuid(0, -1))
+ return PAM_CRED_INSUFFICIENT;
+ if (setreuid(-1, (*pwd)->pw_uid)) {
+ if (setreuid(-1, 0)
+ || setreuid(0, -1)
+ || setreuid(-1, (*pwd)->pw_uid)) {
+ return PAM_CRED_INSUFFICIENT;
+ }
+ }
+ }
+
+ *spwdent = pam_modutil_getspnam(pamh, name);
+ if (save_uid == (*pwd)->pw_uid) {
+ if (setreuid(save_uid, save_euid))
+ return PAM_CRED_INSUFFICIENT;
+ } else {
+ if (setreuid(-1, 0)
+ || setreuid(save_uid, -1)
+ || setreuid(-1, save_euid))
+ return PAM_CRED_INSUFFICIENT;
+ }
+
+ if (*spwdent == NULL || (*spwdent)->sp_pwdp == NULL)
+ return PAM_AUTHINFO_UNAVAIL;
+#else
+ /* we must run helper for NIS+ passwords */
+ return PAM_UNIX_RUN_HELPER;
+#endif
+ } else if (is_pwd_shadowed(*pwd)) {
+ /*
+ * ...and shadow password file entry for this user,
+ * if shadowing is enabled
+ */
+ *spwdent = pam_modutil_getspnam(pamh, name);
+ if (*spwdent == NULL) {
+#ifndef HELPER_COMPILE
+ /* still a chance the user can authenticate */
+ return PAM_UNIX_RUN_HELPER;
+#endif
+ return PAM_AUTHINFO_UNAVAIL;
+ }
+ if ((*spwdent)->sp_pwdp == NULL)
+ return PAM_AUTHINFO_UNAVAIL;
+ }
+ } else {
+ return PAM_USER_UNKNOWN;
+ }
+ return PAM_SUCCESS;
+}
+
+PAMH_ARG_DECL(int get_pwd_hash,
+ const char *name, struct passwd **pwd, char **hash)
+{
+ int retval;
+ struct spwd *spwdent = NULL;
+
+ retval = get_account_info(PAMH_ARG(name, pwd, &spwdent));
+ if (retval != PAM_SUCCESS) {
+ return retval;
+ }
+
+ if (spwdent)
+ *hash = x_strdup(spwdent->sp_pwdp);
+ else
+ *hash = x_strdup((*pwd)->pw_passwd);
+ if (*hash == NULL)
+ return PAM_BUF_ERR;
+
+ return PAM_SUCCESS;
+}
+
+PAMH_ARG_DECL(int check_shadow_expiry,
+ struct spwd *spent, int *daysleft)
+{
+ long int curdays;
+ *daysleft = -1;
+ curdays = (long int)(time(NULL) / (60 * 60 * 24));
+ D(("today is %d, last change %d", curdays, spent->sp_lstchg));
+ if ((curdays >= spent->sp_expire) && (spent->sp_expire != -1)) {
+ D(("account expired"));
+ return PAM_ACCT_EXPIRED;
+ }
+ if (spent->sp_lstchg == 0) {
+ D(("need a new password"));
+ *daysleft = 0;
+ return PAM_NEW_AUTHTOK_REQD;
+ }
+ if (curdays < spent->sp_lstchg) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "account %s has password changed in future",
+ spent->sp_namp);
+ return PAM_SUCCESS;
+ }
+ if ((curdays - spent->sp_lstchg > spent->sp_max)
+ && (curdays - spent->sp_lstchg > spent->sp_inact)
+ && (curdays - spent->sp_lstchg > spent->sp_max + spent->sp_inact)
+ && (spent->sp_max != -1) && (spent->sp_inact != -1)) {
+ *daysleft = (int)((spent->sp_lstchg + spent->sp_max) - curdays);
+ D(("authtok expired"));
+ return PAM_AUTHTOK_EXPIRED;
+ }
+ if ((curdays - spent->sp_lstchg > spent->sp_max) && (spent->sp_max != -1)) {
+ D(("need a new password 2"));
+ return PAM_NEW_AUTHTOK_REQD;
+ }
+ if ((curdays - spent->sp_lstchg > spent->sp_max - spent->sp_warn)
+ && (spent->sp_max != -1) && (spent->sp_warn != -1)) {
+ *daysleft = (int)((spent->sp_lstchg + spent->sp_max) - curdays);
+ D(("warn before expiry"));
+ }
+ if ((curdays - spent->sp_lstchg < spent->sp_min)
+ && (spent->sp_min != -1)) {
+ /*
+ * The last password change was too recent. This error will be ignored
+ * if no password change is attempted.
+ */
+ D(("password change too recent"));
+ return PAM_AUTHTOK_ERR;
+ }
+ return PAM_SUCCESS;
+}
+
+/* passwd/salt conversion macros */
+
+#define PW_TMPFILE "/etc/npasswd"
+#define SH_TMPFILE "/etc/nshadow"
+#define OPW_TMPFILE "/etc/security/nopasswd"
+
+/*
+ * i64c - convert an integer to a radix 64 character
+ */
+static int
+i64c(int i)
+{
+ if (i < 0)
+ return ('.');
+ else if (i > 63)
+ return ('z');
+ if (i == 0)
+ return ('.');
+ if (i == 1)
+ return ('/');
+ if (i >= 2 && i <= 11)
+ return ('0' - 2 + i);
+ if (i >= 12 && i <= 37)
+ return ('A' - 12 + i);
+ if (i >= 38 && i <= 63)
+ return ('a' - 38 + i);
+ return ('\0');
+}
+
+/* <where> must point to a buffer of at least <length>+1 length */
+static void
+crypt_make_salt(char *where, int length)
+{
+ struct timeval tv;
+ MD5_CTX ctx;
+ unsigned char tmp[16];
+ unsigned char *src = (unsigned char *)where;
+ int i;
+#ifdef PAM_PATH_RANDOMDEV
+ int fd;
+ int rv;
+
+ if ((rv = fd = open(PAM_PATH_RANDOMDEV, O_RDONLY)) != -1) {
+ while ((rv = read(fd, where, length)) != length && errno == EINTR);
+ close (fd);
+ }
+ if (rv != length) {
+#endif
+ /*
+ * Code lifted from Marek Michalkiewicz's shadow suite. (CG)
+ * removed use of static variables (AGM)
+ *
+ * will work correctly only for length <= 16 */
+ src = tmp;
+ GoodMD5Init(&ctx);
+ gettimeofday(&tv, (struct timezone *) 0);
+ GoodMD5Update(&ctx, (void *) &tv, sizeof tv);
+ i = getpid();
+ GoodMD5Update(&ctx, (void *) &i, sizeof i);
+ i = clock();
+ GoodMD5Update(&ctx, (void *) &i, sizeof i);
+ GoodMD5Update(&ctx, src, length);
+ GoodMD5Final(tmp, &ctx);
+#ifdef PAM_PATH_RANDOMDEV
+ }
+#endif
+ for (i = 0; i < length; i++)
+ *where++ = i64c(src[i] & 077);
+ *where = '\0';
+}
+
+char *
+crypt_md5_wrapper(const char *pass_new)
+{
+ unsigned char result[16];
+ char *cp = (char *) result;
+
+ cp = stpcpy(cp, "$1$"); /* magic for the MD5 */
+ crypt_make_salt(cp, 8);
+
+ /* no longer need cleartext */
+ cp = Goodcrypt_md5(pass_new, (const char *) result);
+ pass_new = NULL;
+
+ return cp;
+}
+
+PAMH_ARG_DECL(char * create_password_hash,
+ const char *password, unsigned long long ctrl, int rounds)
+{
+ const char *algoid;
+#if defined(CRYPT_GENSALT_OUTPUT_SIZE) && CRYPT_GENSALT_OUTPUT_SIZE > 64
+ /* Strings returned by crypt_gensalt_rn will be no longer than this. */
+ char salt[CRYPT_GENSALT_OUTPUT_SIZE];
+#else
+ char salt[64]; /* contains rounds number + max 16 bytes of salt + algo id */
+#endif
+ char *sp;
+#ifdef HAVE_CRYPT_R
+ struct crypt_data *cdata = NULL;
+#endif
+
+ if (on(UNIX_MD5_PASS, ctrl)) {
+ /* algoid = "$1" */
+ return crypt_md5_wrapper(password);
+ } else if (on(UNIX_YESCRYPT_PASS, ctrl)) {
+ algoid = "$y$";
+ } else if (on(UNIX_GOST_YESCRYPT_PASS, ctrl)) {
+ algoid = "$gy$";
+ } else if (on(UNIX_BLOWFISH_PASS, ctrl)) {
+ algoid = "$2b$";
+ } else if (on(UNIX_SHA256_PASS, ctrl)) {
+ algoid = "$5$";
+ } else if (on(UNIX_SHA512_PASS, ctrl)) {
+ algoid = "$6$";
+ } else { /* must be crypt/bigcrypt */
+ char tmppass[9];
+ char *hashed;
+
+ crypt_make_salt(salt, 2);
+ if (off(UNIX_BIGCRYPT, ctrl) && strlen(password) > 8) {
+ strncpy(tmppass, password, sizeof(tmppass)-1);
+ tmppass[sizeof(tmppass)-1] = '\0';
+ password = tmppass;
+ }
+ hashed = bigcrypt(password, salt);
+ memset(tmppass, '\0', sizeof(tmppass));
+ password = NULL;
+ return hashed;
+ }
+
+#if defined(CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY) && CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY
+ /*
+ * Any version of libcrypt supporting auto entropy is
+ * guaranteed to have crypt_gensalt_rn().
+ */
+ sp = crypt_gensalt_rn(algoid, rounds, NULL, 0, salt, sizeof(salt));
+#else
+ sp = stpcpy(salt, algoid);
+ if (on(UNIX_ALGO_ROUNDS, ctrl)) {
+ sp += snprintf(sp, sizeof(salt) - (16 + 1 + (sp - salt)), "rounds=%u$", rounds);
+ }
+ crypt_make_salt(sp, 16);
+#endif /* CRYPT_GENSALT_IMPLEMENTS_AUTO_ENTROPY */
+#ifdef HAVE_CRYPT_R
+ sp = NULL;
+ cdata = malloc(sizeof(*cdata));
+ if (cdata != NULL) {
+ cdata->initialized = 0;
+ sp = crypt_r(password, salt, cdata);
+ }
+#else
+ sp = crypt(password, salt);
+#endif
+ if (!sp || strncmp(algoid, sp, strlen(algoid)) != 0) {
+ /* libxcrypt/libc doesn't know the algorithm, error out */
+ pam_syslog(pamh, LOG_ERR,
+ "Algo %s not supported by the crypto backend.\n",
+ on(UNIX_YESCRYPT_PASS, ctrl) ? "yescrypt" :
+ on(UNIX_GOST_YESCRYPT_PASS, ctrl) ? "gost_yescrypt" :
+ on(UNIX_BLOWFISH_PASS, ctrl) ? "blowfish" :
+ on(UNIX_SHA256_PASS, ctrl) ? "sha256" :
+ on(UNIX_SHA512_PASS, ctrl) ? "sha512" : algoid);
+ if(sp) {
+ memset(sp, '\0', strlen(sp));
+ }
+#ifdef HAVE_CRYPT_R
+ free(cdata);
+#endif
+ return NULL;
+ }
+ sp = x_strdup(sp);
+#ifdef HAVE_CRYPT_R
+ free(cdata);
+#endif
+ return sp;
+}
+
+#ifdef WITH_SELINUX
+int
+unix_selinux_confined(void)
+{
+ static int confined = -1;
+ int fd;
+ char tempfile[]="/etc/.pwdXXXXXX";
+
+ if (confined != -1)
+ return confined;
+
+ /* cannot be confined without SELinux enabled */
+ if (!SELINUX_ENABLED){
+ confined = 0;
+ return confined;
+ }
+
+ /* let's try opening shadow read only */
+ if ((fd=open("/etc/shadow", O_RDONLY)) != -1) {
+ close(fd);
+ confined = 0;
+ return confined;
+ }
+
+ if (errno == EACCES) {
+ confined = 1;
+ return confined;
+ }
+
+ /* shadow opening failed because of other reasons let's try
+ creating a file in /etc */
+ if ((fd=mkstemp(tempfile)) != -1) {
+ unlink(tempfile);
+ close(fd);
+ confined = 0;
+ return confined;
+ }
+
+ confined = 1;
+ return confined;
+}
+
+#else
+int
+unix_selinux_confined(void)
+{
+ return 0;
+}
+#endif
+
+#ifdef USE_LCKPWDF
+int
+lock_pwdf(void)
+{
+ int i;
+ int retval;
+
+#ifndef HELPER_COMPILE
+ if (unix_selinux_confined()) {
+ return PAM_SUCCESS;
+ }
+#endif
+ /* These values for the number of attempts and the sleep time
+ are, of course, completely arbitrary.
+ My reading of the PAM docs is that, once pam_chauthtok() has been
+ called with PAM_UPDATE_AUTHTOK, we are obliged to take any
+ reasonable steps to make sure the token is updated; so retrying
+ for 1/10 sec. isn't overdoing it. */
+ i=0;
+ while((retval = lckpwdf()) != 0 && i < 100) {
+ usleep(1000);
+ i++;
+ }
+ if(retval != 0) {
+ return PAM_AUTHTOK_LOCK_BUSY;
+ }
+ return PAM_SUCCESS;
+}
+
+void
+unlock_pwdf(void)
+{
+#ifndef HELPER_COMPILE
+ if (unix_selinux_confined()) {
+ return;
+ }
+#endif
+ ulckpwdf();
+}
+#else
+int
+lock_pwdf(void)
+{
+ return PAM_SUCCESS;
+}
+
+void
+unlock_pwdf(void)
+{
+ return;
+}
+#endif
+
+#ifdef HELPER_COMPILE
+int
+save_old_password(const char *forwho, const char *oldpass,
+ int howmany)
+#else
+int
+save_old_password(pam_handle_t *pamh, const char *forwho, const char *oldpass,
+ int howmany)
+#endif
+{
+ static char buf[16384];
+ static char nbuf[16384];
+ char *s_luser, *s_uid, *s_npas, *s_pas, *pass;
+ int npas;
+ FILE *pwfile, *opwfile;
+ int err = 0;
+ int oldmask;
+ int found = 0;
+ struct passwd *pwd = NULL;
+ struct stat st;
+ size_t len = strlen(forwho);
+#ifdef WITH_SELINUX
+ char *prev_context_raw = NULL;
+#endif
+
+ if (howmany < 0) {
+ return PAM_SUCCESS;
+ }
+
+ if (oldpass == NULL) {
+ return PAM_SUCCESS;
+ }
+
+ oldmask = umask(077);
+
+#ifdef WITH_SELINUX
+ if (SELINUX_ENABLED) {
+ char *passwd_context_raw = NULL;
+ if (getfilecon_raw("/etc/passwd",&passwd_context_raw)<0) {
+ return PAM_AUTHTOK_ERR;
+ };
+ if (getfscreatecon_raw(&prev_context_raw)<0) {
+ freecon(passwd_context_raw);
+ return PAM_AUTHTOK_ERR;
+ }
+ if (setfscreatecon_raw(passwd_context_raw)) {
+ freecon(passwd_context_raw);
+ freecon(prev_context_raw);
+ return PAM_AUTHTOK_ERR;
+ }
+ freecon(passwd_context_raw);
+ }
+#endif
+ pwfile = fopen(OPW_TMPFILE, "w");
+ umask(oldmask);
+ if (pwfile == NULL) {
+ err = 1;
+ goto done;
+ }
+
+ opwfile = fopen(OLD_PASSWORDS_FILE, "r");
+ if (opwfile == NULL) {
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
+
+ if (fstat(fileno(opwfile), &st) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
+
+ if (fchown(fileno(pwfile), st.st_uid, st.st_gid) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
+ if (fchmod(fileno(pwfile), st.st_mode) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
+
+ while (fgets(buf, 16380, opwfile)) {
+ if (!strncmp(buf, forwho, len) && strchr(":,\n", buf[len]) != NULL) {
+ char *sptr = NULL;
+ found = 1;
+ if (howmany == 0)
+ continue;
+ buf[strlen(buf) - 1] = '\0';
+ s_luser = strtok_r(buf, ":", &sptr);
+ if (s_luser == NULL) {
+ found = 0;
+ continue;
+ }
+ s_uid = strtok_r(NULL, ":", &sptr);
+ if (s_uid == NULL) {
+ found = 0;
+ continue;
+ }
+ s_npas = strtok_r(NULL, ":", &sptr);
+ if (s_npas == NULL) {
+ found = 0;
+ continue;
+ }
+ s_pas = strtok_r(NULL, ":", &sptr);
+ npas = strtol(s_npas, NULL, 10) + 1;
+ while (npas > howmany && s_pas != NULL) {
+ s_pas = strpbrk(s_pas, ",");
+ if (s_pas != NULL)
+ s_pas++;
+ npas--;
+ }
+ pass = crypt_md5_wrapper(oldpass);
+ if (s_pas == NULL)
+ snprintf(nbuf, sizeof(nbuf), "%s:%s:%d:%s\n",
+ s_luser, s_uid, npas, pass);
+ else
+ snprintf(nbuf, sizeof(nbuf),"%s:%s:%d:%s,%s\n",
+ s_luser, s_uid, npas, s_pas, pass);
+ _pam_delete(pass);
+ if (fputs(nbuf, pwfile) < 0) {
+ err = 1;
+ break;
+ }
+ } else if (fputs(buf, pwfile) < 0) {
+ err = 1;
+ break;
+ }
+ }
+ fclose(opwfile);
+
+ if (!found) {
+ pwd = pam_modutil_getpwnam(pamh, forwho);
+ if (pwd == NULL) {
+ err = 1;
+ } else {
+ pass = crypt_md5_wrapper(oldpass);
+ snprintf(nbuf, sizeof(nbuf), "%s:%lu:1:%s\n",
+ forwho, (unsigned long)pwd->pw_uid, pass);
+ _pam_delete(pass);
+ if (fputs(nbuf, pwfile) < 0) {
+ err = 1;
+ }
+ }
+ }
+
+ if (fflush(pwfile) || fsync(fileno(pwfile))) {
+ D(("fflush or fsync error writing entries to old passwords file: %m"));
+ err = 1;
+ }
+
+ if (fclose(pwfile)) {
+ D(("fclose error writing entries to old passwords file: %m"));
+ err = 1;
+ }
+
+done:
+ if (!err) {
+ if (rename(OPW_TMPFILE, OLD_PASSWORDS_FILE))
+ err = 1;
+ }
+#ifdef WITH_SELINUX
+ if (SELINUX_ENABLED) {
+ if (setfscreatecon_raw(prev_context_raw)) {
+ err = 1;
+ }
+ if (prev_context_raw)
+ freecon(prev_context_raw);
+ prev_context_raw = NULL;
+ }
+#endif
+ if (!err) {
+ return PAM_SUCCESS;
+ } else {
+ unlink(OPW_TMPFILE);
+ return PAM_AUTHTOK_ERR;
+ }
+}
+
+PAMH_ARG_DECL(int unix_update_passwd,
+ const char *forwho, const char *towhat)
+{
+ struct passwd *tmpent = NULL;
+ struct stat st;
+ FILE *pwfile, *opwfile;
+ int err = 1;
+ int oldmask;
+#ifdef WITH_SELINUX
+ char *prev_context_raw = NULL;
+#endif
+
+ oldmask = umask(077);
+#ifdef WITH_SELINUX
+ if (SELINUX_ENABLED) {
+ char *passwd_context_raw = NULL;
+ if (getfilecon_raw("/etc/passwd",&passwd_context_raw)<0) {
+ return PAM_AUTHTOK_ERR;
+ };
+ if (getfscreatecon_raw(&prev_context_raw)<0) {
+ freecon(passwd_context_raw);
+ return PAM_AUTHTOK_ERR;
+ }
+ if (setfscreatecon_raw(passwd_context_raw)) {
+ freecon(passwd_context_raw);
+ freecon(prev_context_raw);
+ return PAM_AUTHTOK_ERR;
+ }
+ freecon(passwd_context_raw);
+ }
+#endif
+ pwfile = fopen(PW_TMPFILE, "w");
+ umask(oldmask);
+ if (pwfile == NULL) {
+ err = 1;
+ goto done;
+ }
+
+ opwfile = fopen("/etc/passwd", "r");
+ if (opwfile == NULL) {
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
+
+ if (fstat(fileno(opwfile), &st) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
+
+ if (fchown(fileno(pwfile), st.st_uid, st.st_gid) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
+ if (fchmod(fileno(pwfile), st.st_mode) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
+
+ tmpent = fgetpwent(opwfile);
+ while (tmpent) {
+ if (!strcmp(tmpent->pw_name, forwho)) {
+ /* To shut gcc up */
+ union {
+ const char *const_charp;
+ char *charp;
+ } assigned_passwd;
+ assigned_passwd.const_charp = towhat;
+
+ tmpent->pw_passwd = assigned_passwd.charp;
+ err = 0;
+ }
+ if (putpwent(tmpent, pwfile)) {
+ D(("error writing entry to password file: %m"));
+ err = 1;
+ break;
+ }
+ tmpent = fgetpwent(opwfile);
+ }
+ fclose(opwfile);
+
+ if (fflush(pwfile) || fsync(fileno(pwfile))) {
+ D(("fflush or fsync error writing entries to password file: %m"));
+ err = 1;
+ }
+
+ if (fclose(pwfile)) {
+ D(("fclose error writing entries to password file: %m"));
+ err = 1;
+ }
+
+done:
+ if (!err) {
+ if (!rename(PW_TMPFILE, "/etc/passwd"))
+ pam_syslog(pamh,
+ LOG_NOTICE, "password changed for %s", forwho);
+ else
+ err = 1;
+ }
+#ifdef WITH_SELINUX
+ if (SELINUX_ENABLED) {
+ if (setfscreatecon_raw(prev_context_raw)) {
+ err = 1;
+ }
+ if (prev_context_raw)
+ freecon(prev_context_raw);
+ prev_context_raw = NULL;
+ }
+#endif
+ if (!err) {
+ return PAM_SUCCESS;
+ } else {
+ unlink(PW_TMPFILE);
+ return PAM_AUTHTOK_ERR;
+ }
+}
+
+PAMH_ARG_DECL(int unix_update_shadow,
+ const char *forwho, char *towhat)
+{
+ struct spwd spwdent, *stmpent = NULL;
+ struct stat st;
+ FILE *pwfile, *opwfile;
+ int err = 0;
+ int oldmask;
+ int wroteentry = 0;
+#ifdef WITH_SELINUX
+ char *prev_context_raw = NULL;
+#endif
+
+ oldmask = umask(077);
+
+#ifdef WITH_SELINUX
+ if (SELINUX_ENABLED) {
+ char *shadow_context_raw = NULL;
+ if (getfilecon_raw("/etc/shadow",&shadow_context_raw)<0) {
+ return PAM_AUTHTOK_ERR;
+ };
+ if (getfscreatecon_raw(&prev_context_raw)<0) {
+ freecon(shadow_context_raw);
+ return PAM_AUTHTOK_ERR;
+ }
+ if (setfscreatecon_raw(shadow_context_raw)) {
+ freecon(shadow_context_raw);
+ freecon(prev_context_raw);
+ return PAM_AUTHTOK_ERR;
+ }
+ freecon(shadow_context_raw);
+ }
+#endif
+ pwfile = fopen(SH_TMPFILE, "w");
+ umask(oldmask);
+ if (pwfile == NULL) {
+ err = 1;
+ goto done;
+ }
+
+ opwfile = fopen("/etc/shadow", "r");
+ if (opwfile == NULL) {
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
+
+ if (fstat(fileno(opwfile), &st) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
+
+ if (fchown(fileno(pwfile), st.st_uid, st.st_gid) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
+ if (fchmod(fileno(pwfile), st.st_mode) == -1) {
+ fclose(opwfile);
+ fclose(pwfile);
+ err = 1;
+ goto done;
+ }
+
+ stmpent = fgetspent(opwfile);
+ while (stmpent) {
+
+ if (!strcmp(stmpent->sp_namp, forwho)) {
+ stmpent->sp_pwdp = towhat;
+ stmpent->sp_lstchg = time(NULL) / (60 * 60 * 24);
+ if (stmpent->sp_lstchg == 0)
+ stmpent->sp_lstchg = -1; /* Don't request passwort change
+ only because time isn't set yet. */
+ wroteentry = 1;
+ D(("Set password %s for %s", stmpent->sp_pwdp, forwho));
+ }
+
+ if (putspent(stmpent, pwfile)) {
+ D(("error writing entry to shadow file: %m"));
+ err = 1;
+ break;
+ }
+
+ stmpent = fgetspent(opwfile);
+ }
+
+ fclose(opwfile);
+
+ if (!wroteentry && !err) {
+ DIAG_PUSH_IGNORE_CAST_QUAL;
+ spwdent.sp_namp = (char *)forwho;
+ DIAG_POP_IGNORE_CAST_QUAL;
+ spwdent.sp_pwdp = towhat;
+ spwdent.sp_lstchg = time(NULL) / (60 * 60 * 24);
+ if (spwdent.sp_lstchg == 0)
+ spwdent.sp_lstchg = -1; /* Don't request passwort change
+ only because time isn't set yet. */
+ spwdent.sp_min = spwdent.sp_max = spwdent.sp_warn = spwdent.sp_inact =
+ spwdent.sp_expire = -1;
+ spwdent.sp_flag = (unsigned long)-1l;
+ if (putspent(&spwdent, pwfile)) {
+ D(("error writing entry to shadow file: %m"));
+ err = 1;
+ }
+ }
+
+ if (fflush(pwfile) || fsync(fileno(pwfile))) {
+ D(("fflush or fsync error writing entries to shadow file: %m"));
+ err = 1;
+ }
+
+ if (fclose(pwfile)) {
+ D(("fclose error writing entries to shadow file: %m"));
+ err = 1;
+ }
+
+ done:
+ if (!err) {
+ if (!rename(SH_TMPFILE, "/etc/shadow"))
+ pam_syslog(pamh,
+ LOG_NOTICE, "password changed for %s", forwho);
+ else
+ err = 1;
+ }
+
+#ifdef WITH_SELINUX
+ if (SELINUX_ENABLED) {
+ if (setfscreatecon_raw(prev_context_raw)) {
+ err = 1;
+ }
+ if (prev_context_raw)
+ freecon(prev_context_raw);
+ prev_context_raw = NULL;
+ }
+#endif
+
+ if (!err) {
+ return PAM_SUCCESS;
+ } else {
+ unlink(SH_TMPFILE);
+ return PAM_AUTHTOK_ERR;
+ }
+}
+
+#ifdef HELPER_COMPILE
+
+int
+helper_verify_password(const char *name, const char *p, int nullok)
+{
+ struct passwd *pwd = NULL;
+ char *hash = NULL;
+ int retval;
+
+ retval = get_pwd_hash(name, &pwd, &hash);
+
+ if (pwd == NULL || hash == NULL) {
+ helper_log_err(LOG_NOTICE, "check pass; user unknown");
+ retval = PAM_USER_UNKNOWN;
+ } else if (p[0] == '\0' && nullok) {
+ if (hash[0] == '\0') {
+ retval = PAM_SUCCESS;
+ } else {
+ retval = PAM_AUTH_ERR;
+ }
+ } else {
+ retval = verify_pwd_hash(p, hash, nullok);
+ }
+
+ if (hash) {
+ _pam_overwrite(hash);
+ _pam_drop(hash);
+ }
+
+ p = NULL; /* no longer needed here */
+
+ return retval;
+}
+
+void
+PAM_FORMAT((printf, 2, 3))
+helper_log_err(int err, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ openlog(HELPER_COMPILE, LOG_CONS | LOG_PID, LOG_AUTHPRIV);
+ vsyslog(err, format, args);
+ va_end(args);
+ closelog();
+}
+
+static void
+su_sighandler(int sig)
+{
+#ifndef SA_RESETHAND
+ /* emulate the behaviour of the SA_RESETHAND flag */
+ if ( sig == SIGILL || sig == SIGTRAP || sig == SIGBUS || sig = SIGSERV ) {
+ struct sigaction sa;
+ memset(&sa, '\0', sizeof(sa));
+ sa.sa_handler = SIG_DFL;
+ sigaction(sig, &sa, NULL);
+ }
+#endif
+ if (sig > 0) {
+ _exit(sig);
+ }
+}
+
+void
+setup_signals(void)
+{
+ struct sigaction action; /* posix signal structure */
+
+ /*
+ * Setup signal handlers
+ */
+ (void) memset((void *) &action, 0, sizeof(action));
+ action.sa_handler = su_sighandler;
+#ifdef SA_RESETHAND
+ action.sa_flags = SA_RESETHAND;
+#endif
+ (void) sigaction(SIGILL, &action, NULL);
+ (void) sigaction(SIGTRAP, &action, NULL);
+ (void) sigaction(SIGBUS, &action, NULL);
+ (void) sigaction(SIGSEGV, &action, NULL);
+ action.sa_handler = SIG_IGN;
+ action.sa_flags = 0;
+ (void) sigaction(SIGTERM, &action, NULL);
+ (void) sigaction(SIGHUP, &action, NULL);
+ (void) sigaction(SIGINT, &action, NULL);
+ (void) sigaction(SIGQUIT, &action, NULL);
+}
+
+char *
+getuidname(uid_t uid)
+{
+ struct passwd *pw;
+ static char username[256];
+
+ pw = getpwuid(uid);
+ if (pw == NULL)
+ return NULL;
+
+ strncpy(username, pw->pw_name, sizeof(username));
+ username[sizeof(username) - 1] = '\0';
+
+ return username;
+}
+
+#endif
+/* ****************************************************************** *
+ * Copyright (c) Jan Rękorajski 1999.
+ * Copyright (c) Andrew G. Morgan 1996-8.
+ * Copyright (c) Alex O. Yuriev, 1996.
+ * Copyright (c) Cristian Gafton 1996.
+ * Copyright (c) Red Hat, Inc. 1996, 2007, 2008.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/modules/pam_unix/passverify.h b/modules/pam_unix/passverify.h
new file mode 100644
index 0000000..c07037d
--- /dev/null
+++ b/modules/pam_unix/passverify.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright information at end of file.
+ */
+
+#include <sys/types.h>
+#include <pwd.h>
+#include <security/pam_modules.h>
+
+#define PAM_UNIX_RUN_HELPER PAM_CRED_INSUFFICIENT
+
+#define OLD_PASSWORDS_FILE "/etc/security/opasswd"
+
+int
+is_pwd_shadowed(const struct passwd *pwd);
+
+char *
+crypt_md5_wrapper(const char *pass_new);
+
+int
+unix_selinux_confined(void);
+
+int
+lock_pwdf(void);
+
+void
+unlock_pwdf(void);
+
+#ifdef HELPER_COMPILE
+int
+save_old_password(const char *forwho, const char *oldpass,
+ int howmany);
+#else
+int
+save_old_password(pam_handle_t *pamh, const char *forwho, const char *oldpass,
+ int howmany);
+#endif
+
+#ifdef HELPER_COMPILE
+void
+helper_log_err(int err, const char *format,...);
+
+int
+helper_verify_password(const char *name, const char *p, int nullok);
+
+void
+setup_signals(void);
+
+char *
+getuidname(uid_t uid);
+
+#endif
+
+#ifdef HELPER_COMPILE
+#define PAMH_ARG_DECL(fname, ...) fname(__VA_ARGS__)
+#define PAMH_ARG(...) __VA_ARGS__
+#else
+#define PAMH_ARG_DECL(fname, ...) fname(pam_handle_t *pamh, __VA_ARGS__)
+#define PAMH_ARG(...) pamh, __VA_ARGS__
+#endif
+
+PAMH_ARG_DECL(int verify_pwd_hash,
+ const char *p, char *hash, unsigned int nullok);
+
+PAMH_ARG_DECL(char * create_password_hash,
+ const char *password, unsigned long long ctrl, int rounds);
+
+PAMH_ARG_DECL(int get_account_info,
+ const char *name, struct passwd **pwd, struct spwd **spwdent);
+
+PAMH_ARG_DECL(int get_pwd_hash,
+ const char *name, struct passwd **pwd, char **hash);
+
+PAMH_ARG_DECL(int check_shadow_expiry,
+ struct spwd *spent, int *daysleft);
+
+PAMH_ARG_DECL(int unix_update_passwd,
+ const char *forwho, const char *towhat);
+
+PAMH_ARG_DECL(int unix_update_shadow,
+ const char *forwho, char *towhat);
+
+/* ****************************************************************** *
+ * Copyright (c) Red Hat, Inc. 2007.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c
new file mode 100644
index 0000000..27ca712
--- /dev/null
+++ b/modules/pam_unix/support.c
@@ -0,0 +1,893 @@
+/*
+ * Copyright information at end of file.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include <pwd.h>
+#include <shadow.h>
+#include <limits.h>
+#include <utmp.h>
+#include <errno.h>
+#include <signal.h>
+#include <ctype.h>
+#include <syslog.h>
+#include <sys/resource.h>
+#ifdef HAVE_RPCSVC_YPCLNT_H
+#include <rpcsvc/ypclnt.h>
+#endif
+
+#include <security/_pam_macros.h>
+#include <security/pam_modules.h>
+#include <security/pam_ext.h>
+#include <security/pam_modutil.h>
+
+#include "pam_cc_compat.h"
+#include "pam_inline.h"
+#include "support.h"
+#include "passverify.h"
+
+/* this is a front-end for module-application conversations */
+
+int _make_remark(pam_handle_t * pamh, unsigned long long ctrl,
+ int type, const char *text)
+{
+ int retval = PAM_SUCCESS;
+
+ if (off(UNIX__QUIET, ctrl)) {
+ retval = pam_prompt(pamh, type, NULL, "%s", text);
+ }
+ return retval;
+}
+
+/*
+ * set the control flags for the UNIX module.
+ */
+
+unsigned long long _set_ctrl(pam_handle_t *pamh, int flags, int *remember,
+ int *rounds, int *pass_min_len, int argc,
+ const char **argv)
+{
+ unsigned long long ctrl;
+ char *val;
+ int j;
+
+ D(("called."));
+
+ ctrl = UNIX_DEFAULTS; /* the default selection of options */
+
+ /* set some flags manually */
+
+ if (getuid() == 0 && !(flags & PAM_CHANGE_EXPIRED_AUTHTOK)) {
+ D(("IAMROOT"));
+ set(UNIX__IAMROOT, ctrl);
+ }
+ if (flags & PAM_UPDATE_AUTHTOK) {
+ D(("UPDATE_AUTHTOK"));
+ set(UNIX__UPDATE, ctrl);
+ }
+ if (flags & PAM_PRELIM_CHECK) {
+ D(("PRELIM_CHECK"));
+ set(UNIX__PRELIM, ctrl);
+ }
+ if (flags & PAM_SILENT) {
+ D(("SILENT"));
+ set(UNIX__QUIET, ctrl);
+ }
+
+ /* preset encryption method with value from /etc/login.defs */
+ val = pam_modutil_search_key(pamh, LOGIN_DEFS, "ENCRYPT_METHOD");
+ if (val) {
+ for (j = 0; j < UNIX_CTRLS_; ++j) {
+ if (unix_args[j].token && unix_args[j].is_hash_algo
+ && !strncasecmp(val, unix_args[j].token, strlen(unix_args[j].token))) {
+ break;
+ }
+ }
+ if (j >= UNIX_CTRLS_) {
+ pam_syslog(pamh, LOG_WARNING, "unrecognized ENCRYPT_METHOD value [%s]", val);
+ } else {
+ ctrl &= unix_args[j].mask; /* for turning things off */
+ ctrl |= unix_args[j].flag; /* for turning things on */
+ }
+ free (val);
+
+ /* read number of rounds for crypt algo */
+ if (rounds && (on(UNIX_SHA256_PASS, ctrl) || on(UNIX_SHA512_PASS, ctrl))) {
+ val = pam_modutil_search_key(pamh, LOGIN_DEFS, "SHA_CRYPT_MAX_ROUNDS");
+
+ if (val) {
+ *rounds = strtol(val, NULL, 10);
+ set(UNIX_ALGO_ROUNDS, ctrl);
+ free (val);
+ }
+ }
+ }
+
+ /* now parse the arguments to this module */
+
+ for (; argc-- > 0; ++argv) {
+ const char *str = NULL;
+
+ D(("pam_unix arg: %s", *argv));
+
+ for (j = 0; j < UNIX_CTRLS_; ++j) {
+ if (unix_args[j].token
+ && (str = pam_str_skip_prefix_len(*argv,
+ unix_args[j].token,
+ strlen(unix_args[j].token))) != NULL) {
+ break;
+ }
+ }
+
+ if (str == NULL) {
+ pam_syslog(pamh, LOG_ERR,
+ "unrecognized option [%s]", *argv);
+ } else {
+ /* special cases */
+ if (j == UNIX_REMEMBER_PASSWD) {
+ if (remember == NULL) {
+ pam_syslog(pamh, LOG_ERR,
+ "option remember not allowed for this module type");
+ continue;
+ }
+ *remember = strtol(str, NULL, 10);
+ if ((*remember == INT_MIN) || (*remember == INT_MAX))
+ *remember = -1;
+ if (*remember > 400)
+ *remember = 400;
+ } else if (j == UNIX_MIN_PASS_LEN) {
+ if (pass_min_len == NULL) {
+ pam_syslog(pamh, LOG_ERR,
+ "option minlen not allowed for this module type");
+ continue;
+ }
+ *pass_min_len = atoi(str);
+ } else if (j == UNIX_ALGO_ROUNDS) {
+ if (rounds == NULL) {
+ pam_syslog(pamh, LOG_ERR,
+ "option rounds not allowed for this module type");
+ continue;
+ }
+ *rounds = strtol(str, NULL, 10);
+ }
+
+ ctrl &= unix_args[j].mask; /* for turning things off */
+ ctrl |= unix_args[j].flag; /* for turning things on */
+ }
+ }
+
+ if (UNIX_DES_CRYPT(ctrl)
+ && pass_min_len && *pass_min_len > 8)
+ {
+ pam_syslog (pamh, LOG_NOTICE, "Password minlen reset to 8 characters");
+ *pass_min_len = 8;
+ }
+
+ if (flags & PAM_DISALLOW_NULL_AUTHTOK) {
+ D(("DISALLOW_NULL_AUTHTOK"));
+ set(UNIX__NONULL, ctrl);
+ }
+
+ /* Set default rounds for blowfish, gost-yescrypt and yescrypt */
+ if (off(UNIX_ALGO_ROUNDS, ctrl) && rounds != NULL) {
+ if (on(UNIX_BLOWFISH_PASS, ctrl) ||
+ on(UNIX_GOST_YESCRYPT_PASS, ctrl) ||
+ on(UNIX_YESCRYPT_PASS, ctrl)) {
+ *rounds = 5;
+ set(UNIX_ALGO_ROUNDS, ctrl);
+ }
+ }
+
+ /* Enforce sane "rounds" values */
+ if (on(UNIX_ALGO_ROUNDS, ctrl)) {
+ if (on(UNIX_GOST_YESCRYPT_PASS, ctrl) ||
+ on(UNIX_YESCRYPT_PASS, ctrl)) {
+ if (*rounds < 3 || *rounds > 11)
+ *rounds = 5;
+ } else if (on(UNIX_BLOWFISH_PASS, ctrl)) {
+ if (*rounds < 4 || *rounds > 31)
+ *rounds = 5;
+ } else if (on(UNIX_SHA256_PASS, ctrl) || on(UNIX_SHA512_PASS, ctrl)) {
+ if ((*rounds < 1000) || (*rounds == INT_MAX)) {
+ /* don't care about bogus values */
+ *rounds = 0;
+ unset(UNIX_ALGO_ROUNDS, ctrl);
+ } else if (*rounds >= 10000000) {
+ *rounds = 9999999;
+ }
+ }
+ }
+
+ /* auditing is a more sensitive version of debug */
+
+ if (on(UNIX_AUDIT, ctrl)) {
+ set(UNIX_DEBUG, ctrl);
+ }
+ /* return the set of flags */
+
+ D(("done."));
+ return ctrl;
+}
+
+/* ************************************************************** *
+ * Useful non-trivial functions *
+ * ************************************************************** */
+
+ /*
+ * the following is used to keep track of the number of times a user fails
+ * to authenticate themself.
+ */
+
+#define FAIL_PREFIX "-UN*X-FAIL-"
+#define UNIX_MAX_RETRIES 3
+
+struct _pam_failed_auth {
+ char *user; /* user that's failed to be authenticated */
+ char *name; /* attempt from user with name */
+ int uid; /* uid of calling user */
+ int euid; /* euid of calling process */
+ int count; /* number of failures so far */
+};
+
+#ifndef PAM_DATA_REPLACE
+#error "Need to get an updated libpam 0.52 or better"
+#endif
+
+static void _cleanup_failures(pam_handle_t * pamh, void *fl, int err)
+{
+ int quiet;
+ const void *service = NULL;
+ const void *ruser = NULL;
+ const void *rhost = NULL;
+ const void *tty = NULL;
+ struct _pam_failed_auth *failure;
+
+ D(("called"));
+
+ quiet = err & PAM_DATA_SILENT; /* should we log something? */
+ err &= PAM_DATA_REPLACE; /* are we just replacing data? */
+ failure = (struct _pam_failed_auth *) fl;
+
+ if (failure != NULL) {
+
+ if (!quiet && !err) { /* under advisement from Sun,may go away */
+
+ /* log the number of authentication failures */
+ if (failure->count > 1) {
+ (void) pam_get_item(pamh, PAM_SERVICE,
+ &service);
+ (void) pam_get_item(pamh, PAM_RUSER,
+ &ruser);
+ (void) pam_get_item(pamh, PAM_RHOST,
+ &rhost);
+ (void) pam_get_item(pamh, PAM_TTY,
+ &tty);
+ pam_syslog(pamh, LOG_NOTICE,
+ "%d more authentication failure%s; "
+ "logname=%s uid=%d euid=%d "
+ "tty=%s ruser=%s rhost=%s "
+ "%s%s",
+ failure->count - 1, failure->count == 2 ? "" : "s",
+ failure->name, failure->uid, failure->euid,
+ tty ? (const char *)tty : "", ruser ? (const char *)ruser : "",
+ rhost ? (const char *)rhost : "",
+ (failure->user && failure->user[0] != '\0')
+ ? " user=" : "", failure->user
+ );
+
+ if (failure->count > UNIX_MAX_RETRIES) {
+ pam_syslog(pamh, LOG_NOTICE,
+ "service(%s) ignoring max retries; %d > %d",
+ service == NULL ? "**unknown**" : (const char *)service,
+ failure->count,
+ UNIX_MAX_RETRIES);
+ }
+ }
+ }
+ _pam_delete(failure->user); /* tidy up */
+ _pam_delete(failure->name); /* tidy up */
+ free(failure);
+ }
+}
+
+/*
+ * _unix_getpwnam() searches only /etc/passwd and NIS to find user information
+ */
+static void _unix_cleanup(pam_handle_t *pamh UNUSED, void *data, int error_status UNUSED)
+{
+ free(data);
+}
+
+int _unix_getpwnam(pam_handle_t *pamh, const char *name,
+ int files, int nis, struct passwd **ret)
+{
+ FILE *passwd;
+ char buf[16384];
+ int matched = 0, buflen;
+ char *slogin, *spasswd, *suid, *sgid, *sgecos, *shome, *sshell, *p;
+
+ memset(buf, 0, sizeof(buf));
+
+ if (!matched && files) {
+ int userlen = strlen(name);
+ passwd = fopen("/etc/passwd", "r");
+ if (passwd != NULL) {
+ while (fgets(buf, sizeof(buf), passwd) != NULL) {
+ if ((buf[userlen] == ':') &&
+ (strncmp(name, buf, userlen) == 0)) {
+ p = buf + strlen(buf) - 1;
+ while (isspace(*p) && (p >= buf)) {
+ *p-- = '\0';
+ }
+ matched = 1;
+ break;
+ }
+ }
+ fclose(passwd);
+ }
+ }
+
+#if defined(HAVE_YP_GET_DEFAULT_DOMAIN) && defined (HAVE_YP_BIND) && defined (HAVE_YP_MATCH) && defined (HAVE_YP_UNBIND)
+ if (!matched && nis) {
+ char *userinfo = NULL, *domain = NULL;
+ int len = 0, i;
+ len = yp_get_default_domain(&domain);
+ if (len == YPERR_SUCCESS) {
+ len = yp_bind(domain);
+ }
+ if (len == YPERR_SUCCESS) {
+ i = yp_match(domain, "passwd.byname", name,
+ strlen(name), &userinfo, &len);
+ yp_unbind(domain);
+ if ((i == YPERR_SUCCESS) && ((size_t)len < sizeof(buf))) {
+ strncpy(buf, userinfo, sizeof(buf) - 1);
+ buf[sizeof(buf) - 1] = '\0';
+ matched = 1;
+ }
+ }
+ }
+#else
+ /* we don't have NIS support, make compiler happy. */
+ (void) nis;
+#endif
+
+ if (matched && (ret != NULL)) {
+ *ret = NULL;
+
+ slogin = buf;
+
+ spasswd = strchr(slogin, ':');
+ if (spasswd == NULL) {
+ return matched;
+ }
+ *spasswd++ = '\0';
+
+ suid = strchr(spasswd, ':');
+ if (suid == NULL) {
+ return matched;
+ }
+ *suid++ = '\0';
+
+ sgid = strchr(suid, ':');
+ if (sgid == NULL) {
+ return matched;
+ }
+ *sgid++ = '\0';
+
+ sgecos = strchr(sgid, ':');
+ if (sgecos == NULL) {
+ return matched;
+ }
+ *sgecos++ = '\0';
+
+ shome = strchr(sgecos, ':');
+ if (shome == NULL) {
+ return matched;
+ }
+ *shome++ = '\0';
+
+ sshell = strchr(shome, ':');
+ if (sshell == NULL) {
+ return matched;
+ }
+ *sshell++ = '\0';
+
+ buflen = sizeof(struct passwd) +
+ strlen(slogin) + 1 +
+ strlen(spasswd) + 1 +
+ strlen(sgecos) + 1 +
+ strlen(shome) + 1 +
+ strlen(sshell) + 1;
+ *ret = malloc(buflen);
+ if (*ret == NULL) {
+ return matched;
+ }
+ memset(*ret, '\0', buflen);
+
+ (*ret)->pw_uid = strtol(suid, &p, 10);
+ if ((strlen(suid) == 0) || (*p != '\0')) {
+ free(*ret);
+ *ret = NULL;
+ return matched;
+ }
+
+ (*ret)->pw_gid = strtol(sgid, &p, 10);
+ if ((strlen(sgid) == 0) || (*p != '\0')) {
+ free(*ret);
+ *ret = NULL;
+ return matched;
+ }
+
+ p = ((char*)(*ret)) + sizeof(struct passwd);
+ (*ret)->pw_name = strcpy(p, slogin);
+ p += strlen(p) + 1;
+ (*ret)->pw_passwd = strcpy(p, spasswd);
+ p += strlen(p) + 1;
+ (*ret)->pw_gecos = strcpy(p, sgecos);
+ p += strlen(p) + 1;
+ (*ret)->pw_dir = strcpy(p, shome);
+ p += strlen(p) + 1;
+ (*ret)->pw_shell = strcpy(p, sshell);
+
+ snprintf(buf, sizeof(buf), "_pam_unix_getpwnam_%s", name);
+
+ if (pam_set_data(pamh, buf,
+ *ret, _unix_cleanup) != PAM_SUCCESS) {
+ free(*ret);
+ *ret = NULL;
+ }
+ }
+
+ return matched;
+}
+
+/*
+ * _unix_comsefromsource() is a quick check to see if information about a given
+ * user comes from a particular source (just files and nis for now)
+ *
+ */
+int _unix_comesfromsource(pam_handle_t *pamh,
+ const char *name, int files, int nis)
+{
+ return _unix_getpwnam(pamh, name, files, nis, NULL);
+}
+
+/*
+ * verify the password of a user
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd,
+ unsigned long long ctrl, const char *user)
+{
+ int retval, child, fds[2];
+ struct sigaction newsa, oldsa;
+
+ D(("called."));
+ /* create a pipe for the password */
+ if (pipe(fds) != 0) {
+ D(("could not make pipe"));
+ return PAM_AUTH_ERR;
+ }
+
+ if (off(UNIX_NOREAP, ctrl)) {
+ /*
+ * This code arranges that the demise of the child does not cause
+ * the application to receive a signal it is not expecting - which
+ * may kill the application or worse.
+ *
+ * The "noreap" module argument is provided so that the admin can
+ * override this behavior.
+ */
+ memset(&newsa, '\0', sizeof(newsa));
+ newsa.sa_handler = SIG_DFL;
+ sigaction(SIGCHLD, &newsa, &oldsa);
+ }
+
+ /* fork */
+ child = fork();
+ if (child == 0) {
+ static char *envp[] = { NULL };
+ const char *args[] = { NULL, NULL, NULL, NULL };
+
+ /* XXX - should really tidy up PAM here too */
+
+ /* reopen stdin as pipe */
+ if (dup2(fds[0], STDIN_FILENO) != STDIN_FILENO) {
+ pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", "stdin");
+ _exit(PAM_AUTHINFO_UNAVAIL);
+ }
+
+ if (pam_modutil_sanitize_helper_fds(pamh, PAM_MODUTIL_IGNORE_FD,
+ PAM_MODUTIL_PIPE_FD,
+ PAM_MODUTIL_PIPE_FD) < 0) {
+ _exit(PAM_AUTHINFO_UNAVAIL);
+ }
+
+ if (geteuid() == 0) {
+ /* must set the real uid to 0 so the helper will not error
+ out if pam is called from setuid binary (su, sudo...) */
+ if (setuid(0) == -1) {
+ D(("setuid failed"));
+ _exit(PAM_AUTHINFO_UNAVAIL);
+ }
+ }
+
+ /* exec binary helper */
+ args[0] = CHKPWD_HELPER;
+ args[1] = user;
+ if (off(UNIX__NONULL, ctrl)) { /* this means we've succeeded */
+ args[2]="nullok";
+ } else {
+ args[2]="nonull";
+ }
+
+ DIAG_PUSH_IGNORE_CAST_QUAL;
+ execve(CHKPWD_HELPER, (char *const *) args, envp);
+ DIAG_POP_IGNORE_CAST_QUAL;
+
+ /* should not get here: exit with error */
+ D(("helper binary is not available"));
+ _exit(PAM_AUTHINFO_UNAVAIL);
+ } else if (child > 0) {
+ /* wait for child */
+ /* if the stored password is NULL */
+ int rc=0;
+ if (passwd != NULL) { /* send the password to the child */
+ int len = strlen(passwd);
+
+ if (len > PAM_MAX_RESP_SIZE)
+ len = PAM_MAX_RESP_SIZE;
+ if (write(fds[1], passwd, len) == -1 ||
+ write(fds[1], "", 1) == -1) {
+ pam_syslog (pamh, LOG_ERR, "Cannot send password to helper: %m");
+ retval = PAM_AUTH_ERR;
+ }
+ passwd = NULL;
+ } else { /* blank password */
+ if (write(fds[1], "", 1) == -1) {
+ pam_syslog (pamh, LOG_ERR, "Cannot send password to helper: %m");
+ retval = PAM_AUTH_ERR;
+ }
+ }
+ close(fds[0]); /* close here to avoid possible SIGPIPE above */
+ close(fds[1]);
+ /* wait for helper to complete: */
+ while ((rc=waitpid(child, &retval, 0)) < 0 && errno == EINTR);
+ if (rc<0) {
+ pam_syslog(pamh, LOG_ERR, "unix_chkpwd waitpid returned %d: %m", rc);
+ retval = PAM_AUTH_ERR;
+ } else if (!WIFEXITED(retval)) {
+ pam_syslog(pamh, LOG_ERR, "unix_chkpwd abnormal exit: %d", retval);
+ retval = PAM_AUTH_ERR;
+ } else {
+ retval = WEXITSTATUS(retval);
+ }
+ } else {
+ D(("fork failed"));
+ close(fds[0]);
+ close(fds[1]);
+ retval = PAM_AUTH_ERR;
+ }
+
+ if (off(UNIX_NOREAP, ctrl)) {
+ sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */
+ }
+
+ D(("returning %d", retval));
+ return retval;
+}
+
+/*
+ * _unix_blankpasswd() is a quick check for a blank password
+ *
+ * returns TRUE if user does not have a password
+ * - to avoid prompting for one in such cases (CG)
+ */
+
+int
+_unix_blankpasswd (pam_handle_t *pamh, unsigned long long ctrl, const char *name)
+{
+ struct passwd *pwd = NULL;
+ char *salt = NULL;
+ int daysleft;
+ int retval;
+ int blank = 0;
+ int execloop;
+ int nonexistent_check = 1;
+
+ D(("called"));
+
+ /*
+ * This function does not have to be too smart if something goes
+ * wrong, return FALSE and let this case to be treated somewhere
+ * else (CG)
+ */
+
+ if (on(UNIX_NULLRESETOK, ctrl)) {
+ retval = _unix_verify_user(pamh, ctrl, name, &daysleft);
+ if (retval == PAM_NEW_AUTHTOK_REQD) {
+ /* password reset is enforced, allow authentication with empty password */
+ pam_syslog(pamh, LOG_DEBUG, "user [%s] has expired blank password, enabling nullok", name);
+ set(UNIX__NULLOK, ctrl);
+ }
+ }
+
+ if (on(UNIX__NONULL, ctrl))
+ return 0; /* will fail but don't let on yet */
+
+ /* UNIX passwords area */
+
+ /*
+ * Execute this loop twice: one checking the password hash of an existing
+ * user and another one for a non-existing user. This way the runtimes
+ * are equal, making it more difficult to differentiate existing from
+ * non-existing users.
+ */
+ for (execloop = 0; execloop < 2; ++execloop) {
+ retval = get_pwd_hash(pamh, name, &pwd, &salt);
+
+ if (retval == PAM_UNIX_RUN_HELPER) {
+ if (_unix_run_helper_binary(pamh, NULL, ctrl, name) == PAM_SUCCESS)
+ blank = nonexistent_check;
+ } else if (retval == PAM_USER_UNKNOWN) {
+ name = "root";
+ nonexistent_check = 0;
+ continue;
+ } else if (salt != NULL) {
+ if (strlen(salt) == 0)
+ blank = nonexistent_check;
+ }
+ name = "pam_unix_non_existent:";
+ /* non-existent user check will not affect the blank value */
+ }
+
+ /* tidy up */
+ if (salt)
+ _pam_delete(salt);
+
+ return blank;
+}
+
+int _unix_verify_password(pam_handle_t * pamh, const char *name
+ ,const char *p, unsigned long long ctrl)
+{
+ struct passwd *pwd = NULL;
+ char *salt = NULL;
+ char *data_name;
+ char pw[PAM_MAX_RESP_SIZE + 1];
+ int retval;
+
+
+ D(("called"));
+
+#ifdef HAVE_PAM_FAIL_DELAY
+ if (off(UNIX_NODELAY, ctrl)) {
+ D(("setting delay"));
+ (void) pam_fail_delay(pamh, 2000000); /* 2 sec delay for on failure */
+ }
+#endif
+
+ /* locate the entry for this user */
+
+ D(("locating user's record"));
+
+ retval = get_pwd_hash(pamh, name, &pwd, &salt);
+
+ data_name = (char *) malloc(sizeof(FAIL_PREFIX) + strlen(name));
+ if (data_name == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "no memory for data-name");
+ } else {
+ strcpy(data_name, FAIL_PREFIX);
+ strcpy(data_name + sizeof(FAIL_PREFIX) - 1, name);
+ }
+
+ if (p != NULL && strlen(p) > PAM_MAX_RESP_SIZE) {
+ memset(pw, 0, sizeof(pw));
+ p = strncpy(pw, p, sizeof(pw) - 1);
+ }
+
+ if (retval != PAM_SUCCESS) {
+ if (retval == PAM_UNIX_RUN_HELPER) {
+ D(("running helper binary"));
+ retval = _unix_run_helper_binary(pamh, p, ctrl, name);
+ } else {
+ D(("user's record unavailable"));
+ p = NULL;
+ if (on(UNIX_AUDIT, ctrl)) {
+ /* this might be a typo and the user has given a password
+ instead of a username. Careful with this. */
+ pam_syslog(pamh, LOG_NOTICE,
+ "check pass; user (%s) unknown", name);
+ } else {
+ name = NULL;
+ if (on(UNIX_DEBUG, ctrl) || pwd == NULL) {
+ pam_syslog(pamh, LOG_NOTICE,
+ "check pass; user unknown");
+ } else {
+ /* don't log failure as another pam module can succeed */
+ goto cleanup;
+ }
+ }
+ }
+ } else {
+ retval = verify_pwd_hash(pamh, p, salt, off(UNIX__NONULL, ctrl));
+ }
+
+ if (retval == PAM_SUCCESS) {
+ if (data_name) /* reset failures */
+ pam_set_data(pamh, data_name, NULL, _cleanup_failures);
+ } else {
+ if (data_name != NULL) {
+ struct _pam_failed_auth *new = NULL;
+ const struct _pam_failed_auth *old = NULL;
+
+ /* get a failure recorder */
+
+ new = (struct _pam_failed_auth *)
+ malloc(sizeof(struct _pam_failed_auth));
+
+ if (new != NULL) {
+
+ const char *login_name;
+ const void *void_old;
+
+
+ login_name = pam_modutil_getlogin(pamh);
+ if (login_name == NULL) {
+ login_name = "";
+ }
+
+ new->user = strdup(name ? name : "");
+ new->uid = getuid();
+ new->euid = geteuid();
+ new->name = strdup(login_name);
+
+ /* any previous failures for this user ? */
+ if (pam_get_data(pamh, data_name, &void_old)
+ == PAM_SUCCESS)
+ old = void_old;
+ else
+ old = NULL;
+
+ if (old != NULL) {
+ new->count = old->count + 1;
+ if (new->count >= UNIX_MAX_RETRIES) {
+ retval = PAM_MAXTRIES;
+ }
+ } else {
+ const void *service=NULL;
+ const void *ruser=NULL;
+ const void *rhost=NULL;
+ const void *tty=NULL;
+
+ (void) pam_get_item(pamh, PAM_SERVICE,
+ &service);
+ (void) pam_get_item(pamh, PAM_RUSER,
+ &ruser);
+ (void) pam_get_item(pamh, PAM_RHOST,
+ &rhost);
+ (void) pam_get_item(pamh, PAM_TTY,
+ &tty);
+
+ pam_syslog(pamh, LOG_NOTICE,
+ "authentication failure; "
+ "logname=%s uid=%d euid=%d "
+ "tty=%s ruser=%s rhost=%s "
+ "%s%s",
+ new->name, new->uid, new->euid,
+ tty ? (const char *)tty : "",
+ ruser ? (const char *)ruser : "",
+ rhost ? (const char *)rhost : "",
+ (new->user && new->user[0] != '\0')
+ ? " user=" : "",
+ new->user
+ );
+ new->count = 1;
+ }
+
+ pam_set_data(pamh, data_name, new, _cleanup_failures);
+
+ } else {
+ pam_syslog(pamh, LOG_CRIT,
+ "no memory for failure recorder");
+ }
+ }
+ }
+
+cleanup:
+ memset(pw, 0, sizeof(pw)); /* clear memory of the password */
+ if (data_name)
+ _pam_delete(data_name);
+ if (salt)
+ _pam_delete(salt);
+
+ D(("done [%d].", retval));
+
+ return retval;
+}
+
+int
+_unix_verify_user(pam_handle_t *pamh,
+ unsigned long long ctrl,
+ const char *name,
+ int *daysleft)
+{
+ int retval;
+ struct spwd *spent;
+ struct passwd *pwent;
+
+ retval = get_account_info(pamh, name, &pwent, &spent);
+ if (retval == PAM_USER_UNKNOWN) {
+ pam_syslog(pamh, LOG_ERR,
+ "could not identify user (from getpwnam(%s))",
+ name);
+ return retval;
+ }
+
+ if (retval == PAM_SUCCESS && spent == NULL)
+ return PAM_SUCCESS;
+
+ if (retval == PAM_UNIX_RUN_HELPER) {
+ retval = _unix_run_verify_binary(pamh, ctrl, name, daysleft);
+ if (retval == PAM_AUTHINFO_UNAVAIL &&
+ on(UNIX_BROKEN_SHADOW, ctrl))
+ return PAM_SUCCESS;
+ } else if (retval != PAM_SUCCESS) {
+ if (on(UNIX_BROKEN_SHADOW,ctrl))
+ return PAM_SUCCESS;
+ else
+ return retval;
+ } else
+ retval = check_shadow_expiry(pamh, spent, daysleft);
+
+ return retval;
+}
+
+/* ****************************************************************** *
+ * Copyright (c) Jan Rękorajski 1999.
+ * Copyright (c) Andrew G. Morgan 1996-8.
+ * Copyright (c) Alex O. Yuriev, 1996.
+ * Copyright (c) Cristian Gafton 1996.
+ * Copyright (c) Red Hat, Inc. 2007.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/modules/pam_unix/support.h b/modules/pam_unix/support.h
new file mode 100644
index 0000000..19754dc
--- /dev/null
+++ b/modules/pam_unix/support.h
@@ -0,0 +1,182 @@
+/*
+ * $Id$
+ */
+
+#ifndef _PAM_UNIX_SUPPORT_H
+#define _PAM_UNIX_SUPPORT_H
+
+#include <pwd.h>
+
+/*
+ * File to read value of ENCRYPT_METHOD from.
+ */
+#define LOGIN_DEFS "/etc/login.defs"
+
+
+/*
+ * here is the string to inform the user that the new passwords they
+ * typed were not the same.
+ */
+
+/* type definition for the control options */
+
+typedef struct {
+ const char *token;
+ unsigned long long mask; /* shall assume 64 bits of flags */
+ unsigned long long flag;
+ unsigned int is_hash_algo;
+} UNIX_Ctrls;
+
+/*
+ * macro to determine if a given flag is on
+ */
+
+#define on(x,ctrl) (unix_args[x].flag & ctrl)
+
+/*
+ * macro to determine that a given flag is NOT on
+ */
+
+#define off(x,ctrl) (!on(x,ctrl))
+
+/*
+ * macro to turn on/off a ctrl flag manually
+ */
+
+#define set(x,ctrl) (ctrl = ((ctrl)&unix_args[x].mask)|unix_args[x].flag)
+#define unset(x,ctrl) (ctrl &= ~(unix_args[x].flag))
+
+/* the generic mask */
+
+#define _ALL_ON_ (~0ULL)
+
+/* end of macro definitions definitions for the control flags */
+
+/* ****************************************************************** *
+ * ctrl flags proper..
+ */
+
+/*
+ * here are the various options recognized by the unix module. They
+ * are enumerated here and then defined below. Internal arguments are
+ * given NULL tokens.
+ */
+
+#define UNIX__OLD_PASSWD 0 /* internal */
+#define UNIX__VERIFY_PASSWD 1 /* internal */
+#define UNIX__IAMROOT 2 /* internal */
+
+#define UNIX_AUDIT 3 /* print more things than debug..
+ some information may be sensitive */
+#define UNIX_USE_FIRST_PASS 4
+#define UNIX_TRY_FIRST_PASS 5
+#define UNIX_AUTHTOK_TYPE 6 /* TYPE for pam_get_authtok() */
+
+#define UNIX__PRELIM 7 /* internal */
+#define UNIX__UPDATE 8 /* internal */
+#define UNIX__NONULL 9 /* internal */
+#define UNIX__QUIET 10 /* internal */
+#define UNIX_USE_AUTHTOK 11 /* insist on reading PAM_AUTHTOK */
+#define UNIX_SHADOW 12 /* signal shadow on */
+#define UNIX_MD5_PASS 13 /* force the use of MD5 passwords */
+#define UNIX__NULLOK 14 /* Null token ok */
+#define UNIX_DEBUG 15 /* send more info to syslog(3) */
+#define UNIX_NODELAY 16 /* admin does not want a fail-delay */
+#define UNIX_NIS 17 /* wish to use NIS for pwd */
+#define UNIX_BIGCRYPT 18 /* use DEC-C2 crypt()^x function */
+#define UNIX_LIKE_AUTH 19 /* need to auth for setcred to work */
+#define UNIX_REMEMBER_PASSWD 20 /* Remember N previous passwords */
+#define UNIX_NOREAP 21 /* don't reap child process */
+#define UNIX_BROKEN_SHADOW 22 /* ignore errors reading password aging
+ * information during acct management */
+#define UNIX_SHA256_PASS 23 /* new password hashes will use SHA256 */
+#define UNIX_SHA512_PASS 24 /* new password hashes will use SHA512 */
+#define UNIX_ALGO_ROUNDS 25 /* optional number of rounds for new
+ password hash algorithms */
+#define UNIX_BLOWFISH_PASS 26 /* new password hashes will use blowfish */
+#define UNIX_MIN_PASS_LEN 27 /* min length for password */
+#define UNIX_QUIET 28 /* Don't print informational messages */
+#define UNIX_NO_PASS_EXPIRY 29 /* Don't check for password expiration if not used for authentication */
+#define UNIX_DES 30 /* DES, default */
+#define UNIX_GOST_YESCRYPT_PASS 31 /* new password hashes will use gost-yescrypt */
+#define UNIX_YESCRYPT_PASS 32 /* new password hashes will use yescrypt */
+#define UNIX_NULLRESETOK 33 /* allow empty password if password reset is enforced */
+/* -------------- */
+#define UNIX_CTRLS_ 34 /* number of ctrl arguments defined */
+
+#define UNIX_DES_CRYPT(ctrl) (off(UNIX_MD5_PASS,ctrl)&&off(UNIX_BIGCRYPT,ctrl)&&off(UNIX_SHA256_PASS,ctrl)&&off(UNIX_SHA512_PASS,ctrl)&&off(UNIX_BLOWFISH_PASS,ctrl)&&off(UNIX_GOST_YESCRYPT_PASS,ctrl)&&off(UNIX_YESCRYPT_PASS,ctrl))
+
+static const UNIX_Ctrls unix_args[UNIX_CTRLS_] =
+{
+/* symbol token name ctrl mask ctrl *
+ * --------------------------- -------------------- ------------------------- ---------------- */
+
+/* UNIX__OLD_PASSWD */ {NULL, _ALL_ON_, 01, 0},
+/* UNIX__VERIFY_PASSWD */ {NULL, _ALL_ON_, 02, 0},
+/* UNIX__IAMROOT */ {NULL, _ALL_ON_, 04, 0},
+/* UNIX_AUDIT */ {"audit", _ALL_ON_, 010, 0},
+/* UNIX_USE_FIRST_PASS */ {"use_first_pass", _ALL_ON_^(060ULL), 020, 0},
+/* UNIX_TRY_FIRST_PASS */ {"try_first_pass", _ALL_ON_^(060ULL), 040, 0},
+/* UNIX_AUTHTOK_TYPE */ {"authtok_type=", _ALL_ON_, 0100, 0},
+/* UNIX__PRELIM */ {NULL, _ALL_ON_^(0600ULL), 0200, 0},
+/* UNIX__UPDATE */ {NULL, _ALL_ON_^(0600ULL), 0400, 0},
+/* UNIX__NONULL */ {NULL, _ALL_ON_, 01000, 0},
+/* UNIX__QUIET */ {NULL, _ALL_ON_, 02000, 0},
+/* UNIX_USE_AUTHTOK */ {"use_authtok", _ALL_ON_, 04000, 0},
+/* UNIX_SHADOW */ {"shadow", _ALL_ON_, 010000, 0},
+/* UNIX_MD5_PASS */ {"md5", _ALL_ON_^(015660420000ULL), 020000, 1},
+/* UNIX__NULLOK */ {"nullok", _ALL_ON_^(01000ULL), 0, 0},
+/* UNIX_DEBUG */ {"debug", _ALL_ON_, 040000, 0},
+/* UNIX_NODELAY */ {"nodelay", _ALL_ON_, 0100000, 0},
+/* UNIX_NIS */ {"nis", _ALL_ON_, 0200000, 0},
+/* UNIX_BIGCRYPT */ {"bigcrypt", _ALL_ON_^(015660420000ULL), 0400000, 1},
+/* UNIX_LIKE_AUTH */ {"likeauth", _ALL_ON_, 01000000, 0},
+/* UNIX_REMEMBER_PASSWD */ {"remember=", _ALL_ON_, 02000000, 0},
+/* UNIX_NOREAP */ {"noreap", _ALL_ON_, 04000000, 0},
+/* UNIX_BROKEN_SHADOW */ {"broken_shadow", _ALL_ON_, 010000000, 0},
+/* UNIX_SHA256_PASS */ {"sha256", _ALL_ON_^(015660420000ULL), 020000000, 1},
+/* UNIX_SHA512_PASS */ {"sha512", _ALL_ON_^(015660420000ULL), 040000000, 1},
+/* UNIX_ALGO_ROUNDS */ {"rounds=", _ALL_ON_, 0100000000, 0},
+/* UNIX_BLOWFISH_PASS */ {"blowfish", _ALL_ON_^(015660420000ULL), 0200000000, 1},
+/* UNIX_MIN_PASS_LEN */ {"minlen=", _ALL_ON_, 0400000000, 0},
+/* UNIX_QUIET */ {"quiet", _ALL_ON_, 01000000000, 0},
+/* UNIX_NO_PASS_EXPIRY */ {"no_pass_expiry", _ALL_ON_, 02000000000, 0},
+/* UNIX_DES */ {"des", _ALL_ON_^(015660420000ULL), 0, 1},
+/* UNIX_GOST_YESCRYPT_PASS */ {"gost_yescrypt", _ALL_ON_^(015660420000ULL), 04000000000, 1},
+/* UNIX_YESCRYPT_PASS */ {"yescrypt", _ALL_ON_^(015660420000ULL), 010000000000, 1},
+/* UNIX_NULLRESETOK */ {"nullresetok", _ALL_ON_, 020000000000, 0},
+};
+
+#define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag)
+
+/* use this to free strings. ESPECIALLY password strings */
+
+#define _pam_delete(xx) \
+{ \
+ _pam_overwrite(xx); \
+ _pam_drop(xx); \
+}
+
+extern int _make_remark(pam_handle_t * pamh, unsigned long long ctrl,
+ int type, const char *text);
+extern unsigned long long _set_ctrl(pam_handle_t * pamh, int flags,
+ int *remember, int *rounds,
+ int *pass_min_len,
+ int argc, const char **argv);
+extern int _unix_getpwnam (pam_handle_t *pamh,
+ const char *name, int files, int nis,
+ struct passwd **ret);
+extern int _unix_comesfromsource (pam_handle_t *pamh,
+ const char *name, int files, int nis);
+extern int _unix_blankpasswd(pam_handle_t *pamh, unsigned long long ctrl,
+ const char *name);
+extern int _unix_verify_password(pam_handle_t * pamh, const char *name,
+ const char *p, unsigned long long ctrl);
+
+extern int _unix_verify_user(pam_handle_t *pamh, unsigned long long ctrl,
+ const char *name, int *daysleft);
+
+extern int _unix_run_verify_binary(pam_handle_t *pamh,
+ unsigned long long ctrl,
+ const char *user, int *daysleft);
+#endif /* _PAM_UNIX_SUPPORT_H */
diff --git a/modules/pam_unix/tst-pam_unix b/modules/pam_unix/tst-pam_unix
new file mode 100755
index 0000000..2292280
--- /dev/null
+++ b/modules/pam_unix/tst-pam_unix
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_unix.so
diff --git a/modules/pam_unix/unix_chkpwd.8 b/modules/pam_unix/unix_chkpwd.8
new file mode 100644
index 0000000..93c95bd
--- /dev/null
+++ b/modules/pam_unix/unix_chkpwd.8
@@ -0,0 +1,53 @@
+'\" t
+.\" Title: unix_chkpwd
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "UNIX_CHKPWD" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+unix_chkpwd \- Helper binary that verifies the password of the current user
+.SH "SYNOPSIS"
+.HP \w'\fBunix_chkpwd\fR\ 'u
+\fBunix_chkpwd\fR [\&.\&.\&.]
+.SH "DESCRIPTION"
+.PP
+\fIunix_chkpwd\fR
+is a helper program for the
+\fIpam_unix\fR
+module that verifies the password of the current user\&. It also checks password and account expiration dates in
+\fIshadow\fR\&. It is not intended to be run directly from the command line and logs a security violation if done so\&.
+.PP
+It is typically installed setuid root or setgid shadow\&.
+.PP
+The interface of the helper \- command line options, and input/output data format are internal to the
+\fIpam_unix\fR
+module and it should not be called directly from applications\&.
+.SH "SEE ALSO"
+.PP
+\fBpam_unix\fR(8)
+.SH "AUTHOR"
+.PP
+Written by Andrew Morgan and other various people\&.
diff --git a/modules/pam_unix/unix_chkpwd.8.xml b/modules/pam_unix/unix_chkpwd.8.xml
new file mode 100644
index 0000000..a10dbe3
--- /dev/null
+++ b/modules/pam_unix/unix_chkpwd.8.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="unix_chkpwd">
+
+ <refmeta>
+ <refentrytitle>unix_chkpwd</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="unix_chkpwd-name">
+ <refname>unix_chkpwd</refname>
+ <refpurpose>Helper binary that verifies the password of the current user</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="unix_chkpwd-cmdsynopsis">
+ <command>unix_chkpwd</command>
+ <arg choice="opt">
+ ...
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="unix_chkpwd-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ <emphasis>unix_chkpwd</emphasis> is a helper program for the
+ <emphasis>pam_unix</emphasis> module that verifies the
+ password of the current user. It also checks password and account
+ expiration dates in <emphasis>shadow</emphasis>. It is not intended to
+ be run directly from the command line and logs a security violation if
+ done so.
+ </para>
+
+ <para>
+ It is typically installed setuid root or setgid shadow.
+ </para>
+
+ <para>
+ The interface of the helper - command line options, and input/output
+ data format are internal to the <emphasis>pam_unix</emphasis>
+ module and it should not be called directly from applications.
+ </para>
+ </refsect1>
+
+ <refsect1 id='unix_chkpwd-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam_unix</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='unix_chkpwd-author'>
+ <title>AUTHOR</title>
+ <para>
+ Written by Andrew Morgan and other various people.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_unix/unix_chkpwd.c b/modules/pam_unix/unix_chkpwd.c
new file mode 100644
index 0000000..3931bab
--- /dev/null
+++ b/modules/pam_unix/unix_chkpwd.c
@@ -0,0 +1,246 @@
+/*
+ * This program is designed to run setuid(root) or with sufficient
+ * privilege to read all of the unix password databases. It is designed
+ * to provide a mechanism for the current user (defined by this
+ * process's uid) to verify their own password.
+ *
+ * The password is read from the standard input. The exit status of
+ * this program indicates whether the user is authenticated or not.
+ *
+ * Copyright information is located at the end of the file.
+ *
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <pwd.h>
+#include <shadow.h>
+#include <signal.h>
+#include <time.h>
+#include <errno.h>
+#ifdef HAVE_LIBAUDIT
+#include <libaudit.h>
+#endif
+
+#include <security/_pam_types.h>
+#include <security/_pam_macros.h>
+
+#include "passverify.h"
+#include "pam_inline.h"
+
+static int _check_expiry(const char *uname)
+{
+ struct spwd *spent;
+ struct passwd *pwent;
+ int retval;
+ int daysleft;
+
+ retval = get_account_info(uname, &pwent, &spent);
+ if (retval != PAM_SUCCESS) {
+ helper_log_err(LOG_ERR, "could not obtain user info (%s)", uname);
+ printf("-1\n");
+ return retval;
+ }
+
+ if (spent == NULL) {
+ printf("-1\n");
+ return retval;
+ }
+
+ retval = check_shadow_expiry(spent, &daysleft);
+ printf("%d\n", daysleft);
+ return retval;
+}
+
+#ifdef HAVE_LIBAUDIT
+static int _audit_log(int type, const char *uname, int rc)
+{
+ int audit_fd;
+
+ audit_fd = audit_open();
+ if (audit_fd < 0) {
+ /* You get these error codes only when the kernel doesn't have
+ * audit compiled in. */
+ if (errno == EINVAL || errno == EPROTONOSUPPORT ||
+ errno == EAFNOSUPPORT)
+ return PAM_SUCCESS;
+
+ helper_log_err(LOG_CRIT, "audit_open() failed: %m");
+ return PAM_AUTH_ERR;
+ }
+
+ rc = audit_log_acct_message(audit_fd, type, NULL, "PAM:unix_chkpwd",
+ uname, -1, NULL, NULL, NULL, rc == PAM_SUCCESS);
+ if (rc == -EPERM && geteuid() != 0) {
+ rc = 0;
+ }
+
+ audit_close(audit_fd);
+
+ return rc < 0 ? PAM_AUTH_ERR : PAM_SUCCESS;
+}
+#endif
+
+int main(int argc, char *argv[])
+{
+ char pass[PAM_MAX_RESP_SIZE + 1];
+ char *option;
+ int npass, nullok;
+ int blankpass = 0;
+ int retval = PAM_AUTH_ERR;
+ char *user;
+ char *passwords[] = { pass };
+
+ /*
+ * Catch or ignore as many signal as possible.
+ */
+ setup_signals();
+
+ /*
+ * we establish that this program is running with non-tty stdin.
+ * this is to discourage casual use. It does *NOT* prevent an
+ * intruder from repeatadly running this program to determine the
+ * password of the current user (brute force attack, but one for
+ * which the attacker must already have gained access to the user's
+ * account).
+ */
+
+ if (isatty(STDIN_FILENO) || argc != 3 ) {
+ helper_log_err(LOG_NOTICE
+ ,"inappropriate use of Unix helper binary [UID=%d]"
+ ,getuid());
+#ifdef HAVE_LIBAUDIT
+ _audit_log(AUDIT_ANOM_EXEC, getuidname(getuid()), PAM_SYSTEM_ERR);
+#endif
+ fprintf(stderr
+ ,"This binary is not designed for running in this way\n"
+ "-- the system administrator has been informed\n");
+ sleep(10); /* this should discourage/annoy the user */
+ return PAM_SYSTEM_ERR;
+ }
+
+ /*
+ * Determine what the current user's name is.
+ * We must thus skip the check if the real uid is 0.
+ */
+ if (getuid() == 0) {
+ user=argv[1];
+ }
+ else {
+ user = getuidname(getuid());
+ /* if the caller specifies the username, verify that user
+ matches it */
+ if (user == NULL || strcmp(user, argv[1])) {
+ user = argv[1];
+ /* no match -> permanently change to the real user and proceed */
+ if (setuid(getuid()) != 0)
+ return PAM_AUTH_ERR;
+ }
+ }
+
+ option=argv[2];
+
+ if (strcmp(option, "chkexpiry") == 0)
+ /* Check account information from the shadow file */
+ return _check_expiry(argv[1]);
+ /* read the nullok/nonull option */
+ else if (strcmp(option, "nullok") == 0)
+ nullok = 1;
+ else if (strcmp(option, "nonull") == 0)
+ nullok = 0;
+ else {
+#ifdef HAVE_LIBAUDIT
+ _audit_log(AUDIT_ANOM_EXEC, getuidname(getuid()), PAM_SYSTEM_ERR);
+#endif
+ return PAM_SYSTEM_ERR;
+ }
+ /* read the password from stdin (a pipe from the pam_unix module) */
+
+ npass = pam_read_passwords(STDIN_FILENO, 1, passwords);
+
+ if (npass != 1) { /* is it a valid password? */
+ helper_log_err(LOG_DEBUG, "no password supplied");
+ *pass = '\0';
+ }
+
+ if (*pass == '\0') {
+ blankpass = 1;
+ }
+
+ retval = helper_verify_password(user, pass, nullok);
+
+ memset(pass, '\0', PAM_MAX_RESP_SIZE); /* clear memory of the password */
+
+ /* return pass or fail */
+
+ if (retval != PAM_SUCCESS) {
+ if (!nullok || !blankpass) {
+ /* no need to log blank pass test */
+#ifdef HAVE_LIBAUDIT
+ if (getuid() != 0)
+ _audit_log(AUDIT_USER_AUTH, user, PAM_AUTH_ERR);
+#endif
+ helper_log_err(LOG_NOTICE, "password check failed for user (%s)", user);
+ }
+ /* if helper_verify_password() returned PAM_USER_UNKNOWN, the
+ most appropriate error to propagate to
+ _unix_verify_password() is PAM_AUTHINFO_UNAVAIL; otherwise
+ return general failure */
+ if (retval == PAM_USER_UNKNOWN)
+ return PAM_AUTHINFO_UNAVAIL;
+ else
+ return PAM_AUTH_ERR;
+ } else {
+ if (getuid() != 0) {
+#ifdef HAVE_LIBAUDIT
+ return _audit_log(AUDIT_USER_AUTH, user, PAM_SUCCESS);
+#else
+ return PAM_SUCCESS;
+#endif
+ }
+ return PAM_SUCCESS;
+ }
+}
+
+/*
+ * Copyright (c) Andrew G. Morgan, 1996. All rights reserved
+ * Copyright (c) Red Hat, Inc., 2007,2008. All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/modules/pam_unix/unix_update.8 b/modules/pam_unix/unix_update.8
new file mode 100644
index 0000000..b1f5ac7
--- /dev/null
+++ b/modules/pam_unix/unix_update.8
@@ -0,0 +1,52 @@
+'\" t
+.\" Title: unix_update
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "UNIX_UPDATE" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+unix_update \- Helper binary that updates the password of a given user
+.SH "SYNOPSIS"
+.HP \w'\fBunix_update\fR\ 'u
+\fBunix_update\fR [\&.\&.\&.]
+.SH "DESCRIPTION"
+.PP
+\fIunix_update\fR
+is a helper program for the
+\fIpam_unix\fR
+module that updates the password of a given user\&. It is not intended to be run directly from the command line and logs a security violation if done so\&.
+.PP
+The purpose of the helper is to enable tighter confinement of login and password changing services\&. The helper is thus called only when SELinux is enabled on the system\&.
+.PP
+The interface of the helper \- command line options, and input/output data format are internal to the
+\fIpam_unix\fR
+module and it should not be called directly from applications\&.
+.SH "SEE ALSO"
+.PP
+\fBpam_unix\fR(8)
+.SH "AUTHOR"
+.PP
+Written by Tomas Mraz and other various people\&.
diff --git a/modules/pam_unix/unix_update.8.xml b/modules/pam_unix/unix_update.8.xml
new file mode 100644
index 0000000..6c7467b
--- /dev/null
+++ b/modules/pam_unix/unix_update.8.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="unix_update">
+
+ <refmeta>
+ <refentrytitle>unix_update</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="unix_update-name">
+ <refname>unix_update</refname>
+ <refpurpose>Helper binary that updates the password of a given user</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="unix_update-cmdsynopsis">
+ <command>unix_update</command>
+ <arg choice="opt">
+ ...
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="unix_update-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ <emphasis>unix_update</emphasis> is a helper program for the
+ <emphasis>pam_unix</emphasis> module that updates the
+ password of a given user. It is not intended to be run directly
+ from the command line and logs a security violation if done so.
+ </para>
+
+ <para>
+ The purpose of the helper is to enable tighter confinement of
+ login and password changing services. The helper is thus called only
+ when SELinux is enabled on the system.
+ </para>
+
+ <para>
+ The interface of the helper - command line options, and input/output
+ data format are internal to the <emphasis>pam_unix</emphasis>
+ module and it should not be called directly from applications.
+ </para>
+ </refsect1>
+
+ <refsect1 id='unix_update-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam_unix</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='unix_update-author'>
+ <title>AUTHOR</title>
+ <para>
+ Written by Tomas Mraz and other various people.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_unix/unix_update.c b/modules/pam_unix/unix_update.c
new file mode 100644
index 0000000..3559972
--- /dev/null
+++ b/modules/pam_unix/unix_update.c
@@ -0,0 +1,192 @@
+/*
+ * This program is designed to run with sufficient privilege
+ * to read and write all of the unix password databases.
+ * Its purpose is to allow updating the databases when
+ * SELinux confinement of the caller domain prevents them to
+ * do that themselves.
+ *
+ * The password is read from the standard input. The exit status of
+ * this program indicates whether the password was updated or not.
+ *
+ * Copyright information is located at the end of the file.
+ *
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <pwd.h>
+#include <shadow.h>
+#include <signal.h>
+#include <time.h>
+#include <sys/time.h>
+
+#include <security/_pam_types.h>
+#include <security/_pam_macros.h>
+
+#include "passverify.h"
+#include "pam_inline.h"
+
+static int
+set_password(const char *forwho, const char *shadow, const char *remember)
+{
+ struct passwd *pwd = NULL;
+ int retval;
+ char pass[PAM_MAX_RESP_SIZE + 1];
+ char towhat[PAM_MAX_RESP_SIZE + 1];
+ int npass = 0;
+ /* we don't care about number format errors because the helper
+ should be called internally only */
+ int doshadow = atoi(shadow);
+ int nremember = atoi(remember);
+ char *passwords[] = { pass, towhat };
+
+ /* read the password from stdin (a pipe from the pam_unix module) */
+
+ npass = pam_read_passwords(STDIN_FILENO, 2, passwords);
+
+ if (npass != 2) { /* is it a valid password? */
+ if (npass == 1) {
+ helper_log_err(LOG_DEBUG, "no new password supplied");
+ memset(pass, '\0', PAM_MAX_RESP_SIZE);
+ } else {
+ helper_log_err(LOG_DEBUG, "no valid passwords supplied");
+ }
+ return PAM_AUTHTOK_ERR;
+ }
+
+ if (lock_pwdf() != PAM_SUCCESS)
+ return PAM_AUTHTOK_LOCK_BUSY;
+
+ pwd = getpwnam(forwho);
+
+ if (pwd == NULL) {
+ retval = PAM_USER_UNKNOWN;
+ goto done;
+ }
+
+ /* If real caller uid is not root we must verify that
+ received old pass agrees with the current one.
+ We always allow change from null pass. */
+ if (getuid()) {
+ retval = helper_verify_password(forwho, pass, 1);
+ if (retval != PAM_SUCCESS) {
+ goto done;
+ }
+ }
+
+ /* first, save old password */
+ if (save_old_password(forwho, pass, nremember)) {
+ retval = PAM_AUTHTOK_ERR;
+ goto done;
+ }
+
+ if (doshadow || is_pwd_shadowed(pwd)) {
+ retval = unix_update_shadow(forwho, towhat);
+ if (retval == PAM_SUCCESS)
+ if (!is_pwd_shadowed(pwd))
+ retval = unix_update_passwd(forwho, "x");
+ } else {
+ retval = unix_update_passwd(forwho, towhat);
+ }
+
+done:
+ memset(pass, '\0', PAM_MAX_RESP_SIZE);
+ memset(towhat, '\0', PAM_MAX_RESP_SIZE);
+
+ unlock_pwdf();
+
+ if (retval == PAM_SUCCESS) {
+ return PAM_SUCCESS;
+ } else {
+ return PAM_AUTHTOK_ERR;
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ char *option;
+
+ /*
+ * Catch or ignore as many signal as possible.
+ */
+ setup_signals();
+
+ /*
+ * we establish that this program is running with non-tty stdin.
+ * this is to discourage casual use. It does *NOT* prevent an
+ * intruder from repeatadly running this program to determine the
+ * password of the current user (brute force attack, but one for
+ * which the attacker must already have gained access to the user's
+ * account).
+ */
+
+ if (isatty(STDIN_FILENO) || argc != 5 ) {
+ helper_log_err(LOG_NOTICE
+ ,"inappropriate use of Unix helper binary [UID=%d]"
+ ,getuid());
+ fprintf(stderr
+ ,"This binary is not designed for running in this way\n"
+ "-- the system administrator has been informed\n");
+ sleep(10); /* this should discourage/annoy the user */
+ return PAM_SYSTEM_ERR;
+ }
+
+ /* We must be root to read/update shadow.
+ */
+ if (geteuid() != 0) {
+ return PAM_CRED_INSUFFICIENT;
+ }
+
+ option = argv[2];
+
+ if (strcmp(option, "update") == 0) {
+ /* Attempting to change the password */
+ return set_password(argv[1], argv[3], argv[4]);
+ }
+
+ return PAM_SYSTEM_ERR;
+}
+
+/*
+ * Copyright (c) Andrew G. Morgan, 1996. All rights reserved
+ * Copyright (c) Red Hat, Inc., 2007, 2008. All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/modules/pam_unix/yppasswd.h b/modules/pam_unix/yppasswd.h
new file mode 100644
index 0000000..5f94707
--- /dev/null
+++ b/modules/pam_unix/yppasswd.h
@@ -0,0 +1,51 @@
+/*
+ * yppasswdd
+ * Copyright 1994, 1995, 1996 Olaf Kirch, <okir@lst.de>
+ *
+ * This program is covered by the GNU General Public License, version 2
+ * or later. It is provided in the hope that it is useful. However, the author
+ * disclaims ALL WARRANTIES, expressed or implied. See the GPL for details.
+ *
+ * This file was generated automatically by rpcgen from yppasswd.x, and
+ * editied manually.
+ */
+
+#ifndef _YPPASSWD_H_
+#define _YPPASSWD_H_
+
+#define YPPASSWDPROG ((u_long)100009)
+#define YPPASSWDVERS ((u_long)1)
+#define YPPASSWDPROC_UPDATE ((u_long)1)
+
+/*
+ * The password struct passed by the update call. I renamed it to
+ * xpasswd to avoid a type clash with the one defined in <pwd.h>.
+ */
+#ifndef __sgi
+typedef struct xpasswd {
+ char *pw_name;
+ char *pw_passwd;
+ int pw_uid;
+ int pw_gid;
+ char *pw_gecos;
+ char *pw_dir;
+ char *pw_shell;
+} xpasswd;
+
+#else
+#include <pwd.h>
+typedef struct xpasswd xpasswd;
+#endif
+
+/* The updated password information, plus the old password.
+ */
+typedef struct yppasswd {
+ char *oldpass;
+ xpasswd newpw;
+} yppasswd;
+
+/* XDR encoding/decoding routines */
+bool_t xdr_xpasswd(XDR * xdrs, xpasswd * objp);
+bool_t xdr_yppasswd(XDR * xdrs, yppasswd * objp);
+
+#endif /* _YPPASSWD_H_ */
diff --git a/modules/pam_unix/yppasswd_xdr.c b/modules/pam_unix/yppasswd_xdr.c
new file mode 100644
index 0000000..f2b86a5
--- /dev/null
+++ b/modules/pam_unix/yppasswd_xdr.c
@@ -0,0 +1,40 @@
+/*
+ * yppasswdd
+ * Copyright 1994, 1995, 1996 Olaf Kirch, <okir@lst.de>
+ *
+ * This program is covered by the GNU General Public License, version 2
+ * or later. It is provided in the hope that it is useful. However, the author
+ * disclaims ALL WARRANTIES, expressed or implied. See the GPL for details.
+ *
+ * This file was generated automatically by rpcgen from yppasswd.x, and
+ * editied manually.
+ */
+
+#include "config.h"
+
+#ifdef HAVE_RPC_RPC_H
+
+#include <rpc/rpc.h>
+#include "yppasswd.h"
+
+bool_t
+xdr_xpasswd(XDR * xdrs, xpasswd * objp)
+{
+ return xdr_string(xdrs, &objp->pw_name, ~0)
+ && xdr_string(xdrs, &objp->pw_passwd, ~0)
+ && xdr_int(xdrs, &objp->pw_uid)
+ && xdr_int(xdrs, &objp->pw_gid)
+ && xdr_string(xdrs, &objp->pw_gecos, ~0)
+ && xdr_string(xdrs, &objp->pw_dir, ~0)
+ && xdr_string(xdrs, &objp->pw_shell, ~0);
+}
+
+
+bool_t
+xdr_yppasswd(XDR * xdrs, yppasswd * objp)
+{
+ return xdr_string(xdrs, &objp->oldpass, ~0)
+ && xdr_xpasswd(xdrs, &objp->newpw);
+}
+
+#endif
diff --git a/modules/pam_userdb/Makefile.am b/modules/pam_userdb/Makefile.am
new file mode 100644
index 0000000..aa70e7d
--- /dev/null
+++ b/modules/pam_userdb/Makefile.am
@@ -0,0 +1,35 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@thkukuk.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS) create.pl
+
+if HAVE_DOC
+dist_man_MANS = pam_userdb.8
+endif
+XMLS = README.xml pam_userdb.8.xml
+dist_check_SCRIPTS = tst-pam_userdb
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module @LIBDB@ @LIBCRYPT@
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_userdb.la
+pam_userdb_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+noinst_HEADERS = pam_userdb.h
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_userdb/Makefile.in b/modules/pam_userdb/Makefile.in
new file mode 100644
index 0000000..6eb785f
--- /dev/null
+++ b/modules/pam_userdb/Makefile.in
@@ -0,0 +1,1155 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@thkukuk.de>
+#
+
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_userdb
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(noinst_HEADERS) \
+ $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_userdb_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_userdb_la_SOURCES = pam_userdb.c
+pam_userdb_la_OBJECTS = pam_userdb.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_userdb.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_userdb.c
+DIST_SOURCES = pam_userdb.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS) create.pl
+@HAVE_DOC_TRUE@dist_man_MANS = pam_userdb.8
+XMLS = README.xml pam_userdb.8.xml
+dist_check_SCRIPTS = tst-pam_userdb
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module @LIBDB@ @LIBCRYPT@ \
+ $(am__append_1)
+securelib_LTLIBRARIES = pam_userdb.la
+pam_userdb_la_LIBADD = $(top_builddir)/libpam/libpam.la
+noinst_HEADERS = pam_userdb.h
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_userdb/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_userdb/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_userdb.la: $(pam_userdb_la_OBJECTS) $(pam_userdb_la_DEPENDENCIES) $(EXTRA_pam_userdb_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_userdb_la_OBJECTS) $(pam_userdb_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_userdb.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_userdb.log: tst-pam_userdb
+ @p='tst-pam_userdb'; \
+ b='tst-pam_userdb'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_userdb.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_userdb.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_userdb/README b/modules/pam_userdb/README
new file mode 100644
index 0000000..9d931bb
--- /dev/null
+++ b/modules/pam_userdb/README
@@ -0,0 +1,76 @@
+pam_userdb — PAM module to authenticate against a db database
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+The pam_userdb module is used to verify a username/password pair against values
+stored in a Berkeley DB database. The database is indexed by the username, and
+the data fields corresponding to the username keys are the passwords.
+
+OPTIONS
+
+crypt=[crypt|none]
+
+ Indicates whether encrypted or plaintext passwords are stored in the
+ database. If it is crypt, passwords should be stored in the database in
+ crypt(3) form. If none is selected, passwords should be stored in the
+ database as plaintext.
+
+db=/path/database
+
+ Use the /path/database database for performing lookup. There is no default;
+ the module will return PAM_IGNORE if no database is provided. Note that the
+ path to the database file should be specified without the .db suffix.
+
+debug
+
+ Print debug information. Note that password hashes, both from db and
+ computed, will be printed to syslog.
+
+dump
+
+ Dump all the entries in the database to the log. Don't do this by default!
+
+icase
+
+ Make the password verification to be case insensitive (ie when working with
+ registration numbers and such). Only works with plaintext password storage.
+
+try_first_pass
+
+ Use the authentication token previously obtained by another module that did
+ the conversation with the application. If this token can not be obtained
+ then the module will try to converse. This option can be used for stacking
+ different modules that need to deal with the authentication tokens.
+
+use_first_pass
+
+ Use the authentication token previously obtained by another module that did
+ the conversation with the application. If this token can not be obtained
+ then the module will fail. This option can be used for stacking different
+ modules that need to deal with the authentication tokens.
+
+unknown_ok
+
+ Do not return error when checking for a user that is not in the database.
+ This can be used to stack more than one pam_userdb module that will check a
+ username/password pair in more than a database.
+
+key_only
+
+ The username and password are concatenated together in the database hash as
+ 'username-password' with a random value. if the concatenation of the
+ username and password with a dash in the middle returns any result, the
+ user is valid. this is useful in cases where the username may not be unique
+ but the username and password pair are.
+
+EXAMPLES
+
+auth sufficient pam_userdb.so icase db=/etc/dbtest
+
+
+AUTHOR
+
+pam_userdb was written by Cristian Gafton >gafton@redhat.com<.
+
diff --git a/modules/pam_userdb/README.xml b/modules/pam_userdb/README.xml
new file mode 100644
index 0000000..b22c09e
--- /dev/null
+++ b/modules/pam_userdb/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_userdb.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_userdb.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_userdb-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_userdb.8.xml" xpointer='xpointer(//refsect1[@id = "pam_userdb-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_userdb.8.xml" xpointer='xpointer(//refsect1[@id = "pam_userdb-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_userdb.8.xml" xpointer='xpointer(//refsect1[@id = "pam_userdb-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_userdb.8.xml" xpointer='xpointer(//refsect1[@id = "pam_userdb-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_userdb/create.pl b/modules/pam_userdb/create.pl
new file mode 100644
index 0000000..06915c9
--- /dev/null
+++ b/modules/pam_userdb/create.pl
@@ -0,0 +1,21 @@
+#!/usr/bin/perl
+# this program creates a database in ARGV[1] from pairs given on
+# stdandard input
+#
+# $Id$
+
+use DB_File;
+
+my $database = $ARGV[0];
+die "Use: create.pl <database>\n" unless ($database);
+print "Using database: $database\n";
+
+my %lusers = ();
+
+tie %lusers, 'DB_File', $database, O_RDWR|O_CREAT, 0644, $DB_HASH ;
+while (<STDIN>) {
+ my ($user, $pass) = split;
+
+ $lusers{$user} = $pass;
+}
+untie %lusers;
diff --git a/modules/pam_userdb/pam_userdb.8 b/modules/pam_userdb/pam_userdb.8
new file mode 100644
index 0000000..fc00278
--- /dev/null
+++ b/modules/pam_userdb/pam_userdb.8
@@ -0,0 +1,158 @@
+'\" t
+.\" Title: pam_userdb
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_USERDB" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_userdb \- PAM module to authenticate against a db database
+.SH "SYNOPSIS"
+.HP \w'\fBpam_userdb\&.so\fR\ 'u
+\fBpam_userdb\&.so\fR db=\fI/path/database\fR [debug] [crypt=[crypt|none]] [icase] [dump] [try_first_pass] [use_first_pass] [unknown_ok] [key_only]
+.SH "DESCRIPTION"
+.PP
+The pam_userdb module is used to verify a username/password pair against values stored in a Berkeley DB database\&. The database is indexed by the username, and the data fields corresponding to the username keys are the passwords\&.
+.SH "OPTIONS"
+.PP
+\fBcrypt=[crypt|none]\fR
+.RS 4
+Indicates whether encrypted or plaintext passwords are stored in the database\&. If it is
+\fBcrypt\fR, passwords should be stored in the database in
+\fBcrypt\fR(3)
+form\&. If
+\fBnone\fR
+is selected, passwords should be stored in the database as plaintext\&.
+.RE
+.PP
+\fBdb=\fR\fB\fI/path/database\fR\fR
+.RS 4
+Use the
+/path/database
+database for performing lookup\&. There is no default; the module will return
+\fBPAM_IGNORE\fR
+if no database is provided\&. Note that the path to the database file should be specified without the
+\&.db
+suffix\&.
+.RE
+.PP
+\fBdebug\fR
+.RS 4
+Print debug information\&. Note that password hashes, both from db and computed, will be printed to syslog\&.
+.RE
+.PP
+\fBdump\fR
+.RS 4
+Dump all the entries in the database to the log\&. Don\*(Aqt do this by default!
+.RE
+.PP
+\fBicase\fR
+.RS 4
+Make the password verification to be case insensitive (ie when working with registration numbers and such)\&. Only works with plaintext password storage\&.
+.RE
+.PP
+\fBtry_first_pass\fR
+.RS 4
+Use the authentication token previously obtained by another module that did the conversation with the application\&. If this token can not be obtained then the module will try to converse\&. This option can be used for stacking different modules that need to deal with the authentication tokens\&.
+.RE
+.PP
+\fBuse_first_pass\fR
+.RS 4
+Use the authentication token previously obtained by another module that did the conversation with the application\&. If this token can not be obtained then the module will fail\&. This option can be used for stacking different modules that need to deal with the authentication tokens\&.
+.RE
+.PP
+\fBunknown_ok\fR
+.RS 4
+Do not return error when checking for a user that is not in the database\&. This can be used to stack more than one pam_userdb module that will check a username/password pair in more than a database\&.
+.RE
+.PP
+\fBkey_only\fR
+.RS 4
+The username and password are concatenated together in the database hash as \*(Aqusername\-password\*(Aq with a random value\&. if the concatenation of the username and password with a dash in the middle returns any result, the user is valid\&. this is useful in cases where the username may not be unique but the username and password pair are\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+The
+\fBauth\fR
+and
+\fBaccount\fR
+module types are provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_AUTH_ERR
+.RS 4
+Authentication failure\&.
+.RE
+.PP
+PAM_AUTHTOK_RECOVERY_ERR
+.RS 4
+Authentication information cannot be recovered\&.
+.RE
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_CONV_ERR
+.RS 4
+Conversation failure\&.
+.RE
+.PP
+PAM_SERVICE_ERR
+.RS 4
+Error in service module\&.
+.RE
+.PP
+PAM_SUCCESS
+.RS 4
+Success\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+User not known to the underlying authentication module\&.
+.RE
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+auth sufficient pam_userdb\&.so icase db=/etc/dbtest
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+.PP
+\fBcrypt\fR(3),
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_userdb was written by Cristian Gafton >gafton@redhat\&.com<\&.
diff --git a/modules/pam_userdb/pam_userdb.8.xml b/modules/pam_userdb/pam_userdb.8.xml
new file mode 100644
index 0000000..bce9285
--- /dev/null
+++ b/modules/pam_userdb/pam_userdb.8.xml
@@ -0,0 +1,294 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_userdb">
+
+ <refmeta>
+ <refentrytitle>pam_userdb</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_userdb-name">
+ <refname>pam_userdb</refname>
+ <refpurpose>PAM module to authenticate against a db database</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_userdb-cmdsynopsis">
+ <command>pam_userdb.so</command>
+ <arg choice="plain">
+ db=<replaceable>/path/database</replaceable>
+ </arg>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ crypt=[crypt|none]
+ </arg>
+ <arg choice="opt">
+ icase
+ </arg>
+ <arg choice="opt">
+ dump
+ </arg>
+ <arg choice="opt">
+ try_first_pass
+ </arg>
+ <arg choice="opt">
+ use_first_pass
+ </arg>
+ <arg choice="opt">
+ unknown_ok
+ </arg>
+ <arg choice="opt">
+ key_only
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_userdb-description">
+
+ <title>DESCRIPTION</title>
+
+ <para>
+ The pam_userdb module is used to verify a username/password pair
+ against values stored in a Berkeley DB database. The database is
+ indexed by the username, and the data fields corresponding to the
+ username keys are the passwords.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_userdb-options">
+
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>crypt=[crypt|none]</option>
+ </term>
+ <listitem>
+ <para>
+ Indicates whether encrypted or plaintext passwords are stored
+ in the database. If it is <option>crypt</option>, passwords
+ should be stored in the database in
+ <citerefentry>
+ <refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry> form. If <option>none</option> is selected,
+ passwords should be stored in the database as plaintext.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>db=<replaceable>/path/database</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Use the <filename>/path/database</filename> database for
+ performing lookup. There is no default; the module will
+ return <emphasis remap='B'>PAM_IGNORE</emphasis> if no
+ database is provided. Note that the path to the database file
+ should be specified without the <filename>.db</filename> suffix.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Print debug information. Note that password hashes, both from db
+ and computed, will be printed to syslog.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>dump</option>
+ </term>
+ <listitem>
+ <para>
+ Dump all the entries in the database to the log.
+ Don't do this by default!
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>icase</option>
+ </term>
+ <listitem>
+ <para>
+ Make the password verification to be case insensitive
+ (ie when working with registration numbers and such).
+ Only works with plaintext password storage.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>try_first_pass</option>
+ </term>
+ <listitem>
+ <para>
+ Use the authentication token previously obtained by
+ another module that did the conversation with the
+ application. If this token can not be obtained then
+ the module will try to converse. This option can
+ be used for stacking different modules that need to
+ deal with the authentication tokens.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>use_first_pass</option>
+ </term>
+ <listitem>
+ <para>
+ Use the authentication token previously obtained by
+ another module that did the conversation with the
+ application. If this token can not be obtained then
+ the module will fail. This option can be used for
+ stacking different modules that need to deal with
+ the authentication tokens.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>unknown_ok</option>
+ </term>
+ <listitem>
+ <para>
+ Do not return error when checking for a user that is
+ not in the database. This can be used to stack more
+ than one pam_userdb module that will check a
+ username/password pair in more than a database.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>key_only</option>
+ </term>
+ <listitem>
+ <para>
+ The username and password are concatenated together
+ in the database hash as 'username-password' with a
+ random value. if the concatenation of the username and
+ password with a dash in the middle returns any result,
+ the user is valid. this is useful in cases where
+ the username may not be unique but the username and
+ password pair are.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_userdb-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ The <option>auth</option> and <option>account</option> module
+ types are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_userdb-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_AUTH_ERR</term>
+ <listitem>
+ <para>Authentication failure.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_AUTHTOK_RECOVERY_ERR</term>
+ <listitem>
+ <para>
+ Authentication information cannot be recovered.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory buffer error.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_CONV_ERR</term>
+ <listitem>
+ <para>
+ Conversation failure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ Error in service module.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Success.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ User not known to the underlying authentication module.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_userdb-examples'>
+ <title>EXAMPLES</title>
+ <programlisting>
+auth sufficient pam_userdb.so icase db=/etc/dbtest
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id='pam_userdb-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>crypt</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_userdb-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_userdb was written by Cristian Gafton &gt;gafton@redhat.com&lt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_userdb/pam_userdb.c b/modules/pam_userdb/pam_userdb.c
new file mode 100644
index 0000000..f467ea4
--- /dev/null
+++ b/modules/pam_userdb/pam_userdb.c
@@ -0,0 +1,517 @@
+/*
+ * pam_userdb module
+ *
+ * Written by Cristian Gafton <gafton@redhat.com> 1996/09/10
+ * See the end of the file for Copyright Information
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#ifdef HAVE_CRYPT_H
+#include <crypt.h>
+#endif
+
+#include "pam_userdb.h"
+
+#ifdef HAVE_NDBM_H
+# include <ndbm.h>
+#else
+# ifdef HAVE_DB_H
+# define DB_DBM_HSEARCH 1 /* use the dbm interface */
+# define HAVE_DBM /* for BerkDB 5.0 and later */
+# include <db.h>
+# else
+# error "failed to find a libdb or equivalent"
+# endif
+#endif
+
+#include <security/pam_modules.h>
+#include <security/pam_ext.h>
+#include <security/_pam_macros.h>
+#include "pam_inline.h"
+
+/*
+ * Conversation function to obtain the user's password
+ */
+static int
+obtain_authtok(pam_handle_t *pamh)
+{
+ char *resp;
+ const void *item;
+ int retval;
+
+ retval = pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, &resp, _("Password: "));
+
+ if (retval != PAM_SUCCESS)
+ return retval;
+
+ if (resp == NULL)
+ return PAM_CONV_ERR;
+
+ /* set the auth token */
+ retval = pam_set_item(pamh, PAM_AUTHTOK, resp);
+
+ /* clean it up */
+ _pam_overwrite(resp);
+ _pam_drop(resp);
+
+ if ( (retval != PAM_SUCCESS) ||
+ (retval = pam_get_item(pamh, PAM_AUTHTOK, &item))
+ != PAM_SUCCESS ) {
+ return retval;
+ }
+
+ return retval;
+}
+
+static int
+_pam_parse (pam_handle_t *pamh, int argc, const char **argv,
+ const char **database, const char **cryptmode)
+{
+ int ctrl;
+
+ *database = NULL;
+ *cryptmode = NULL;
+
+ /* step through arguments */
+ for (ctrl = 0; argc-- > 0; ++argv)
+ {
+ const char *str;
+
+ /* generic options */
+
+ if (!strcmp(*argv,"debug"))
+ ctrl |= PAM_DEBUG_ARG;
+ else if (!strcasecmp(*argv, "icase"))
+ ctrl |= PAM_ICASE_ARG;
+ else if (!strcasecmp(*argv, "dump"))
+ ctrl |= PAM_DUMP_ARG;
+ else if (!strcasecmp(*argv, "unknown_ok"))
+ ctrl |= PAM_UNKNOWN_OK_ARG;
+ else if (!strcasecmp(*argv, "key_only"))
+ ctrl |= PAM_KEY_ONLY_ARG;
+ else if (!strcasecmp(*argv, "use_first_pass"))
+ ctrl |= PAM_USE_FPASS_ARG;
+ else if (!strcasecmp(*argv, "try_first_pass"))
+ ctrl |= PAM_TRY_FPASS_ARG;
+ else if ((str = pam_str_skip_icase_prefix(*argv, "db=")) != NULL)
+ {
+ *database = str;
+ if (**database == '\0') {
+ *database = NULL;
+ pam_syslog(pamh, LOG_ERR,
+ "db= specification missing argument - ignored");
+ }
+ }
+ else if ((str = pam_str_skip_icase_prefix(*argv, "crypt=")) != NULL)
+ {
+ *cryptmode = str;
+ if (**cryptmode == '\0')
+ pam_syslog(pamh, LOG_ERR,
+ "crypt= specification missing argument - ignored");
+ }
+ else
+ {
+ pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
+ }
+ }
+
+ return ctrl;
+}
+
+
+/*
+ * Looks up a user name in a database and checks the password
+ *
+ * return values:
+ * 1 = User not found
+ * 0 = OK
+ * -1 = Password incorrect
+ * -2 = System error
+ */
+static int
+user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode,
+ const char *user, const char *pass, int ctrl)
+{
+ DBM *dbm;
+ datum key, data;
+
+ /* Open the DB file. */
+ dbm = dbm_open(database, O_RDONLY, 0644);
+ if (dbm == NULL) {
+ pam_syslog(pamh, LOG_ERR,
+ "user_lookup: could not open database `%s': %m", database);
+ return -2;
+ }
+
+ /* dump out the database contents for debugging */
+ if (ctrl & PAM_DUMP_ARG) {
+ pam_syslog(pamh, LOG_INFO, "Database dump:");
+ for (key = dbm_firstkey(dbm); key.dptr != NULL;
+ key = dbm_nextkey(dbm)) {
+ data = dbm_fetch(dbm, key);
+ pam_syslog(pamh, LOG_INFO,
+ "key[len=%d] = `%s', data[len=%d] = `%s'",
+ key.dsize, key.dptr, data.dsize, data.dptr);
+ }
+ }
+
+ /* do some more init work */
+ memset(&key, 0, sizeof(key));
+ memset(&data, 0, sizeof(data));
+ if (ctrl & PAM_KEY_ONLY_ARG) {
+ if (asprintf(&key.dptr, "%s-%s", user, pass) < 0)
+ key.dptr = NULL;
+ else
+ key.dsize = strlen(key.dptr);
+ } else {
+ key.dptr = strdup(user);
+ key.dsize = strlen(user);
+ }
+
+ if (key.dptr) {
+ data = dbm_fetch(dbm, key);
+ memset(key.dptr, 0, key.dsize);
+ free(key.dptr);
+ }
+
+ if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_INFO,
+ "password in database is [%p]`%.*s', len is %d",
+ data.dptr, data.dsize, (char *) data.dptr, data.dsize);
+ }
+
+ if (data.dptr != NULL) {
+ int compare = -2;
+
+ if (ctrl & PAM_KEY_ONLY_ARG)
+ {
+ dbm_close (dbm);
+ return 0; /* found it, data contents don't matter */
+ }
+
+ if (cryptmode && pam_str_skip_icase_prefix(cryptmode, "crypt") != NULL) {
+
+ /* crypt(3) password storage */
+
+ char *cryptpw = NULL;
+
+ if (data.dsize < 13) {
+ /* hash is too short */
+ pam_syslog(pamh, LOG_INFO, "password hash in database is too short");
+ } else if (ctrl & PAM_ICASE_ARG) {
+ pam_syslog(pamh, LOG_INFO,
+ "case-insensitive comparison only works with plaintext passwords");
+ } else {
+ /* libdb is not guaranteed to produce null terminated strings */
+ char *pwhash = strndup(data.dptr, data.dsize);
+
+ if (pwhash == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "strndup failed: data.dptr");
+ } else {
+#ifdef HAVE_CRYPT_R
+ struct crypt_data *cdata = NULL;
+ cdata = malloc(sizeof(*cdata));
+ if (cdata == NULL) {
+ pam_syslog(pamh, LOG_CRIT, "malloc failed: struct crypt_data");
+ } else {
+ cdata->initialized = 0;
+ cryptpw = crypt_r(pass, pwhash, cdata);
+ }
+#else
+ cryptpw = crypt (pass, pwhash);
+#endif
+ if (cryptpw && strlen(cryptpw) == (size_t)data.dsize) {
+ compare = memcmp(data.dptr, cryptpw, data.dsize);
+ } else {
+ if (ctrl & PAM_DEBUG_ARG) {
+ if (cryptpw) {
+ pam_syslog(pamh, LOG_INFO, "lengths of computed and stored hashes differ");
+ pam_syslog(pamh, LOG_INFO, "computed hash: %s", cryptpw);
+ } else {
+ pam_syslog(pamh, LOG_ERR, "crypt() returned NULL");
+ }
+ }
+ }
+#ifdef HAVE_CRYPT_R
+ free(cdata);
+#endif
+ }
+ free(pwhash);
+ }
+ } else {
+
+ /* Unknown password encryption method -
+ * default to plaintext password storage
+ */
+
+ if (strlen(pass) != (size_t)data.dsize) {
+ compare = 1; /* wrong password len -> wrong password */
+ } else if (ctrl & PAM_ICASE_ARG) {
+ compare = strncasecmp(data.dptr, pass, data.dsize);
+ } else {
+ compare = strncmp(data.dptr, pass, data.dsize);
+ }
+
+ if (cryptmode && pam_str_skip_icase_prefix(cryptmode, "none") == NULL
+ && (ctrl & PAM_DEBUG_ARG)) {
+ pam_syslog(pamh, LOG_INFO, "invalid value for crypt parameter: %s",
+ cryptmode);
+ pam_syslog(pamh, LOG_INFO, "defaulting to plaintext password mode");
+ }
+
+ }
+
+ dbm_close(dbm);
+ if (compare == 0)
+ return 0; /* match */
+ else
+ return -1; /* wrong */
+ } else {
+ int saw_user = 0;
+
+ if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_INFO, "error returned by dbm_fetch: %m");
+ }
+
+ /* probably we should check dbm_error() here */
+
+ if ((ctrl & PAM_KEY_ONLY_ARG) == 0) {
+ dbm_close(dbm);
+ return 1; /* not key_only, so no entry => no entry for the user */
+ }
+
+ /* now handle the key_only case */
+ for (key = dbm_firstkey(dbm);
+ key.dptr != NULL;
+ key = dbm_nextkey(dbm)) {
+ int compare;
+ /* first compare the user portion (case sensitive) */
+ compare = strncmp(key.dptr, user, strlen(user));
+ if (compare == 0) {
+ /* assume failure */
+ compare = -1;
+ /* if we have the divider where we expect it to be... */
+ if (key.dptr[strlen(user)] == '-') {
+ saw_user = 1;
+ if ((size_t)key.dsize == strlen(user) + 1 + strlen(pass)) {
+ if (ctrl & PAM_ICASE_ARG) {
+ /* compare the password portion (case insensitive)*/
+ compare = strncasecmp(key.dptr + strlen(user) + 1,
+ pass,
+ strlen(pass));
+ } else {
+ /* compare the password portion (case sensitive) */
+ compare = strncmp(key.dptr + strlen(user) + 1,
+ pass,
+ strlen(pass));
+ }
+ }
+ }
+ if (compare == 0) {
+ dbm_close(dbm);
+ return 0; /* match */
+ }
+ }
+ }
+ dbm_close(dbm);
+ if (saw_user)
+ return -1; /* saw the user, but password mismatch */
+ else
+ return 1; /* not found */
+ }
+
+ /* NOT REACHED */
+ return -2;
+}
+
+/* --- authentication management functions (only) --- */
+
+int
+pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ const char *username;
+ const void *password;
+ const char *database = NULL;
+ const char *cryptmode = NULL;
+ int retval = PAM_AUTH_ERR, ctrl;
+
+ /* parse arguments */
+ ctrl = _pam_parse(pamh, argc, argv, &database, &cryptmode);
+ if (database == NULL) {
+ pam_syslog(pamh, LOG_ERR, "can not get the database name");
+ return PAM_SERVICE_ERR;
+ }
+
+ /* Get the username */
+ retval = pam_get_user(pamh, &username, NULL);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE, "cannot determine user name: %s",
+ pam_strerror(pamh, retval));
+ return PAM_SERVICE_ERR;
+ }
+
+ if ((ctrl & PAM_USE_FPASS_ARG) == 0 && (ctrl & PAM_TRY_FPASS_ARG) == 0) {
+ /* Converse to obtain a password */
+ retval = obtain_authtok(pamh);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR, "can not obtain password from user");
+ return retval;
+ }
+ }
+
+ /* Check if we got a password */
+ retval = pam_get_item(pamh, PAM_AUTHTOK, &password);
+ if (retval != PAM_SUCCESS || password == NULL) {
+ if ((ctrl & PAM_TRY_FPASS_ARG) != 0) {
+ /* Converse to obtain a password */
+ retval = obtain_authtok(pamh);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR, "can not obtain password from user");
+ return retval;
+ }
+ retval = pam_get_item(pamh, PAM_AUTHTOK, &password);
+ }
+ if (retval != PAM_SUCCESS || password == NULL) {
+ pam_syslog(pamh, LOG_ERR, "can not recover user password");
+ return PAM_AUTHTOK_RECOVERY_ERR;
+ }
+ }
+
+ if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh, LOG_INFO, "Verify user `%s' with a password",
+ username);
+
+ /* Now use the username to look up password in the database file */
+ retval = user_lookup(pamh, database, cryptmode, username, password, ctrl);
+ switch (retval) {
+ case -2:
+ /* some sort of system error. The log was already printed */
+ return PAM_SERVICE_ERR;
+ case -1:
+ /* incorrect password */
+ pam_syslog(pamh, LOG_NOTICE,
+ "user `%s' denied access (incorrect password)",
+ username);
+ return PAM_AUTH_ERR;
+ case 1:
+ /* the user does not exist in the database */
+ if (ctrl & PAM_DEBUG_ARG)
+ pam_syslog(pamh, LOG_NOTICE,
+ "user `%s' not found in the database", username);
+ return PAM_USER_UNKNOWN;
+ case 0:
+ /* Otherwise, the authentication looked good */
+ pam_syslog(pamh, LOG_NOTICE, "user '%s' granted access", username);
+ return PAM_SUCCESS;
+ default:
+ /* we don't know anything about this return value */
+ pam_syslog(pamh, LOG_ERR,
+ "internal module error (retval = %d, user = `%s'",
+ retval, username);
+ return PAM_SERVICE_ERR;
+ }
+
+ /* should not be reached */
+ return PAM_IGNORE;
+}
+
+int
+pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
+
+int
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ const char *username;
+ const char *database = NULL;
+ const char *cryptmode = NULL;
+ int retval = PAM_AUTH_ERR, ctrl;
+
+ /* parse arguments */
+ ctrl = _pam_parse(pamh, argc, argv, &database, &cryptmode);
+
+ /* Get the username */
+ retval = pam_get_user(pamh, &username, NULL);
+ if (retval != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE, "cannot determine user name: %s",
+ pam_strerror(pamh, retval));
+ return PAM_SERVICE_ERR;
+ }
+
+ /* Now use the username to look up password in the database file */
+ retval = user_lookup(pamh, database, cryptmode, username, "", ctrl);
+ switch (retval) {
+ case -2:
+ /* some sort of system error. The log was already printed */
+ return PAM_SERVICE_ERR;
+ case -1:
+ /* incorrect password, but we don't care */
+ /* FALL THROUGH */
+ case 0:
+ /* authentication succeeded. dumbest password ever. */
+ return PAM_SUCCESS;
+ case 1:
+ /* the user does not exist in the database */
+ return PAM_USER_UNKNOWN;
+ default:
+ /* we don't know anything about this return value */
+ pam_syslog(pamh, LOG_ERR,
+ "internal module error (retval = %d, user = `%s'",
+ retval, username);
+ return PAM_SERVICE_ERR;
+ }
+
+ return PAM_SUCCESS;
+}
+
+/*
+ * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1999
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/modules/pam_userdb/pam_userdb.h b/modules/pam_userdb/pam_userdb.h
new file mode 100644
index 0000000..86e9b47
--- /dev/null
+++ b/modules/pam_userdb/pam_userdb.h
@@ -0,0 +1,59 @@
+
+#ifndef _PAM_USERSDB_H
+#define _PAM_USERSDB_H
+/* $Id$ */
+
+/* Header files */
+#include <security/pam_appl.h>
+
+/* argument parsing */
+#define PAM_DEBUG_ARG 0x0001
+#define PAM_ICASE_ARG 0x0002
+#define PAM_DUMP_ARG 0x0004
+#define PAM_UNKNOWN_OK_ARG 0x0010
+#define PAM_KEY_ONLY_ARG 0x0020
+#define PAM_USE_FPASS_ARG 0x0040
+#define PAM_TRY_FPASS_ARG 0x0080
+
+/* The name of the module we are compiling */
+#ifndef MODULE_NAME
+#define MODULE_NAME "pam_userdb"
+#endif /* MODULE_NAME */
+
+#endif /* _PAM_USERSDB_H */
+
+/*
+ * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1999
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/modules/pam_userdb/tst-pam_userdb b/modules/pam_userdb/tst-pam_userdb
new file mode 100755
index 0000000..5d5eb19
--- /dev/null
+++ b/modules/pam_userdb/tst-pam_userdb
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_userdb.so
diff --git a/modules/pam_usertype/Makefile.am b/modules/pam_usertype/Makefile.am
new file mode 100644
index 0000000..28224b9
--- /dev/null
+++ b/modules/pam_usertype/Makefile.am
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+# Copyright (c) 2020 Red Hat, Inc.
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_usertype.8
+endif
+XMLS = README.xml pam_usertype.8.xml
+dist_check_SCRIPTS = tst-pam_usertype
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_usertype.la
+pam_usertype_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_usertype/Makefile.in b/modules/pam_usertype/Makefile.in
new file mode 100644
index 0000000..4118a62
--- /dev/null
+++ b/modules/pam_usertype/Makefile.in
@@ -0,0 +1,1151 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+# Copyright (c) 2020 Red Hat, Inc.
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_usertype
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_usertype_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_usertype_la_SOURCES = pam_usertype.c
+pam_usertype_la_OBJECTS = pam_usertype.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_usertype.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_usertype.c
+DIST_SOURCES = pam_usertype.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_usertype.8
+XMLS = README.xml pam_usertype.8.xml
+dist_check_SCRIPTS = tst-pam_usertype
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_usertype.la
+pam_usertype_la_LIBADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_usertype/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_usertype/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_usertype.la: $(pam_usertype_la_OBJECTS) $(pam_usertype_la_DEPENDENCIES) $(EXTRA_pam_usertype_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_usertype_la_OBJECTS) $(pam_usertype_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_usertype.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_usertype.log: tst-pam_usertype
+ @p='tst-pam_usertype'; \
+ b='tst-pam_usertype'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_usertype.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_usertype.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_usertype/README b/modules/pam_usertype/README
new file mode 100644
index 0000000..246a389
--- /dev/null
+++ b/modules/pam_usertype/README
@@ -0,0 +1,48 @@
+pam_usertype — check if the authenticated user is a system or regular account
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+pam_usertype.so is designed to succeed or fail authentication based on type of
+the account of the authenticated user. The type of the account is decided with
+help of SYS_UID_MIN and SYS_UID_MAX settings in /etc/login.defs. One use is to
+select whether to load other modules based on this test.
+
+The module should be given only one condition as module argument.
+Authentication will succeed only if the condition is met.
+
+OPTIONS
+
+The following flags are supported:
+
+use_uid
+
+ Evaluate conditions using the account of the user whose UID the application
+ is running under instead of the user being authenticated.
+
+audit
+
+ Log unknown users to the system log.
+
+Available conditions are:
+
+issystem
+
+ Succeed if the user is a system user.
+
+isregular
+
+ Succeed if the user is a regular user.
+
+EXAMPLES
+
+Skip remaining modules if the user is a system user:
+
+account sufficient pam_usertype.so issystem
+
+
+AUTHOR
+
+Pavel Březina <pbrezina@redhat.com>
+
diff --git a/modules/pam_usertype/README.xml b/modules/pam_usertype/README.xml
new file mode 100644
index 0000000..5855046
--- /dev/null
+++ b/modules/pam_usertype/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_usertype.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_usertype.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_usertype-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_usertype.8.xml" xpointer='xpointer(//refsect1[@id = "pam_usertype-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_usertype.8.xml" xpointer='xpointer(//refsect1[@id = "pam_usertype-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_usertype.8.xml" xpointer='xpointer(//refsect1[@id = "pam_usertype-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_usertype.8.xml" xpointer='xpointer(//refsect1[@id = "pam_usertype-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_usertype/pam_usertype.8 b/modules/pam_usertype/pam_usertype.8
new file mode 100644
index 0000000..2f02101
--- /dev/null
+++ b/modules/pam_usertype/pam_usertype.8
@@ -0,0 +1,135 @@
+'\" t
+.\" Title: pam_usertype
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM
+.\" Source: Linux-PAM
+.\" Language: English
+.\"
+.TH "PAM_USERTYPE" "8" "09/03/2021" "Linux-PAM" "Linux\-PAM"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_usertype \- check if the authenticated user is a system or regular account
+.SH "SYNOPSIS"
+.HP \w'\fBpam_usertype\&.so\fR\ 'u
+\fBpam_usertype\&.so\fR [\fIflag\fR...] {\fIcondition\fR}
+.SH "DESCRIPTION"
+.PP
+pam_usertype\&.so is designed to succeed or fail authentication based on type of the account of the authenticated user\&. The type of the account is decided with help of
+\fISYS_UID_MIN\fR
+and
+\fISYS_UID_MAX\fR
+settings in
+\fI/etc/login\&.defs\fR\&. One use is to select whether to load other modules based on this test\&.
+.PP
+The module should be given only one condition as module argument\&. Authentication will succeed only if the condition is met\&.
+.SH "OPTIONS"
+.PP
+The following
+\fIflag\fRs are supported:
+.PP
+\fBuse_uid\fR
+.RS 4
+Evaluate conditions using the account of the user whose UID the application is running under instead of the user being authenticated\&.
+.RE
+.PP
+\fBaudit\fR
+.RS 4
+Log unknown users to the system log\&.
+.RE
+.PP
+Available
+\fIcondition\fRs are:
+.PP
+\fBissystem\fR
+.RS 4
+Succeed if the user is a system user\&.
+.RE
+.PP
+\fBisregular\fR
+.RS 4
+Succeed if the user is a regular user\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+All module types (\fBaccount\fR,
+\fBauth\fR,
+\fBpassword\fR
+and
+\fBsession\fR) are provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_SUCCESS
+.RS 4
+The condition was true\&.
+.RE
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_CONV_ERR
+.RS 4
+The conversation method supplied by the application failed to obtain the username\&.
+.RE
+.PP
+PAM_INCOMPLETE
+.RS 4
+The conversation method supplied by the application returned PAM_CONV_AGAIN\&.
+.RE
+.PP
+PAM_AUTH_ERR
+.RS 4
+The condition was false\&.
+.RE
+.PP
+PAM_SERVICE_ERR
+.RS 4
+A service error occurred or the arguments can\*(Aqt be parsed correctly\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+User was not found\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Skip remaining modules if the user is a system user:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+account sufficient pam_usertype\&.so issystem
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+.PP
+\fBlogin.defs\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+Pavel Březina <pbrezina@redhat\&.com>
diff --git a/modules/pam_usertype/pam_usertype.8.xml b/modules/pam_usertype/pam_usertype.8.xml
new file mode 100644
index 0000000..7651da6
--- /dev/null
+++ b/modules/pam_usertype/pam_usertype.8.xml
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+
+<refentry id='pam_usertype'>
+ <refmeta>
+ <refentrytitle>pam_usertype</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class='sectdesc'>Linux-PAM</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id='pam_usertype-name'>
+ <refname>pam_usertype</refname>
+ <refpurpose>check if the authenticated user is a system or regular account</refpurpose>
+ </refnamediv>
+
+
+ <refsynopsisdiv>
+ <cmdsynopsis id='pam_usertype-cmdsynopsis'>
+ <command>pam_usertype.so</command>
+ <arg choice='opt' rep='repeat'><replaceable>flag</replaceable></arg>
+ <arg choice='req'><replaceable>condition</replaceable></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1 id='pam_usertype-description'>
+ <title>DESCRIPTION</title>
+ <para>
+ pam_usertype.so is designed to succeed or fail authentication
+ based on type of the account of the authenticated user.
+ The type of the account is decided with help of
+ <emphasis>SYS_UID_MIN</emphasis> and <emphasis>SYS_UID_MAX</emphasis>
+ settings in <emphasis>/etc/login.defs</emphasis>. One use is to select
+ whether to load other modules based on this test.
+ </para>
+
+ <para>
+ The module should be given only one condition as module argument.
+ Authentication will succeed only if the condition is met.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_usertype-options">
+ <title>OPTIONS</title>
+ <para>
+ The following <emphasis>flag</emphasis>s are supported:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>use_uid</option></term>
+ <listitem>
+ <para>
+ Evaluate conditions using the account of the user whose UID
+ the application is running under instead of the user being
+ authenticated.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>audit</option></term>
+ <listitem>
+ <para>
+ Log unknown users to the system log.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
+ <para>
+ Available <emphasis>condition</emphasis>s are:
+ </para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>issystem</option></term>
+ <listitem>
+ <para>Succeed if the user is a system user.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>isregular</option></term>
+ <listitem>
+ <para>Succeed if the user is a regular user.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_usertype-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ All module types (<option>account</option>, <option>auth</option>,
+ <option>password</option> and <option>session</option>) are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_usertype-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ The condition was true.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory buffer error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_CONV_ERR</term>
+ <listitem>
+ <para>
+ The conversation method supplied by the application
+ failed to obtain the username.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_INCOMPLETE</term>
+ <listitem>
+ <para>
+ The conversation method supplied by the application
+ returned PAM_CONV_AGAIN.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_AUTH_ERR</term>
+ <listitem>
+ <para>
+ The condition was false.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ A service error occurred or the arguments can't be
+ parsed correctly.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ User was not found.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+
+ <refsect1 id='pam_usertype-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ Skip remaining modules if the user is a system user:
+ </para>
+ <programlisting>
+account sufficient pam_usertype.so issystem
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id='pam_usertype-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>login.defs</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_usertype-author'>
+ <title>AUTHOR</title>
+ <para>Pavel Březina &lt;pbrezina@redhat.com&gt;</para>
+ </refsect1>
+</refentry>
diff --git a/modules/pam_usertype/pam_usertype.c b/modules/pam_usertype/pam_usertype.c
new file mode 100644
index 0000000..d03b73b
--- /dev/null
+++ b/modules/pam_usertype/pam_usertype.c
@@ -0,0 +1,311 @@
+/******************************************************************************
+ * Check user type based on login.defs.
+ *
+ * Copyright (c) 2020 Red Hat, Inc.
+ * Written by Pavel Březina <pbrezina@redhat.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+
+#define LOGIN_DEFS "/etc/login.defs"
+
+enum pam_usertype_op {
+ OP_IS_SYSTEM,
+ OP_IS_REGULAR,
+
+ OP_SENTINEL
+};
+
+struct pam_usertype_opts {
+ enum pam_usertype_op op;
+ int use_uid;
+ int audit;
+};
+
+static int
+pam_usertype_parse_args(struct pam_usertype_opts *opts,
+ pam_handle_t *pamh,
+ int argc,
+ const char **argv)
+{
+ int i;
+
+ memset(opts, 0, sizeof(struct pam_usertype_opts));
+ opts->op = OP_SENTINEL;
+
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "use_uid") == 0) {
+ opts->use_uid = 1;
+ } else if (strcmp(argv[i], "audit") == 0) {
+ opts->audit = 1;
+ } else if (strcmp(argv[i], "issystem") == 0) {
+ opts->op = OP_IS_SYSTEM;
+ } else if (strcmp(argv[i], "isregular") == 0) {
+ opts->op = OP_IS_REGULAR;
+ } else {
+ pam_syslog(pamh, LOG_WARNING, "Unknown argument: %s", argv[i]);
+ /* Just continue. */
+ }
+ }
+
+ if (opts->op == OP_SENTINEL) {
+ pam_syslog(pamh, LOG_ERR, "Operation not specified");
+ return PAM_SERVICE_ERR;
+ }
+
+ return PAM_SUCCESS;
+}
+
+static int
+pam_usertype_get_uid(struct pam_usertype_opts *opts,
+ pam_handle_t *pamh,
+ uid_t *_uid)
+{
+ struct passwd *pwd;
+ const char *username;
+ int ret;
+
+ /* Get uid of user that runs the application. */
+ if (opts->use_uid) {
+ pwd = pam_modutil_getpwuid(pamh, getuid());
+ if (pwd == NULL) {
+ pam_syslog(pamh, LOG_ERR,
+ "error retrieving information about user %lu",
+ (unsigned long)getuid());
+ return PAM_USER_UNKNOWN;
+ }
+
+ *_uid = pwd->pw_uid;
+ return PAM_SUCCESS;
+ }
+
+ /* Get uid of user that is being authenticated. */
+ ret = pam_get_user(pamh, &username, NULL);
+ if (ret != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE, "cannot determine user name: %s",
+ pam_strerror(pamh, ret));
+ return ret == PAM_CONV_AGAIN ? PAM_INCOMPLETE : ret;
+ }
+
+ pwd = pam_modutil_getpwnam(pamh, username);
+ if (pwd == NULL) {
+ if (opts->audit) {
+ pam_syslog(pamh, LOG_NOTICE,
+ "error retrieving information about user %s", username);
+ }
+
+ pam_modutil_getpwnam(pamh, "root");
+
+ return PAM_USER_UNKNOWN;
+ }
+ pam_modutil_getpwnam(pamh, "pam_usertype_non_existent:");
+
+ *_uid = pwd->pw_uid;
+
+ return PAM_SUCCESS;
+}
+
+#define MAX_UID_VALUE 0xFFFFFFFFUL
+
+static uid_t
+pam_usertype_get_id(pam_handle_t *pamh,
+ const char *key,
+ uid_t default_value)
+{
+ unsigned long ul;
+ char *value;
+ char *ep;
+ uid_t uid;
+
+ value = pam_modutil_search_key(pamh, LOGIN_DEFS, key);
+ if (value == NULL) {
+ return default_value;
+ }
+
+ /* taken from get_lastlog_uid_max() */
+ ep = value + strlen(value);
+ while (ep > value && isspace(*(--ep))) {
+ *ep = '\0';
+ }
+
+ errno = 0;
+ ul = strtoul(value, &ep, 10);
+ if (!(ul >= MAX_UID_VALUE
+ || (uid_t)ul >= MAX_UID_VALUE
+ || (errno != 0 && ul == 0)
+ || value == ep
+ || *ep != '\0')) {
+ uid = (uid_t)ul;
+ } else {
+ uid = default_value;
+ }
+
+ free(value);
+
+ return uid;
+}
+
+static int
+pam_usertype_is_system(pam_handle_t *pamh, uid_t uid)
+{
+ uid_t uid_min;
+ uid_t sys_min;
+ uid_t sys_max;
+
+ if (uid == (uid_t)-1) {
+ pam_syslog(pamh, LOG_WARNING, "invalid uid");
+ return PAM_USER_UNKNOWN;
+ }
+
+ if (uid <= 99) {
+ /* Reserved. */
+ return PAM_SUCCESS;
+ }
+
+ if (uid == PAM_USERTYPE_OVERFLOW_UID) {
+ /* nobody */
+ return PAM_SUCCESS;
+ }
+
+ uid_min = pam_usertype_get_id(pamh, "UID_MIN", PAM_USERTYPE_UIDMIN);
+ sys_min = pam_usertype_get_id(pamh, "SYS_UID_MIN", PAM_USERTYPE_SYSUIDMIN);
+ sys_max = pam_usertype_get_id(pamh, "SYS_UID_MAX", uid_min - 1);
+
+ return uid >= sys_min && uid <= sys_max ? PAM_SUCCESS : PAM_AUTH_ERR;
+}
+
+static int
+pam_usertype_is_regular(pam_handle_t *pamh, uid_t uid)
+{
+ int ret;
+
+ ret = pam_usertype_is_system(pamh, uid);
+ switch (ret) {
+ case PAM_SUCCESS:
+ return PAM_AUTH_ERR;
+ case PAM_USER_UNKNOWN:
+ return PAM_USER_UNKNOWN;
+ default:
+ return PAM_SUCCESS;
+ }
+}
+
+static int
+pam_usertype_evaluate(struct pam_usertype_opts *opts,
+ pam_handle_t *pamh,
+ uid_t uid)
+{
+ switch (opts->op) {
+ case OP_IS_SYSTEM:
+ return pam_usertype_is_system(pamh, uid);
+ case OP_IS_REGULAR:
+ return pam_usertype_is_regular(pamh, uid);
+ default:
+ pam_syslog(pamh, LOG_ERR, "Unknown operation: %d", opts->op);
+ return PAM_SERVICE_ERR;
+ }
+}
+
+/**
+ * Arguments:
+ * - issystem: uid in <SYS_UID_MIN, SYS_UID_MAX>
+ * - isregular: not issystem
+ * - use_uid: use user that runs application not that is being authenticate (same as in pam_succeed_if)
+ * - audit: log unknown users to syslog
+ */
+int
+pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ struct pam_usertype_opts opts;
+ uid_t uid = -1;
+ int ret;
+
+ ret = pam_usertype_parse_args(&opts, pamh, argc, argv);
+ if (ret != PAM_SUCCESS) {
+ return ret;
+ }
+
+ ret = pam_usertype_get_uid(&opts, pamh, &uid);
+ if (ret != PAM_SUCCESS) {
+ return ret;
+ }
+
+ return pam_usertype_evaluate(&opts, pamh, uid);
+}
+
+int
+pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_IGNORE;
+}
+
+int
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+int
+pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+int
+pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+int
+pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
+{
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
diff --git a/modules/pam_usertype/tst-pam_usertype b/modules/pam_usertype/tst-pam_usertype
new file mode 100755
index 0000000..a21f8fe
--- /dev/null
+++ b/modules/pam_usertype/tst-pam_usertype
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_usertype.so
diff --git a/modules/pam_warn/Makefile.am b/modules/pam_warn/Makefile.am
new file mode 100644
index 0000000..d0f021f
--- /dev/null
+++ b/modules/pam_warn/Makefile.am
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_warn.8
+endif
+XMLS = README.xml pam_warn.8.xml
+dist_check_SCRIPTS = tst-pam_warn
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_warn.la
+pam_warn_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+check_PROGRAMS = tst-pam_warn-retval
+tst_pam_warn_retval_LDADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_warn/Makefile.in b/modules/pam_warn/Makefile.in
new file mode 100644
index 0000000..a1f192f
--- /dev/null
+++ b/modules/pam_warn/Makefile.in
@@ -0,0 +1,1180 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+check_PROGRAMS = tst-pam_warn-retval$(EXEEXT)
+subdir = modules/pam_warn
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_warn_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_warn_la_SOURCES = pam_warn.c
+pam_warn_la_OBJECTS = pam_warn.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+tst_pam_warn_retval_SOURCES = tst-pam_warn-retval.c
+tst_pam_warn_retval_OBJECTS = tst-pam_warn-retval.$(OBJEXT)
+tst_pam_warn_retval_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_warn.Plo \
+ ./$(DEPDIR)/tst-pam_warn-retval.Po
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_warn.c tst-pam_warn-retval.c
+DIST_SOURCES = pam_warn.c tst-pam_warn-retval.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_warn.8
+XMLS = README.xml pam_warn.8.xml
+dist_check_SCRIPTS = tst-pam_warn
+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_warn.la
+pam_warn_la_LIBADD = $(top_builddir)/libpam/libpam.la
+tst_pam_warn_retval_LDADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_warn/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_warn/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_warn.la: $(pam_warn_la_OBJECTS) $(pam_warn_la_DEPENDENCIES) $(EXTRA_pam_warn_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_warn_la_OBJECTS) $(pam_warn_la_LIBADD) $(LIBS)
+
+tst-pam_warn-retval$(EXEEXT): $(tst_pam_warn_retval_OBJECTS) $(tst_pam_warn_retval_DEPENDENCIES) $(EXTRA_tst_pam_warn_retval_DEPENDENCIES)
+ @rm -f tst-pam_warn-retval$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tst_pam_warn_retval_OBJECTS) $(tst_pam_warn_retval_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_warn.Plo@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tst-pam_warn-retval.Po@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(check_PROGRAMS) $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_warn.log: tst-pam_warn
+ @p='tst-pam_warn'; \
+ b='tst-pam_warn'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+tst-pam_warn-retval.log: tst-pam_warn-retval$(EXEEXT)
+ @p='tst-pam_warn-retval$(EXEEXT)'; \
+ b='tst-pam_warn-retval'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) \
+ $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_warn.Plo
+ -rm -f ./$(DEPDIR)/tst-pam_warn-retval.Po
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_warn.Plo
+ -rm -f ./$(DEPDIR)/tst-pam_warn-retval.Po
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-checkPROGRAMS clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_warn/README b/modules/pam_warn/README
new file mode 100644
index 0000000..a071317
--- /dev/null
+++ b/modules/pam_warn/README
@@ -0,0 +1,36 @@
+pam_warn — PAM module which logs all PAM items if called
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+pam_warn is a PAM module that logs the service, terminal, user, remote user and
+remote host to syslog(3). The items are not probed for, but instead obtained
+from the standard PAM items. The module always returns PAM_IGNORE, indicating
+that it does not want to affect the authentication process.
+
+OPTIONS
+
+This module does not recognise any options.
+
+EXAMPLES
+
+#%PAM-1.0
+#
+# If we don't have config entries for a service, the
+# OTHER entries are used. To be secure, warn and deny
+# access to everything.
+other auth required pam_warn.so
+other auth required pam_deny.so
+other account required pam_warn.so
+other account required pam_deny.so
+other password required pam_warn.so
+other password required pam_deny.so
+other session required pam_warn.so
+other session required pam_deny.so
+
+
+AUTHOR
+
+pam_warn was written by Andrew G. Morgan <morgan@kernel.org>.
+
diff --git a/modules/pam_warn/README.xml b/modules/pam_warn/README.xml
new file mode 100644
index 0000000..4367c28
--- /dev/null
+++ b/modules/pam_warn/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_warn.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_warn.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_warn-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_warn.8.xml" xpointer='xpointer(//refsect1[@id = "pam_warn-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_warn.8.xml" xpointer='xpointer(//refsect1[@id = "pam_warn-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_warn.8.xml" xpointer='xpointer(//refsect1[@id = "pam_warn-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_warn.8.xml" xpointer='xpointer(//refsect1[@id = "pam_warn-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_warn/pam_warn.8 b/modules/pam_warn/pam_warn.8
new file mode 100644
index 0000000..2b990fa
--- /dev/null
+++ b/modules/pam_warn/pam_warn.8
@@ -0,0 +1,89 @@
+'\" t
+.\" Title: pam_warn
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_WARN" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_warn \- PAM module which logs all PAM items if called
+.SH "SYNOPSIS"
+.HP \w'\fBpam_warn\&.so\fR\ 'u
+\fBpam_warn\&.so\fR
+.SH "DESCRIPTION"
+.PP
+pam_warn is a PAM module that logs the service, terminal, user, remote user and remote host to
+\fBsyslog\fR(3)\&. The items are not probed for, but instead obtained from the standard PAM items\&. The module always returns
+\fBPAM_IGNORE\fR, indicating that it does not want to affect the authentication process\&.
+.SH "OPTIONS"
+.PP
+This module does not recognise any options\&.
+.SH "MODULE TYPES PROVIDED"
+.PP
+The
+\fBauth\fR,
+\fBaccount\fR,
+\fBpassword\fR
+and
+\fBsession\fR
+module types are provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_IGNORE
+.RS 4
+This module always returns PAM_IGNORE\&.
+.RE
+.SH "EXAMPLES"
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+#%PAM\-1\&.0
+#
+# If we don\*(Aqt have config entries for a service, the
+# OTHER entries are used\&. To be secure, warn and deny
+# access to everything\&.
+other auth required pam_warn\&.so
+other auth required pam_deny\&.so
+other account required pam_warn\&.so
+other account required pam_deny\&.so
+other password required pam_warn\&.so
+other password required pam_deny\&.so
+other session required pam_warn\&.so
+other session required pam_deny\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.SH "SEE ALSO"
+.PP
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_warn was written by Andrew G\&. Morgan <morgan@kernel\&.org>\&.
diff --git a/modules/pam_warn/pam_warn.8.xml b/modules/pam_warn/pam_warn.8.xml
new file mode 100644
index 0000000..1764ec9
--- /dev/null
+++ b/modules/pam_warn/pam_warn.8.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_warn">
+
+ <refmeta>
+ <refentrytitle>pam_warn</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+ <refnamediv id="pam_warn-name">
+ <refname>pam_warn</refname>
+ <refpurpose>PAM module which logs all PAM items if called</refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_warn-cmdsynopsis">
+ <command>pam_warn.so</command>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_warn-description">
+ <title>DESCRIPTION</title>
+ <para>
+ pam_warn is a PAM module that logs the service, terminal, user,
+ remote user and remote host to
+ <citerefentry>
+ <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum>
+ </citerefentry>. The items are not probed for, but instead obtained
+ from the standard PAM items. The module always returns
+ <emphasis remap='B'>PAM_IGNORE</emphasis>, indicating that it
+ does not want to affect the authentication process.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_warn-options">
+ <title>OPTIONS</title>
+ <para>This module does not recognise any options.</para>
+ </refsect1>
+
+ <refsect1 id="pam_warn-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ The <option>auth</option>, <option>account</option>,
+ <option>password</option> and <option>session</option> module
+ types are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_warn-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ This module always returns PAM_IGNORE.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_warn-examples'>
+ <title>EXAMPLES</title>
+ <programlisting>
+#%PAM-1.0
+#
+# If we don't have config entries for a service, the
+# OTHER entries are used. To be secure, warn and deny
+# access to everything.
+other auth required pam_warn.so
+other auth required pam_deny.so
+other account required pam_warn.so
+other account required pam_deny.so
+other password required pam_warn.so
+other password required pam_deny.so
+other session required pam_warn.so
+other session required pam_deny.so
+ </programlisting>
+ </refsect1>
+
+ <refsect1 id='pam_warn-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_warn-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_warn was written by Andrew G. Morgan &lt;morgan@kernel.org&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_warn/pam_warn.c b/modules/pam_warn/pam_warn.c
new file mode 100644
index 0000000..d91c3e9
--- /dev/null
+++ b/modules/pam_warn/pam_warn.c
@@ -0,0 +1,92 @@
+/*
+ * pam_warn module
+ *
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <stdarg.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_ext.h>
+
+/* some syslogging */
+
+#define OBTAIN(item, value, default_value) do { \
+ (void) pam_get_item(pamh, item, &value); \
+ value = value ? value : default_value ; \
+} while (0)
+
+static void log_items(pam_handle_t *pamh, const char *function, int flags)
+{
+ const void *service=NULL, *user=NULL, *terminal=NULL,
+ *rhost=NULL, *ruser=NULL;
+
+ OBTAIN(PAM_SERVICE, service, "<unknown>");
+ OBTAIN(PAM_TTY, terminal, "<unknown>");
+ OBTAIN(PAM_USER, user, "<unknown>");
+ OBTAIN(PAM_RUSER, ruser, "<unknown>");
+ OBTAIN(PAM_RHOST, rhost, "<unknown>");
+
+ pam_syslog(pamh, LOG_NOTICE,
+ "function=[%s] flags=%#x service=[%s] terminal=[%s] user=[%s]"
+ " ruser=[%s] rhost=[%s]\n", function, flags,
+ (const char *) service, (const char *) terminal,
+ (const char *) user, (const char *) ruser,
+ (const char *) rhost);
+}
+
+/* --- authentication management functions (only) --- */
+
+int pam_sm_authenticate(pam_handle_t *pamh, int flags,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ log_items(pamh, __FUNCTION__, flags);
+ return PAM_IGNORE;
+}
+
+int pam_sm_setcred(pam_handle_t *pamh, int flags,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ log_items(pamh, __FUNCTION__, flags);
+ return PAM_IGNORE;
+}
+
+/* password updating functions */
+
+int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ log_items(pamh, __FUNCTION__, flags);
+ return PAM_IGNORE;
+}
+
+int
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ log_items(pamh, __FUNCTION__, flags);
+ return PAM_IGNORE;
+}
+
+int
+pam_sm_open_session(pam_handle_t *pamh, int flags,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ log_items(pamh, __FUNCTION__, flags);
+ return PAM_IGNORE;
+}
+
+int
+pam_sm_close_session(pam_handle_t *pamh, int flags,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ log_items(pamh, __FUNCTION__, flags);
+ return PAM_IGNORE;
+}
+
+/* end of module definition */
diff --git a/modules/pam_warn/tst-pam_warn b/modules/pam_warn/tst-pam_warn
new file mode 100755
index 0000000..0b48365
--- /dev/null
+++ b/modules/pam_warn/tst-pam_warn
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_warn.so
diff --git a/modules/pam_warn/tst-pam_warn-retval.c b/modules/pam_warn/tst-pam_warn-retval.c
new file mode 100644
index 0000000..49d6524
--- /dev/null
+++ b/modules/pam_warn/tst-pam_warn-retval.c
@@ -0,0 +1,88 @@
+/*
+ * Check pam_warn return values.
+ *
+ * Copyright (c) 2020 Dmitry V. Levin <ldv@altlinux.org>
+ */
+
+#include "test_assert.h"
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <security/pam_appl.h>
+
+#define MODULE_NAME "pam_warn"
+#define TEST_NAME "tst-" MODULE_NAME "-retval"
+
+static const char service_file[] = TEST_NAME ".service";
+static const char user_name[] = "";
+static struct pam_conv conv;
+
+int
+main(void)
+{
+ pam_handle_t *pamh = NULL;
+ FILE *fp;
+ char cwd[PATH_MAX];
+
+ ASSERT_NE(NULL, getcwd(cwd, sizeof(cwd)));
+
+ /* PAM_IGNORE -> PAM_PERM_DENIED */
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so\n"
+ "account required %s/.libs/%s.so\n"
+ "password required %s/.libs/%s.so\n"
+ "session required %s/.libs/%s.so\n",
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME,
+ cwd, MODULE_NAME));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, user_name, &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_PERM_DENIED, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_chauthtok(pamh, 0));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_PERM_DENIED, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ /* PAM_IGNORE -> PAM_SUCCESS */
+ ASSERT_NE(NULL, fp = fopen(service_file, "w"));
+ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n"
+ "auth required %s/.libs/%s.so\n"
+ "auth required %s/../pam_permit/.libs/pam_permit.so\n"
+ "account required %s/.libs/%s.so\n"
+ "account required %s/../pam_permit/.libs/pam_permit.so\n"
+ "password required %s/.libs/%s.so\n"
+ "password required %s/../pam_permit/.libs/pam_permit.so\n"
+ "session required %s/.libs/%s.so\n"
+ "session required %s/../pam_permit/.libs/pam_permit.so\n",
+ cwd, MODULE_NAME, cwd,
+ cwd, MODULE_NAME, cwd,
+ cwd, MODULE_NAME, cwd,
+ cwd, MODULE_NAME, cwd));
+ ASSERT_EQ(0, fclose(fp));
+
+ ASSERT_EQ(PAM_SUCCESS,
+ pam_start_confdir(service_file, user_name, &conv, ".", &pamh));
+ ASSERT_NE(NULL, pamh);
+ ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_setcred(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_acct_mgmt(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_chauthtok(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_open_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_close_session(pamh, 0));
+ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0));
+ pamh = NULL;
+
+ ASSERT_EQ(0, unlink(service_file));
+
+ return 0;
+}
diff --git a/modules/pam_wheel/Makefile.am b/modules/pam_wheel/Makefile.am
new file mode 100644
index 0000000..67ddc67
--- /dev/null
+++ b/modules/pam_wheel/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_wheel.8
+endif
+XMLS = README.xml pam_wheel.8.xml
+dist_check_SCRIPTS = tst-pam_wheel
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_wheel.la
+pam_wheel_la_LIBADD = $(top_builddir)/libpam/libpam.la
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_wheel/Makefile.in b/modules/pam_wheel/Makefile.in
new file mode 100644
index 0000000..fedf07a
--- /dev/null
+++ b/modules/pam_wheel/Makefile.in
@@ -0,0 +1,1150 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_wheel
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_wheel_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_wheel_la_SOURCES = pam_wheel.c
+pam_wheel_la_OBJECTS = pam_wheel.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_wheel.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_wheel.c
+DIST_SOURCES = pam_wheel.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_wheel.8
+XMLS = README.xml pam_wheel.8.xml
+dist_check_SCRIPTS = tst-pam_wheel
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_wheel.la
+pam_wheel_la_LIBADD = $(top_builddir)/libpam/libpam.la
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_wheel/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_wheel/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_wheel.la: $(pam_wheel_la_OBJECTS) $(pam_wheel_la_DEPENDENCIES) $(EXTRA_pam_wheel_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_wheel_la_OBJECTS) $(pam_wheel_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_wheel.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_wheel.log: tst-pam_wheel
+ @p='tst-pam_wheel'; \
+ b='tst-pam_wheel'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_wheel.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_wheel.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_wheel/README b/modules/pam_wheel/README
new file mode 100644
index 0000000..5dae4b6
--- /dev/null
+++ b/modules/pam_wheel/README
@@ -0,0 +1,61 @@
+pam_wheel — Only permit root access to members of group wheel
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+The pam_wheel PAM module is used to enforce the so-called wheel group. By
+default it permits access to the target user if the applicant user is a member
+of the wheel group. If no group with this name exist, the module is using the
+group with the group-ID 0.
+
+OPTIONS
+
+debug
+
+ Print debug information.
+
+deny
+
+ Reverse the sense of the auth operation: if the user is trying to get UID 0
+ access and is a member of the wheel group (or the group of the group
+ option), deny access. Conversely, if the user is not in the group, return
+ PAM_IGNORE (unless trust was also specified, in which case we return
+ PAM_SUCCESS).
+
+group=name
+
+ Instead of checking the wheel or GID 0 groups, use the name group to
+ perform the authentication.
+
+root_only
+
+ The check for wheel membership is done only when the target user UID is 0.
+
+trust
+
+ The pam_wheel module will return PAM_SUCCESS instead of PAM_IGNORE if the
+ user is a member of the wheel group (thus with a little play stacking the
+ modules the wheel members may be able to su to root without being prompted
+ for a passwd).
+
+use_uid
+
+ The check will be done against the real uid of the calling process, instead
+ of trying to obtain the user from the login session associated with the
+ terminal in use.
+
+EXAMPLES
+
+The root account gains access by default (rootok), only wheel members can
+become root (wheel) but Unix authenticate non-root applicants.
+
+su auth sufficient pam_rootok.so
+su auth required pam_wheel.so
+su auth required pam_unix.so
+
+
+AUTHOR
+
+pam_wheel was written by Cristian Gafton <gafton@redhat.com>.
+
diff --git a/modules/pam_wheel/README.xml b/modules/pam_wheel/README.xml
new file mode 100644
index 0000000..9e33d7f
--- /dev/null
+++ b/modules/pam_wheel/README.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_wheel.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_wheel.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_wheel-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_wheel.8.xml" xpointer='xpointer(//refsect1[@id = "pam_wheel-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_wheel.8.xml" xpointer='xpointer(//refsect1[@id = "pam_wheel-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_wheel.8.xml" xpointer='xpointer(//refsect1[@id = "pam_wheel-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_wheel.8.xml" xpointer='xpointer(//refsect1[@id = "pam_wheel-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_wheel/pam_wheel.8 b/modules/pam_wheel/pam_wheel.8
new file mode 100644
index 0000000..648046e
--- /dev/null
+++ b/modules/pam_wheel/pam_wheel.8
@@ -0,0 +1,147 @@
+'\" t
+.\" Title: pam_wheel
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_WHEEL" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_wheel \- Only permit root access to members of group wheel
+.SH "SYNOPSIS"
+.HP \w'\fBpam_wheel\&.so\fR\ 'u
+\fBpam_wheel\&.so\fR [debug] [deny] [group=\fIname\fR] [root_only] [trust] [use_uid]
+.SH "DESCRIPTION"
+.PP
+The pam_wheel PAM module is used to enforce the so\-called
+\fIwheel\fR
+group\&. By default it permits access to the target user if the applicant user is a member of the
+\fIwheel\fR
+group\&. If no group with this name exist, the module is using the group with the group\-ID
+\fB0\fR\&.
+.SH "OPTIONS"
+.PP
+\fBdebug\fR
+.RS 4
+Print debug information\&.
+.RE
+.PP
+\fBdeny\fR
+.RS 4
+Reverse the sense of the auth operation: if the user is trying to get UID 0 access and is a member of the wheel group (or the group of the
+\fBgroup\fR
+option), deny access\&. Conversely, if the user is not in the group, return PAM_IGNORE (unless
+\fBtrust\fR
+was also specified, in which case we return PAM_SUCCESS)\&.
+.RE
+.PP
+\fBgroup=\fR\fB\fIname\fR\fR
+.RS 4
+Instead of checking the wheel or GID 0 groups, use the
+\fB\fIname\fR\fR
+group to perform the authentication\&.
+.RE
+.PP
+\fBroot_only\fR
+.RS 4
+The check for wheel membership is done only when the target user UID is 0\&.
+.RE
+.PP
+\fBtrust\fR
+.RS 4
+The pam_wheel module will return PAM_SUCCESS instead of PAM_IGNORE if the user is a member of the wheel group (thus with a little play stacking the modules the wheel members may be able to su to root without being prompted for a passwd)\&.
+.RE
+.PP
+\fBuse_uid\fR
+.RS 4
+The check will be done against the real uid of the calling process, instead of trying to obtain the user from the login session associated with the terminal in use\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+The
+\fBauth\fR
+and
+\fBaccount\fR
+module types are provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_AUTH_ERR
+.RS 4
+Authentication failure\&.
+.RE
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_IGNORE
+.RS 4
+The return value should be ignored by PAM dispatch\&.
+.RE
+.PP
+PAM_PERM_DENY
+.RS 4
+Permission denied\&.
+.RE
+.PP
+PAM_SERVICE_ERR
+.RS 4
+Cannot determine the user name\&.
+.RE
+.PP
+PAM_SUCCESS
+.RS 4
+Success\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+User not known\&.
+.RE
+.SH "EXAMPLES"
+.PP
+The root account gains access by default (rootok), only wheel members can become root (wheel) but Unix authenticate non\-root applicants\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+su auth sufficient pam_rootok\&.so
+su auth required pam_wheel\&.so
+su auth required pam_unix\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "SEE ALSO"
+.PP
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_wheel was written by Cristian Gafton <gafton@redhat\&.com>\&.
diff --git a/modules/pam_wheel/pam_wheel.8.xml b/modules/pam_wheel/pam_wheel.8.xml
new file mode 100644
index 0000000..ee8c7d2
--- /dev/null
+++ b/modules/pam_wheel/pam_wheel.8.xml
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_wheel">
+
+ <refmeta>
+ <refentrytitle>pam_wheel</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_wheel-name">
+ <refname>pam_wheel</refname>
+ <refpurpose>Only permit root access to members of group wheel</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_wheel-cmdsynopsis">
+ <command>pam_wheel.so</command>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ deny
+ </arg>
+ <arg choice="opt">
+ group=<replaceable>name</replaceable>
+ </arg>
+ <arg choice="opt">
+ root_only
+ </arg>
+ <arg choice="opt">
+ trust
+ </arg>
+ <arg choice="opt">
+ use_uid
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_wheel-description">
+ <title>DESCRIPTION</title>
+ <para>
+ The pam_wheel PAM module is used to enforce the so-called
+ <emphasis>wheel</emphasis> group. By default it permits
+ access to the target user if the applicant user is a member of the
+ <emphasis>wheel</emphasis> group. If no group with this name exist,
+ the module is using the group with the group-ID
+ <emphasis remap='B'>0</emphasis>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_wheel-options">
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Print debug information.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>deny</option>
+ </term>
+ <listitem>
+ <para>
+ Reverse the sense of the auth operation: if the user
+ is trying to get UID 0 access and is a member of the
+ wheel group (or the group of the <option>group</option> option),
+ deny access. Conversely, if the user is not in the group, return
+ PAM_IGNORE (unless <option>trust</option> was also specified,
+ in which case we return PAM_SUCCESS).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>group=<replaceable>name</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Instead of checking the wheel or GID 0 groups, use
+ the <option><replaceable>name</replaceable></option> group
+ to perform the authentication.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>root_only</option>
+ </term>
+ <listitem>
+ <para>
+ The check for wheel membership is done only when the target user
+ UID is 0.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>trust</option>
+ </term>
+ <listitem>
+ <para>
+ The pam_wheel module will return PAM_SUCCESS instead
+ of PAM_IGNORE if the user is a member of the wheel group
+ (thus with a little play stacking the modules the wheel
+ members may be able to su to root without being prompted
+ for a passwd).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>use_uid</option>
+ </term>
+ <listitem>
+ <para>
+ The check will be done against the real uid of the calling process,
+ instead of trying to obtain the user from the login session
+ associated with the terminal in use.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_wheel-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ The <emphasis remap='B'>auth</emphasis> and
+ <emphasis remap='B'>account</emphasis> module types are provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_wheel-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_AUTH_ERR</term>
+ <listitem>
+ <para>
+ Authentication failure.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory buffer error.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_IGNORE</term>
+ <listitem>
+ <para>
+ The return value should be ignored by PAM dispatch.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_PERM_DENY</term>
+ <listitem>
+ <para>
+ Permission denied.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ Cannot determine the user name.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Success.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ User not known.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_wheel-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ The root account gains access by default (rootok), only wheel
+ members can become root (wheel) but Unix authenticate non-root
+ applicants.
+ <programlisting>
+su auth sufficient pam_rootok.so
+su auth required pam_wheel.so
+su auth required pam_unix.so
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_wheel-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_wheel-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_wheel was written by Cristian Gafton &lt;gafton@redhat.com&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_wheel/pam_wheel.c b/modules/pam_wheel/pam_wheel.c
new file mode 100644
index 0000000..179f56b
--- /dev/null
+++ b/modules/pam_wheel/pam_wheel.c
@@ -0,0 +1,301 @@
+/*
+ * pam_wheel module
+ *
+ * Written by Cristian Gafton <gafton@redhat.com> 1996/09/10
+ * See the end of the file for Copyright Information
+ *
+ *
+ * 1.2 - added 'deny' and 'group=' options
+ * 1.1 - added 'trust' option
+ * 1.0 - the code is working for at least another person, so... :-)
+ * 0.1 - use vsyslog instead of vfprintf/syslog in _pam_log
+ * - return PAM_IGNORE on success (take care of sloppy sysadmins..)
+ * - use pam_get_user instead of pam_get_item(...,PAM_USER,...)
+ * - a new arg use_uid to auth the current uid instead of the
+ * initial (logged in) one.
+ * 0.0 - first release
+ *
+ * TODO:
+ * - try to use make_remark from pam_unix/support.c
+ * - consider returning on failure PAM_FAIL_NOW if the user is not
+ * a wheel member.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+
+/*
+ * here, we make a definition for the externally accessible function
+ * in this file (this definition is required for static a module
+ * but strongly encouraged generally) it is used to instruct the
+ * modules include file to define the function prototypes.
+ */
+
+#include <security/pam_modules.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+#include "pam_inline.h"
+
+/* argument parsing */
+
+#define PAM_DEBUG_ARG 0x0001
+#define PAM_USE_UID_ARG 0x0002
+#define PAM_TRUST_ARG 0x0004
+#define PAM_DENY_ARG 0x0010
+#define PAM_ROOT_ONLY_ARG 0x0020
+
+static int
+_pam_parse (const pam_handle_t *pamh, int argc, const char **argv,
+ char *use_group, size_t group_length)
+{
+ int ctrl=0;
+
+ memset(use_group, '\0', group_length);
+
+ /* step through arguments */
+ for (ctrl=0; argc-- > 0; ++argv) {
+ const char *str;
+
+ /* generic options */
+
+ if (!strcmp(*argv,"debug"))
+ ctrl |= PAM_DEBUG_ARG;
+ else if (!strcmp(*argv,"use_uid"))
+ ctrl |= PAM_USE_UID_ARG;
+ else if (!strcmp(*argv,"trust"))
+ ctrl |= PAM_TRUST_ARG;
+ else if (!strcmp(*argv,"deny"))
+ ctrl |= PAM_DENY_ARG;
+ else if (!strcmp(*argv,"root_only"))
+ ctrl |= PAM_ROOT_ONLY_ARG;
+ else if ((str = pam_str_skip_prefix(*argv, "group=")) != NULL)
+ strncpy(use_group, str, group_length - 1);
+ else {
+ pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
+ }
+ }
+
+ return ctrl;
+}
+
+static int
+perform_check (pam_handle_t *pamh, int ctrl, const char *use_group)
+{
+ const char *username = NULL;
+ const char *fromsu;
+ struct passwd *pwd, *tpwd = NULL;
+ struct group *grp;
+ int retval = PAM_AUTH_ERR;
+
+ retval = pam_get_user(pamh, &username, NULL);
+ if (retval != PAM_SUCCESS) {
+ if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_DEBUG, "cannot determine user name: %s",
+ pam_strerror(pamh, retval));
+ }
+ return PAM_SERVICE_ERR;
+ }
+
+ pwd = pam_modutil_getpwnam (pamh, username);
+ if (!pwd) {
+ if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_NOTICE, "unknown user %s", username);
+ }
+ return PAM_USER_UNKNOWN;
+ }
+ if (ctrl & PAM_ROOT_ONLY_ARG) {
+ /* su to a non uid 0 account ? */
+ if (pwd->pw_uid != 0) {
+ return PAM_IGNORE;
+ }
+ }
+
+ if (ctrl & PAM_USE_UID_ARG) {
+ tpwd = pam_modutil_getpwuid (pamh, getuid());
+ if (tpwd == NULL) {
+ if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_NOTICE, "who is running me ?!");
+ }
+ return PAM_SERVICE_ERR;
+ }
+ fromsu = tpwd->pw_name;
+ } else {
+ fromsu = pam_modutil_getlogin(pamh);
+
+ /* if getlogin fails try a fallback to PAM_RUSER */
+ if (fromsu == NULL) {
+ const char *rhostname;
+
+ retval = pam_get_item(pamh, PAM_RHOST, (const void **)&rhostname);
+ if (retval != PAM_SUCCESS || rhostname == NULL) {
+ retval = pam_get_item(pamh, PAM_RUSER, (const void **)&fromsu);
+ }
+ }
+
+ if (fromsu != NULL) {
+ tpwd = pam_modutil_getpwnam (pamh, fromsu);
+ }
+
+ if (fromsu == NULL || tpwd == NULL) {
+ if (ctrl & PAM_DEBUG_ARG) {
+ pam_syslog(pamh, LOG_NOTICE, "who is running me ?!");
+ }
+ return PAM_SERVICE_ERR;
+ }
+ }
+
+ /*
+ * At this point fromsu = username-of-invoker; tpwd = pwd ptr for fromsu
+ */
+
+ if (!use_group[0]) {
+ if ((grp = pam_modutil_getgrnam (pamh, "wheel")) == NULL) {
+ grp = pam_modutil_getgrgid (pamh, 0);
+ }
+ } else {
+ grp = pam_modutil_getgrnam (pamh, use_group);
+ }
+
+ if (grp == NULL) {
+ if (ctrl & PAM_DEBUG_ARG) {
+ if (!use_group[0]) {
+ pam_syslog(pamh, LOG_NOTICE, "no members in a GID 0 group");
+ } else {
+ pam_syslog(pamh, LOG_NOTICE,
+ "no members in '%s' group", use_group);
+ }
+ }
+ if (ctrl & PAM_DENY_ARG) {
+ /* if this was meant to deny access to the members
+ * of this group and the group does not exist, allow
+ * access
+ */
+ return PAM_IGNORE;
+ } else {
+ return PAM_AUTH_ERR;
+ }
+ }
+
+ /*
+ * test if the user is a member of the group, or if the
+ * user has the "wheel" (sic) group as its primary group.
+ */
+
+ if (pam_modutil_user_in_group_uid_gid(pamh, tpwd->pw_uid, grp->gr_gid)) {
+
+ if (ctrl & PAM_DENY_ARG) {
+ retval = PAM_PERM_DENIED;
+
+ } else if (ctrl & PAM_TRUST_ARG) {
+ retval = PAM_SUCCESS; /* this can be a sufficient check */
+
+ } else {
+ retval = PAM_IGNORE;
+ }
+
+ } else {
+
+ if (ctrl & PAM_DENY_ARG) {
+
+ if (ctrl & PAM_TRUST_ARG) {
+ retval = PAM_SUCCESS; /* this can be a sufficient check */
+ } else {
+ retval = PAM_IGNORE;
+ }
+
+ } else {
+ retval = PAM_PERM_DENIED;
+ }
+ }
+
+ if (ctrl & PAM_DEBUG_ARG) {
+ if (retval == PAM_IGNORE) {
+ pam_syslog(pamh, LOG_NOTICE,
+ "Ignoring access request '%s' for '%s'",
+ fromsu, username);
+ } else {
+ pam_syslog(pamh, LOG_NOTICE, "Access %s to '%s' for '%s'",
+ (retval != PAM_SUCCESS) ? "denied":"granted",
+ fromsu, username);
+ }
+ }
+
+ return retval;
+}
+
+/* --- authentication management functions --- */
+
+int
+pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ char use_group[BUFSIZ];
+ int ctrl;
+
+ ctrl = _pam_parse(pamh, argc, argv, use_group, sizeof(use_group));
+
+ return perform_check(pamh, ctrl, use_group);
+}
+
+int
+pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED,
+ int argc UNUSED, const char **argv UNUSED)
+{
+ return PAM_SUCCESS;
+}
+
+int
+pam_sm_acct_mgmt (pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ char use_group[BUFSIZ];
+ int ctrl;
+
+ ctrl = _pam_parse(pamh, argc, argv, use_group, sizeof(use_group));
+
+ return perform_check(pamh, ctrl, use_group);
+}
+
+/*
+ * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1996, 1997
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/modules/pam_wheel/tst-pam_wheel b/modules/pam_wheel/tst-pam_wheel
new file mode 100755
index 0000000..4bf5d6a
--- /dev/null
+++ b/modules/pam_wheel/tst-pam_wheel
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_wheel.so
diff --git a/modules/pam_xauth/Makefile.am b/modules/pam_xauth/Makefile.am
new file mode 100644
index 0000000..7c55770
--- /dev/null
+++ b/modules/pam_xauth/Makefile.am
@@ -0,0 +1,33 @@
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+
+EXTRA_DIST = $(XMLS)
+
+if HAVE_DOC
+dist_man_MANS = pam_xauth.8
+endif
+XMLS = README.xml pam_xauth.8.xml
+dist_check_SCRIPTS = tst-pam_xauth
+TESTS = $(dist_check_SCRIPTS)
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+AM_LDFLAGS = -no-undefined -avoid-version -module
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+securelib_LTLIBRARIES = pam_xauth.la
+pam_xauth_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBSELINUX@
+
+if ENABLE_REGENERATE_MAN
+dist_noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
diff --git a/modules/pam_xauth/Makefile.in b/modules/pam_xauth/Makefile.in
new file mode 100644
index 0000000..4838634
--- /dev/null
+++ b/modules/pam_xauth/Makefile.in
@@ -0,0 +1,1150 @@
+# Makefile.in generated by automake 1.16.3 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2005, 2006, 2009 Thorsten Kukuk <kukuk@suse.de>
+#
+
+
+VPATH = @srcdir@
+am__is_gnu_make = { \
+ if test -z '$(MAKELEVEL)'; then \
+ false; \
+ elif test -n '$(MAKE_HOST)'; then \
+ true; \
+ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
+ true; \
+ else \
+ false; \
+ fi; \
+}
+am__make_running_with_option = \
+ case $${target_option-} in \
+ ?) ;; \
+ *) echo "am__make_running_with_option: internal error: invalid" \
+ "target option '$${target_option-}' specified" >&2; \
+ exit 1;; \
+ esac; \
+ has_opt=no; \
+ sane_makeflags=$$MAKEFLAGS; \
+ if $(am__is_gnu_make); then \
+ sane_makeflags=$$MFLAGS; \
+ else \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ bs=\\; \
+ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
+ esac; \
+ fi; \
+ skip_next=no; \
+ strip_trailopt () \
+ { \
+ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+ }; \
+ for flg in $$sane_makeflags; do \
+ test $$skip_next = yes && { skip_next=no; continue; }; \
+ case $$flg in \
+ *=*|--*) continue;; \
+ -*I) strip_trailopt 'I'; skip_next=yes;; \
+ -*I?*) strip_trailopt 'I';; \
+ -*O) strip_trailopt 'O'; skip_next=yes;; \
+ -*O?*) strip_trailopt 'O';; \
+ -*l) strip_trailopt 'l'; skip_next=yes;; \
+ -*l?*) strip_trailopt 'l';; \
+ -[dEDm]) skip_next=yes;; \
+ -[JT]) skip_next=yes;; \
+ esac; \
+ case $$flg in \
+ *$$target_option*) has_opt=yes; break;; \
+ esac; \
+ done; \
+ test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_xauth
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/attribute.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \
+ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
+ $(top_srcdir)/m4/ld-no-undefined.m4 \
+ $(top_srcdir)/m4/ld-z-now.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/libprelude.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 \
+ $(top_srcdir)/m4/warn_lang_flags.m4 \
+ $(top_srcdir)/m4/warnings.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+DIST_COMMON = $(srcdir)/Makefile.am $(dist_check_SCRIPTS) \
+ $(am__dist_noinst_DATA_DIST) $(am__DIST_COMMON)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
+am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_xauth_la_DEPENDENCIES = $(top_builddir)/libpam/libpam.la
+pam_xauth_la_SOURCES = pam_xauth.c
+pam_xauth_la_OBJECTS = pam_xauth.lo
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+am__v_lt_1 =
+AM_V_P = $(am__v_P_@AM_V@)
+am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_@AM_V@)
+am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
+am__v_GEN_0 = @echo " GEN " $@;
+am__v_GEN_1 =
+AM_V_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 =
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__maybe_remake_depfiles = depfiles
+am__depfiles_remade = ./$(DEPDIR)/pam_xauth.Plo
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
+SOURCES = pam_xauth.c
+DIST_SOURCES = pam_xauth.c
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(dist_man_MANS)
+am__dist_noinst_DATA_DIST = README
+DATA = $(dist_noinst_DATA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates. Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+ BEGIN { nonempty = 0; } \
+ { items[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique. This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+ list='$(am__tagged_files)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = { \
+ $(am__tty_colors_dummy); \
+ if test "X$(AM_COLOR_TESTS)" = Xno; then \
+ am__color_tests=no; \
+ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+ am__color_tests=yes; \
+ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+ am__color_tests=yes; \
+ fi; \
+ if test $$am__color_tests = yes; then \
+ red=''; \
+ grn=''; \
+ lgn=''; \
+ blu=''; \
+ mgn=''; \
+ brg=''; \
+ std=''; \
+ fi; \
+}
+am__recheck_rx = ^[ ]*:recheck:[ ]*
+am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
+am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+ recheck = 1; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ { \
+ if ((getline line2 < ($$0 ".log")) < 0) \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+ { \
+ recheck = 0; \
+ break; \
+ } \
+ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+ { \
+ break; \
+ } \
+ }; \
+ if (recheck) \
+ print $$0; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+ print "fatal: making $@: " msg | "cat >&2"; \
+ exit 1; \
+} \
+function rst_section(header) \
+{ \
+ print header; \
+ len = length(header); \
+ for (i = 1; i <= len; i = i + 1) \
+ printf "="; \
+ printf "\n\n"; \
+} \
+{ \
+ copy_in_global_log = 1; \
+ global_test_result = "RUN"; \
+ while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".trs"); \
+ if (line ~ /$(am__global_test_result_rx)/) \
+ { \
+ sub("$(am__global_test_result_rx)", "", line); \
+ sub("[ ]*$$", "", line); \
+ global_test_result = line; \
+ } \
+ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+ copy_in_global_log = 0; \
+ }; \
+ if (copy_in_global_log) \
+ { \
+ rst_section(global_test_result ": " $$0); \
+ while ((rc = (getline line < ($$0 ".log"))) != 0) \
+ { \
+ if (rc < 0) \
+ fatal("failed to read from " $$0 ".log"); \
+ print line; \
+ }; \
+ printf "\n"; \
+ }; \
+ close ($$0 ".trs"); \
+ close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+ --color-tests "$$am__color_tests" \
+ --enable-hard-errors "$$am__enable_hard_errors" \
+ --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test. Creates the
+# directory for the log if needed. Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log. Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup); \
+$(am__vpath_adj_setup) $(am__vpath_adj) \
+$(am__tty_colors); \
+srcdir=$(srcdir); export srcdir; \
+case "$@" in \
+ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
+ *) am__odir=.;; \
+esac; \
+test "x$$am__odir" = x"." || test -d "$$am__odir" \
+ || $(MKDIR_P) "$$am__odir" || exit $$?; \
+if test -f "./$$f"; then dir=./; \
+elif test -f "$$f"; then dir=; \
+else dir="$(srcdir)/"; fi; \
+tst=$$dir$$f; log='$@'; \
+if test -n '$(DISABLE_HARD_ERRORS)'; then \
+ am__enable_hard_errors=no; \
+else \
+ am__enable_hard_errors=yes; \
+fi; \
+case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
+ am__expect_failure=yes;; \
+ *) \
+ am__expect_failure=no;; \
+esac; \
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed). The result is saved in the shell variable
+# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+ bases='$(TEST_LOGS)'; \
+ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+ bases=`echo $$bases`
+AM_TESTSUITE_SUMMARY_HEADER = ' for $(PACKAGE_STRING)'
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+ case '$@' in \
+ */*) \
+ case '$*' in \
+ */*) b='$*';; \
+ *) b=`echo '$@' | sed 's/\.log$$//'`; \
+ esac;; \
+ *) \
+ b='$*';; \
+ esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+ $(TEST_LOG_FLAGS)
+am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \
+ $(top_srcdir)/build-aux/depcomp \
+ $(top_srcdir)/build-aux/test-driver
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+BUILD_CFLAGS = @BUILD_CFLAGS@
+BUILD_CPPFLAGS = @BUILD_CPPFLAGS@
+BUILD_LDFLAGS = @BUILD_LDFLAGS@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CRYPTO_LIBS = @CRYPTO_LIBS@
+CRYPT_CFLAGS = @CRYPT_CFLAGS@
+CRYPT_LIBS = @CRYPT_LIBS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+ECONF_CFLAGS = @ECONF_CFLAGS@
+ECONF_LIBS = @ECONF_LIBS@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXE_CFLAGS = @EXE_CFLAGS@
+EXE_LDFLAGS = @EXE_LDFLAGS@
+FGREP = @FGREP@
+FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
+MAKEINFO = @MAKEINFO@
+MANIFEST_TOOL = @MANIFEST_TOOL@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NIS_CFLAGS = @NIS_CFLAGS@
+NIS_LIBS = @NIS_LIBS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+NSL_CFLAGS = @NSL_CFLAGS@
+NSL_LIBS = @NSL_LIBS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
+PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRINGPARAM_HMAC = @STRINGPARAM_HMAC@
+STRINGPARAM_VENDORDIR = @STRINGPARAM_VENDORDIR@
+STRIP = @STRIP@
+TIRPC_CFLAGS = @TIRPC_CFLAGS@
+TIRPC_LIBS = @TIRPC_LIBS@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WARN_CFLAGS = @WARN_CFLAGS@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+systemdunitdir = @systemdunitdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAINTAINERCLEANFILES = $(MANS) README
+EXTRA_DIST = $(XMLS)
+@HAVE_DOC_TRUE@dist_man_MANS = pam_xauth.8
+XMLS = README.xml pam_xauth.8.xml
+dist_check_SCRIPTS = tst-pam_xauth
+TESTS = $(dist_check_SCRIPTS)
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ $(WARN_CFLAGS)
+
+AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1)
+securelib_LTLIBRARIES = pam_xauth.la
+pam_xauth_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBSELINUX@
+@ENABLE_REGENERATE_MAN_TRUE@dist_noinst_DATA = README
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .log .o .obj .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_xauth/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_xauth/Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(securelibdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(securelibdir)" || exit 1; \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(securelibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(securelibdir)"; \
+ }
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; test -n "$(securelibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$f"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; \
+ locs=`for p in $$list; do echo $$p; done | \
+ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
+ sort -u`; \
+ test -z "$$locs" || { \
+ echo rm -f $${locs}; \
+ rm -f $${locs}; \
+ }
+
+pam_xauth.la: $(pam_xauth_la_OBJECTS) $(pam_xauth_la_DEPENDENCIES) $(EXTRA_pam_xauth_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(LINK) -rpath $(securelibdir) $(pam_xauth_la_OBJECTS) $(pam_xauth_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_xauth.Plo@am__quote@ # am--include-marker
+
+$(am__depfiles_remade):
+ @$(MKDIR_P) $(@D)
+ @echo '# dummy' >$@-t && $(am__mv) $@-t $@
+
+am--depfiles: $(am__depfiles_remade)
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man8: $(dist_man_MANS)
+ @$(NORMAL_INSTALL)
+ @list1=''; \
+ list2='$(dist_man_MANS)'; \
+ test -n "$(man8dir)" \
+ && test -n "`echo $$list1$$list2`" \
+ || exit 0; \
+ echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
+ { for i in $$list1; do echo "$$i"; done; \
+ if test -n "$$list2"; then \
+ for i in $$list2; do echo "$$i"; done \
+ | sed -n '/\.8[a-z]*$$/p'; \
+ fi; \
+ } | while read p; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; echo "$$p"; \
+ done | \
+ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+ sed 'N;N;s,\n, ,g' | { \
+ list=; while read file base inst; do \
+ if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
+ fi; \
+ done; \
+ for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+ while read files; do \
+ test -z "$$files" || { \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
+ done; }
+
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list=''; test -n "$(man8dir)" || exit 0; \
+ files=`{ for i in $$list; do echo "$$i"; done; \
+ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+ sed -n '/\.8[a-z]*$$/p'; \
+ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
+ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
+ dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
+
+ID: $(am__tagged_files)
+ $(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ set x; \
+ here=`pwd`; \
+ $(am__define_uniq_tagged_files); \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+ $(am__define_uniq_tagged_files); \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+ list='$(am__tagged_files)'; \
+ case "$(srcdir)" in \
+ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+ *) sdir=$(subdir)/$(srcdir) ;; \
+ esac; \
+ for i in $$list; do \
+ if test -f "$$i"; then \
+ echo "$(subdir)/$$i"; \
+ else \
+ echo "$$sdir/$$i"; \
+ fi; \
+ done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+ rm -f $< $@
+ $(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+ @:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+ @$(am__set_TESTS_bases); \
+ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+ redo_bases=`for i in $$bases; do \
+ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+ done`; \
+ if test -n "$$redo_bases"; then \
+ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+ if $(am__make_dryrun); then :; else \
+ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+ fi; \
+ fi; \
+ if test -n "$$am__remaking_logs"; then \
+ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+ "recursion detected" >&2; \
+ elif test -n "$$redo_logs"; then \
+ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+ fi; \
+ if $(am__make_dryrun); then :; else \
+ st=0; \
+ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+ for i in $$redo_bases; do \
+ test -f $$i.trs && test -r $$i.trs \
+ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+ test -f $$i.log && test -r $$i.log \
+ || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+ done; \
+ test $$st -eq 0 || exit 1; \
+ fi
+ @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+ ws='[ ]'; \
+ results=`for b in $$bases; do echo $$b.trs; done`; \
+ test -n "$$results" || results=/dev/null; \
+ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
+ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
+ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
+ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
+ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+ if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+ success=true; \
+ else \
+ success=false; \
+ fi; \
+ br='==================='; br=$$br$$br$$br$$br; \
+ result_count () \
+ { \
+ if test x"$$1" = x"--maybe-color"; then \
+ maybe_colorize=yes; \
+ elif test x"$$1" = x"--no-color"; then \
+ maybe_colorize=no; \
+ else \
+ echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+ fi; \
+ shift; \
+ desc=$$1 count=$$2; \
+ if test $$maybe_colorize = yes && test $$count -gt 0; then \
+ color_start=$$3 color_end=$$std; \
+ else \
+ color_start= color_end=; \
+ fi; \
+ echo "$${color_start}# $$desc $$count$${color_end}"; \
+ }; \
+ create_testsuite_report () \
+ { \
+ result_count $$1 "TOTAL:" $$all "$$brg"; \
+ result_count $$1 "PASS: " $$pass "$$grn"; \
+ result_count $$1 "SKIP: " $$skip "$$blu"; \
+ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+ result_count $$1 "FAIL: " $$fail "$$red"; \
+ result_count $$1 "XPASS:" $$xpass "$$red"; \
+ result_count $$1 "ERROR:" $$error "$$mgn"; \
+ }; \
+ { \
+ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
+ $(am__rst_title); \
+ create_testsuite_report --no-color; \
+ echo; \
+ echo ".. contents:: :depth: 2"; \
+ echo; \
+ for b in $$bases; do echo $$b; done \
+ | $(am__create_global_log); \
+ } >$(TEST_SUITE_LOG).tmp || exit 1; \
+ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
+ if $$success; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
+ fi; \
+ echo "$${col}$$br$${std}"; \
+ echo "$${col}Testsuite summary"$(AM_TESTSUITE_SUMMARY_HEADER)"$${std}"; \
+ echo "$${col}$$br$${std}"; \
+ create_testsuite_report --maybe-color; \
+ echo "$$col$$br$$std"; \
+ if $$success; then :; else \
+ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
+ if test -n "$(PACKAGE_BUGREPORT)"; then \
+ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
+ fi; \
+ echo "$$col$$br$$std"; \
+ fi; \
+ $$success || exit 1
+
+check-TESTS: $(dist_check_SCRIPTS)
+ @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
+ @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+ exit $$?;
+recheck: all $(dist_check_SCRIPTS)
+ @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+ @set +e; $(am__set_TESTS_bases); \
+ bases=`for i in $$bases; do echo $$i; done \
+ | $(am__list_recheck_tests)` || exit 1; \
+ log_list=`for i in $$bases; do echo $$i.log; done`; \
+ log_list=`echo $$log_list`; \
+ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+ am__force_recheck=am--force-recheck \
+ TEST_LOGS="$$log_list"; \
+ exit $$?
+tst-pam_xauth.log: tst-pam_xauth
+ @p='tst-pam_xauth'; \
+ b='tst-pam_xauth'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+ @p='$<'; \
+ $(am__set_b); \
+ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
+@am__EXEEXT_TRUE@.test$(EXEEXT).log:
+@am__EXEEXT_TRUE@ @p='$<'; \
+@am__EXEEXT_TRUE@ $(am__set_b); \
+@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
+@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) distdir-am
+
+distdir-am: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(dist_check_SCRIPTS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
+mostlyclean-generic:
+ -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+ -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+ -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -f ./$(DEPDIR)/pam_xauth.Plo
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man: install-man8
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f ./$(DEPDIR)/pam_xauth.Plo
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man8
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-TESTS \
+ check-am clean clean-generic clean-libtool \
+ clean-securelibLTLIBRARIES cscopelist-am ctags ctags-am \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man8 install-pdf \
+ install-pdf-am install-ps install-ps-am \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ recheck tags tags-am uninstall uninstall-am uninstall-man \
+ uninstall-man8 uninstall-securelibLTLIBRARIES
+
+.PRECIOUS: Makefile
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/pam_xauth/README b/modules/pam_xauth/README
new file mode 100644
index 0000000..a32822d
--- /dev/null
+++ b/modules/pam_xauth/README
@@ -0,0 +1,90 @@
+pam_xauth — PAM module to forward xauth keys between users
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+DESCRIPTION
+
+The pam_xauth PAM module is designed to forward xauth keys (sometimes referred
+to as "cookies") between users.
+
+Without pam_xauth, when xauth is enabled and a user uses the su(1) command to
+assume another user's privileges, that user is no longer able to access the
+original user's X display because the new user does not have the key needed to
+access the display. pam_xauth solves the problem by forwarding the key from the
+user running su (the source user) to the user whose identity the source user is
+assuming (the target user) when the session is created, and destroying the key
+when the session is torn down.
+
+This means, for example, that when you run su(1) from an xterm session, you
+will be able to run X programs without explicitly dealing with the xauth(1)
+xauth command or ~/.Xauthority files.
+
+pam_xauth will only forward keys if xauth can list a key connected to the
+$DISPLAY environment variable.
+
+Primitive access control is provided by ~/.xauth/export in the invoking user's
+home directory and ~/.xauth/import in the target user's home directory.
+
+If a user has a ~/.xauth/import file, the user will only receive cookies from
+users listed in the file. If there is no ~/.xauth/import file, the user will
+accept cookies from any other user.
+
+If a user has a .xauth/export file, the user will only forward cookies to users
+listed in the file. If there is no ~/.xauth/export file, and the invoking user
+is not root, the user will forward cookies to any other user. If there is no ~
+/.xauth/export file, and the invoking user is root, the user will not forward
+cookies to other users.
+
+Both the import and export files support wildcards (such as *). Both the import
+and export files can be empty, signifying that no users are allowed.
+
+OPTIONS
+
+debug
+
+ Print debug information.
+
+xauthpath=/path/to/xauth
+
+ Specify the path the xauth program (it is expected in /usr/X11R6/bin/xauth,
+ /usr/bin/xauth, or /usr/bin/X11/xauth by default).
+
+systemuser=UID
+
+ Specify the highest UID which will be assumed to belong to a "system" user.
+ pam_xauth will refuse to forward credentials to users with UID less than or
+ equal to this number, except for root and the "targetuser", if specified.
+
+targetuser=UID
+
+ Specify a single target UID which is exempt from the systemuser check.
+
+EXAMPLES
+
+Add the following line to /etc/pam.d/su to forward xauth keys between users
+when calling su:
+
+session optional pam_xauth.so
+
+
+IMPLEMENTATION DETAILS
+
+pam_xauth will work only if it is used from a setuid application in which the
+getuid() call returns the id of the user running the application, and for which
+PAM can supply the name of the account that the user is attempting to assume.
+The typical application of this type is su(1). The application must call both
+pam_open_session() and pam_close_session() with the ruid set to the uid of the
+calling user and the euid set to root, and must have provided as the PAM_USER
+item the name of the target user.
+
+pam_xauth calls xauth(1) as the source user to extract the key for $DISPLAY,
+then calls xauth as the target user to merge the key into the a temporary
+database and later remove the database.
+
+pam_xauth cannot be told to not remove the keys when the session is closed.
+
+AUTHOR
+
+pam_xauth was written by Nalin Dahyabhai <nalin@redhat.com>, based on original
+version by Michael K. Johnson <johnsonm@redhat.com>.
+
diff --git a/modules/pam_xauth/README.xml b/modules/pam_xauth/README.xml
new file mode 100644
index 0000000..adefbd9
--- /dev/null
+++ b/modules/pam_xauth/README.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+"http://www.docbook.org/xml/4.3/docbookx.dtd"
+[
+<!--
+<!ENTITY pamaccess SYSTEM "pam_xauth.8.xml">
+-->
+]>
+
+<article>
+
+ <articleinfo>
+
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_xauth.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_xauth-name"]/*)'/>
+ </title>
+
+ </articleinfo>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_xauth.8.xml" xpointer='xpointer(//refsect1[@id = "pam_xauth-description"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_xauth.8.xml" xpointer='xpointer(//refsect1[@id = "pam_xauth-options"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_xauth.8.xml" xpointer='xpointer(//refsect1[@id = "pam_xauth-examples"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_xauth.8.xml" xpointer='xpointer(//refsect1[@id = "pam_xauth-implementation"]/*)'/>
+ </section>
+
+ <section>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_xauth.8.xml" xpointer='xpointer(//refsect1[@id = "pam_xauth-author"]/*)'/>
+ </section>
+
+</article>
diff --git a/modules/pam_xauth/pam_xauth.8 b/modules/pam_xauth/pam_xauth.8
new file mode 100644
index 0000000..90177fb
--- /dev/null
+++ b/modules/pam_xauth/pam_xauth.8
@@ -0,0 +1,183 @@
+'\" t
+.\" Title: pam_xauth
+.\" Author: [see the "AUTHOR" section]
+.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
+.\" Date: 09/03/2021
+.\" Manual: Linux-PAM Manual
+.\" Source: Linux-PAM Manual
+.\" Language: English
+.\"
+.TH "PAM_XAUTH" "8" "09/03/2021" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * Define some portability stuff
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
+.\" disable hyphenation
+.nh
+.\" disable justification (adjust text to left margin only)
+.ad l
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "NAME"
+pam_xauth \- PAM module to forward xauth keys between users
+.SH "SYNOPSIS"
+.HP \w'\fBpam_xauth\&.so\fR\ 'u
+\fBpam_xauth\&.so\fR [debug] [xauthpath=\fI/path/to/xauth\fR] [systemuser=\fIUID\fR] [targetuser=\fIUID\fR]
+.SH "DESCRIPTION"
+.PP
+The pam_xauth PAM module is designed to forward xauth keys (sometimes referred to as "cookies") between users\&.
+.PP
+Without pam_xauth, when xauth is enabled and a user uses the
+\fBsu\fR(1)
+command to assume another user\*(Aqs privileges, that user is no longer able to access the original user\*(Aqs X display because the new user does not have the key needed to access the display\&. pam_xauth solves the problem by forwarding the key from the user running su (the source user) to the user whose identity the source user is assuming (the target user) when the session is created, and destroying the key when the session is torn down\&.
+.PP
+This means, for example, that when you run
+\fBsu\fR(1)
+from an xterm session, you will be able to run X programs without explicitly dealing with the
+\fBxauth\fR(1)
+xauth command or ~/\&.Xauthority files\&.
+.PP
+pam_xauth will only forward keys if xauth can list a key connected to the $DISPLAY environment variable\&.
+.PP
+Primitive access control is provided by
+~/\&.xauth/export
+in the invoking user\*(Aqs home directory and
+~/\&.xauth/import
+in the target user\*(Aqs home directory\&.
+.PP
+If a user has a
+~/\&.xauth/import
+file, the user will only receive cookies from users listed in the file\&. If there is no
+~/\&.xauth/import
+file, the user will accept cookies from any other user\&.
+.PP
+If a user has a
+\&.xauth/export
+file, the user will only forward cookies to users listed in the file\&. If there is no
+~/\&.xauth/export
+file, and the invoking user is not
+\fBroot\fR, the user will forward cookies to any other user\&. If there is no
+~/\&.xauth/export
+file, and the invoking user is
+\fBroot\fR, the user will
+\fInot\fR
+forward cookies to other users\&.
+.PP
+Both the import and export files support wildcards (such as
+\fI*\fR)\&. Both the import and export files can be empty, signifying that no users are allowed\&.
+.SH "OPTIONS"
+.PP
+\fBdebug\fR
+.RS 4
+Print debug information\&.
+.RE
+.PP
+\fBxauthpath=\fR\fB\fI/path/to/xauth\fR\fR
+.RS 4
+Specify the path the xauth program (it is expected in
+/usr/X11R6/bin/xauth,
+/usr/bin/xauth, or
+/usr/bin/X11/xauth
+by default)\&.
+.RE
+.PP
+\fBsystemuser=\fR\fB\fIUID\fR\fR
+.RS 4
+Specify the highest UID which will be assumed to belong to a "system" user\&. pam_xauth will refuse to forward credentials to users with UID less than or equal to this number, except for root and the "targetuser", if specified\&.
+.RE
+.PP
+\fBtargetuser=\fR\fB\fIUID\fR\fR
+.RS 4
+Specify a single target UID which is exempt from the systemuser check\&.
+.RE
+.SH "MODULE TYPES PROVIDED"
+.PP
+Only the
+\fBsession\fR
+type is provided\&.
+.SH "RETURN VALUES"
+.PP
+PAM_BUF_ERR
+.RS 4
+Memory buffer error\&.
+.RE
+.PP
+PAM_PERM_DENIED
+.RS 4
+Permission denied by import/export file\&.
+.RE
+.PP
+PAM_SESSION_ERR
+.RS 4
+Cannot determine user name, UID or access users home directory\&.
+.RE
+.PP
+PAM_SUCCESS
+.RS 4
+Success\&.
+.RE
+.PP
+PAM_USER_UNKNOWN
+.RS 4
+User not known\&.
+.RE
+.SH "EXAMPLES"
+.PP
+Add the following line to
+/etc/pam\&.d/su
+to forward xauth keys between users when calling su:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+session optional pam_xauth\&.so
+
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+.SH "IMPLEMENTATION DETAILS"
+.PP
+pam_xauth will work
+\fIonly\fR
+if it is used from a setuid application in which the
+\fBgetuid\fR() call returns the id of the user running the application, and for which PAM can supply the name of the account that the user is attempting to assume\&. The typical application of this type is
+\fBsu\fR(1)\&. The application must call both
+\fBpam_open_session\fR() and
+\fBpam_close_session\fR() with the ruid set to the uid of the calling user and the euid set to root, and must have provided as the PAM_USER item the name of the target user\&.
+.PP
+pam_xauth calls
+\fBxauth\fR(1)
+as the source user to extract the key for $DISPLAY, then calls xauth as the target user to merge the key into the a temporary database and later remove the database\&.
+.PP
+pam_xauth cannot be told to not remove the keys when the session is closed\&.
+.SH "FILES"
+.PP
+~/\&.xauth/import
+.RS 4
+XXX
+.RE
+.PP
+~/\&.xauth/export
+.RS 4
+XXX
+.RE
+.SH "SEE ALSO"
+.PP
+\fBpam.conf\fR(5),
+\fBpam.d\fR(5),
+\fBpam\fR(8)
+.SH "AUTHOR"
+.PP
+pam_xauth was written by Nalin Dahyabhai <nalin@redhat\&.com>, based on original version by Michael K\&. Johnson <johnsonm@redhat\&.com>\&.
diff --git a/modules/pam_xauth/pam_xauth.8.xml b/modules/pam_xauth/pam_xauth.8.xml
new file mode 100644
index 0000000..08c06cf
--- /dev/null
+++ b/modules/pam_xauth/pam_xauth.8.xml
@@ -0,0 +1,293 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="pam_xauth">
+
+ <refmeta>
+ <refentrytitle>pam_xauth</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id="pam_xauth-name">
+ <refname>pam_xauth</refname>
+ <refpurpose>PAM module to forward xauth keys between users</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_xauth-cmdsynopsis">
+ <command>pam_xauth.so</command>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ xauthpath=<replaceable>/path/to/xauth</replaceable>
+ </arg>
+ <arg choice="opt">
+ systemuser=<replaceable>UID</replaceable>
+ </arg>
+ <arg choice="opt">
+ targetuser=<replaceable>UID</replaceable>
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+ <refsect1 id="pam_xauth-description">
+ <title>DESCRIPTION</title>
+ <para>
+ The pam_xauth PAM module is designed to forward xauth keys
+ (sometimes referred to as "cookies") between users.
+ </para>
+ <para>
+ Without pam_xauth, when xauth is enabled and a user uses the
+ <citerefentry>
+ <refentrytitle>su</refentrytitle><manvolnum>1</manvolnum>
+ </citerefentry> command to assume another user's privileges,
+ that user is no longer able to access the original user's X display
+ because the new user does not have the key needed to access the
+ display. pam_xauth solves the problem by forwarding the key from
+ the user running su (the source user) to the user whose identity the
+ source user is assuming (the target user) when the session is created,
+ and destroying the key when the session is torn down.
+ </para>
+ <para>
+ This means, for example, that when you run
+ <citerefentry>
+ <refentrytitle>su</refentrytitle><manvolnum>1</manvolnum>
+ </citerefentry> from an xterm session, you will be able to run
+ X programs without explicitly dealing with the
+ <citerefentry>
+ <refentrytitle>xauth</refentrytitle><manvolnum>1</manvolnum>
+ </citerefentry> xauth command or ~/.Xauthority files.
+ </para>
+ <para>
+ pam_xauth will only forward keys if xauth can list a key connected
+ to the $DISPLAY environment variable.
+ </para>
+ <para>
+ Primitive access control is provided by
+ <filename>~/.xauth/export</filename> in the invoking user's home
+ directory and <filename>~/.xauth/import</filename> in the target
+ user's home directory.
+ </para>
+ <para>
+ If a user has a <filename>~/.xauth/import</filename> file, the user
+ will only receive cookies from users listed in the file. If there is
+ no <filename>~/.xauth/import</filename> file, the user will accept
+ cookies from any other user.
+ </para>
+ <para>
+ If a user has a <filename>.xauth/export</filename> file, the user will
+ only forward cookies to users listed in the file. If there is no
+ <filename>~/.xauth/export</filename> file, and the invoking user is
+ not <emphasis remap='B'>root</emphasis>, the user will forward cookies
+ to any other user. If there is no <filename>~/.xauth/export</filename>
+ file, and the invoking user is <emphasis remap='B'>root</emphasis>,
+ the user will <emphasis remap='I'>not</emphasis> forward cookies to
+ other users.
+ </para>
+ <para>
+ Both the import and export files support wildcards (such as
+ <emphasis remap='I'>*</emphasis>). Both the import and export files
+ can be empty, signifying that no users are allowed.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_xauth-options">
+ <title>OPTIONS</title>
+ <variablelist>
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ Print debug information.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>xauthpath=<replaceable>/path/to/xauth</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Specify the path the xauth program (it is expected in
+ <filename>/usr/X11R6/bin/xauth</filename>,
+ <filename>/usr/bin/xauth</filename>, or
+ <filename>/usr/bin/X11/xauth</filename> by default).
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>systemuser=<replaceable>UID</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Specify the highest UID which will be assumed to belong to a
+ "system" user. pam_xauth will refuse to forward credentials to
+ users with UID less than or equal to this number, except for
+ root and the "targetuser", if specified.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>
+ <option>targetuser=<replaceable>UID</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Specify a single target UID which is exempt from the
+ systemuser check.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_xauth-types">
+ <title>MODULE TYPES PROVIDED</title>
+ <para>
+ Only the <emphasis remap='B'>session</emphasis> type is provided.
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_xauth-return_values'>
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_BUF_ERR</term>
+ <listitem>
+ <para>
+ Memory buffer error.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_PERM_DENIED</term>
+ <listitem>
+ <para>
+ Permission denied by import/export file.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SESSION_ERR</term>
+ <listitem>
+ <para>
+ Cannot determine user name, UID or access users home directory.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Success.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>PAM_USER_UNKNOWN</term>
+ <listitem>
+ <para>
+ User not known.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id='pam_xauth-examples'>
+ <title>EXAMPLES</title>
+ <para>
+ Add the following line to <filename>/etc/pam.d/su</filename> to
+ forward xauth keys between users when calling su:
+ <programlisting>
+session optional pam_xauth.so
+ </programlisting>
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_xauth-implementation">
+ <title>IMPLEMENTATION DETAILS</title>
+ <para>
+ pam_xauth will work <emphasis remap='I'>only</emphasis> if it is
+ used from a setuid application in which the
+ <function>getuid</function>() call returns the id of the user
+ running the application, and for which PAM can supply the name
+ of the account that the user is attempting to assume. The typical
+ application of this type is
+ <citerefentry>
+ <refentrytitle>su</refentrytitle><manvolnum>1</manvolnum>
+ </citerefentry>.
+ The application must call both <function>pam_open_session</function>()
+ and <function>pam_close_session</function>() with the ruid set to the
+ uid of the calling user and the euid set to root, and must have
+ provided as the PAM_USER item the name of the target user.
+ </para>
+ <para>
+ pam_xauth calls
+ <citerefentry>
+ <refentrytitle>xauth</refentrytitle><manvolnum>1</manvolnum>
+ </citerefentry> as the source user to extract the key for $DISPLAY,
+ then calls xauth as the target user to merge the key into the a
+ temporary database and later remove the database.
+ </para>
+ <para>
+ pam_xauth cannot be told to not remove the keys when the session
+ is closed.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_lastlog-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>~/.xauth/import</filename></term>
+ <listitem>
+ <para>XXX</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><filename>~/.xauth/export</filename></term>
+ <listitem>
+ <para>XXX</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+
+ <refsect1 id='pam_xauth-see_also'>
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id='pam_xauth-author'>
+ <title>AUTHOR</title>
+ <para>
+ pam_xauth was written by Nalin Dahyabhai &lt;nalin@redhat.com&gt;,
+ based on original version by
+ Michael K. Johnson &lt;johnsonm@redhat.com&gt;.
+ </para>
+ </refsect1>
+
+</refentry>
diff --git a/modules/pam_xauth/pam_xauth.c b/modules/pam_xauth/pam_xauth.c
new file mode 100644
index 0000000..03f8dc7
--- /dev/null
+++ b/modules/pam_xauth/pam_xauth.c
@@ -0,0 +1,803 @@
+/*
+ * pam_xauth module
+ *
+ * Copyright 2001-2003 Red Hat, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fnmatch.h>
+#include <grp.h>
+#include <limits.h>
+#include <netdb.h>
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+#include <security/pam_modutil.h>
+#include <security/pam_ext.h>
+
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#include <selinux/label.h>
+#endif
+
+#include "pam_cc_compat.h"
+#include "pam_inline.h"
+
+#define DATANAME "pam_xauth_cookie_file"
+#define XAUTHENV "XAUTHORITY"
+#define HOMEENV "HOME"
+#define XAUTHDEF ".Xauthority"
+#define XAUTHTMP ".xauthXXXXXX"
+
+/* Hurd compatibility */
+#ifndef PATH_MAX
+#define PATH_MAX 4096
+#endif
+
+/* Possible paths to xauth executable */
+static const char * const xauthpaths[] = {
+#ifdef PAM_PATH_XAUTH
+ PAM_PATH_XAUTH,
+#endif
+ "/usr/X11R6/bin/xauth",
+ "/usr/bin/xauth",
+ "/usr/bin/X11/xauth"
+};
+
+/* Run a given command (with a NULL-terminated argument list), feeding it the
+ * given input on stdin, and storing any output it generates. */
+static int
+run_coprocess(pam_handle_t *pamh, const char *input, char **output,
+ uid_t uid, gid_t gid, const char *command, ...)
+{
+ int ipipe[2], opipe[2], i;
+ char buf[LINE_MAX];
+ pid_t child;
+ char *buffer = NULL;
+ size_t buffer_size = 0;
+ va_list ap;
+
+ *output = NULL;
+
+ /* Create stdio pipery. */
+ if (pipe(ipipe) == -1) {
+ pam_syslog(pamh, LOG_ERR, "Could not create pipe: %m");
+ return -1;
+ }
+ if (pipe(opipe) == -1) {
+ pam_syslog(pamh, LOG_ERR, "Could not create pipe: %m");
+ close(ipipe[0]);
+ close(ipipe[1]);
+ return -1;
+ }
+
+ /* Fork off a child. */
+ child = fork();
+ if (child == -1) {
+ pam_syslog(pamh, LOG_ERR, "Could not fork: %m");
+ close(ipipe[0]);
+ close(ipipe[1]);
+ close(opipe[0]);
+ close(opipe[1]);
+ return -1;
+ }
+
+ if (child == 0) {
+ /* We're the child. */
+ size_t j;
+ const char *args[10];
+ /* Drop privileges. */
+ if (setgid(gid) == -1)
+ {
+ int err = errno;
+ pam_syslog (pamh, LOG_ERR, "setgid(%lu) failed: %m",
+ (unsigned long) getegid ());
+ _exit (err);
+ }
+ if (setgroups(0, NULL) == -1)
+ {
+ int err = errno;
+ pam_syslog (pamh, LOG_ERR, "setgroups() failed: %m");
+ _exit (err);
+ }
+ if (setuid(uid) == -1)
+ {
+ int err = errno;
+ pam_syslog (pamh, LOG_ERR, "setuid(%lu) failed: %m",
+ (unsigned long) geteuid ());
+ _exit (err);
+ }
+ /* Set the pipe descriptors up as stdin and stdout, and close
+ * everything else, including the original values for the
+ * descriptors. */
+ if (dup2(ipipe[0], STDIN_FILENO) != STDIN_FILENO) {
+ int err = errno;
+ pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", "stdin");
+ _exit(err);
+ }
+ if (dup2(opipe[1], STDOUT_FILENO) != STDOUT_FILENO) {
+ int err = errno;
+ pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", "stdout");
+ _exit(err);
+ }
+ if (pam_modutil_sanitize_helper_fds(pamh, PAM_MODUTIL_IGNORE_FD,
+ PAM_MODUTIL_IGNORE_FD,
+ PAM_MODUTIL_NULL_FD) < 0) {
+ _exit(1);
+ }
+ /* Initialize the argument list. */
+ memset(args, 0, sizeof(args));
+ /* Convert the varargs list into a regular array of strings. */
+ va_start(ap, command);
+ args[0] = command;
+ for (j = 1; j < PAM_ARRAY_SIZE(args) - 1; j++) {
+ args[j] = va_arg(ap, const char*);
+ if (args[j] == NULL) {
+ break;
+ }
+ }
+ /* Run the command. */
+ DIAG_PUSH_IGNORE_CAST_QUAL;
+ execv(command, (char *const *) args);
+ DIAG_POP_IGNORE_CAST_QUAL;
+ /* Never reached. */
+ _exit(1);
+ }
+
+ /* We're the parent, so close the other ends of the pipes. */
+ close(opipe[1]);
+ /* Send input to the process (if we have any), then send an EOF. */
+ if (input) {
+ (void)pam_modutil_write(ipipe[1], input, strlen(input));
+ }
+ close(ipipe[0]); /* close here to avoid possible SIGPIPE above */
+ close(ipipe[1]);
+
+ /* Read data output until we run out of stuff to read. */
+ i = pam_modutil_read(opipe[0], buf, sizeof(buf));
+ while ((i != 0) && (i != -1)) {
+ char *tmp;
+ /* Resize the buffer to hold the data. */
+ tmp = realloc(buffer, buffer_size + i + 1);
+ if (tmp == NULL) {
+ /* Uh-oh, bail. */
+ if (buffer != NULL) {
+ free(buffer);
+ }
+ close(opipe[0]);
+ waitpid(child, NULL, 0);
+ return -1;
+ }
+ /* Save the new buffer location, copy the newly-read data into
+ * the buffer, and make sure the result will be
+ * nul-terminated. */
+ buffer = tmp;
+ memcpy(buffer + buffer_size, buf, i);
+ buffer[buffer_size + i] = '\0';
+ buffer_size += i;
+ /* Try to read again. */
+ i = pam_modutil_read(opipe[0], buf, sizeof(buf));
+ }
+ /* No more data. Clean up and return data. */
+ close(opipe[0]);
+ *output = buffer;
+ waitpid(child, NULL, 0);
+ return 0;
+}
+
+/* Free a data item. */
+static void
+cleanup (pam_handle_t *pamh UNUSED, void *data, int err UNUSED)
+{
+ free (data);
+}
+
+/* Check if we want to allow export to the other user, or import from the
+ * other user. */
+static int
+check_acl(pam_handle_t *pamh,
+ const char *sense, const char *this_user, const char *other_user,
+ int noent_code, int debug)
+{
+ char path[PATH_MAX];
+ struct passwd *pwd;
+ FILE *fp = NULL;
+ int i, fd = -1, save_errno;
+ struct stat st;
+ PAM_MODUTIL_DEF_PRIVS(privs);
+
+ /* Check this user's <sense> file. */
+ pwd = pam_modutil_getpwnam(pamh, this_user);
+ if (pwd == NULL) {
+ pam_syslog(pamh, LOG_ERR,
+ "error determining home directory for '%s'",
+ this_user);
+ return PAM_SESSION_ERR;
+ }
+ /* Figure out what that file is really named. */
+ i = snprintf(path, sizeof(path), "%s/.xauth/%s", pwd->pw_dir, sense);
+ if ((i >= (int)sizeof(path)) || (i < 0)) {
+ pam_syslog(pamh, LOG_ERR,
+ "name of user's home directory is too long");
+ return PAM_SESSION_ERR;
+ }
+ if (pam_modutil_drop_priv(pamh, &privs, pwd))
+ return PAM_SESSION_ERR;
+ if (!stat(path, &st)) {
+ if (!S_ISREG(st.st_mode))
+ errno = EINVAL;
+ else
+ fd = open(path, O_RDONLY | O_NOCTTY);
+ }
+ save_errno = errno;
+ if (pam_modutil_regain_priv(pamh, &privs)) {
+ if (fd >= 0)
+ close(fd);
+ return PAM_SESSION_ERR;
+ }
+ if (fd >= 0) {
+ if (!fstat(fd, &st)) {
+ if (!S_ISREG(st.st_mode))
+ errno = EINVAL;
+ else
+ fp = fdopen(fd, "r");
+ }
+ if (!fp) {
+ save_errno = errno;
+ close(fd);
+ }
+ }
+ if (fp) {
+ char buf[LINE_MAX], *tmp;
+ /* Scan the file for a list of specs of users to "trust". */
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+ tmp = memchr(buf, '\r', sizeof(buf));
+ if (tmp != NULL) {
+ *tmp = '\0';
+ }
+ tmp = memchr(buf, '\n', sizeof(buf));
+ if (tmp != NULL) {
+ *tmp = '\0';
+ }
+ if (fnmatch(buf, other_user, 0) == 0) {
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "%s %s allowed by %s",
+ other_user, sense, path);
+ }
+ fclose(fp);
+ return PAM_SUCCESS;
+ }
+ }
+ /* If there's no match in the file, we fail. */
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG, "%s not listed in %s",
+ other_user, path);
+ }
+ fclose(fp);
+ return PAM_PERM_DENIED;
+ } else {
+ /* Default to okay if the file doesn't exist. */
+ errno = save_errno;
+ switch (errno) {
+ case ENOENT:
+ if (noent_code == PAM_SUCCESS) {
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "%s does not exist, ignoring",
+ path);
+ }
+ } else {
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "%s does not exist, failing",
+ path);
+ }
+ }
+ return noent_code;
+ default:
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "error opening %s: %m", path);
+ }
+ return PAM_PERM_DENIED;
+ }
+ }
+}
+
+int
+pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ char *cookiefile = NULL, *xauthority = NULL,
+ *cookie = NULL, *display = NULL, *tmp = NULL,
+ *xauthlocalhostname = NULL;
+ const char *user, *xauth = NULL;
+ struct passwd *tpwd, *rpwd;
+ int fd, i, debug = 0;
+ int retval = PAM_SUCCESS;
+ uid_t systemuser = 499, targetuser = 0;
+
+ /* Parse arguments. We don't understand many, so no sense in breaking
+ * this into a separate function. */
+ for (i = 0; i < argc; i++) {
+ const char *str;
+
+ if (strcmp(argv[i], "debug") == 0) {
+ debug = 1;
+ continue;
+ }
+ if ((str = pam_str_skip_prefix(argv[i], "xauthpath=")) != NULL) {
+ xauth = str;
+ continue;
+ }
+ if ((str = pam_str_skip_prefix(argv[i], "targetuser=")) != NULL) {
+ long l = strtol(str, &tmp, 10);
+ if ((*str != '\0') && (*tmp == '\0')) {
+ targetuser = l;
+ } else {
+ pam_syslog(pamh, LOG_WARNING,
+ "invalid value for targetuser (`%s')",
+ argv[i] + 11);
+ }
+ continue;
+ }
+ if ((str = pam_str_skip_prefix(argv[i], "systemuser=")) != NULL) {
+ long l = strtol(str, &tmp, 10);
+ if ((*str != '\0') && (*tmp == '\0')) {
+ systemuser = l;
+ } else {
+ pam_syslog(pamh, LOG_WARNING,
+ "invalid value for systemuser (`%s')",
+ argv[i] + 11);
+ }
+ continue;
+ }
+ pam_syslog(pamh, LOG_WARNING, "unrecognized option `%s'",
+ argv[i]);
+ }
+
+ if (xauth == NULL) {
+ size_t j;
+ for (j = 0; j < PAM_ARRAY_SIZE(xauthpaths); j++) {
+ if (access(xauthpaths[j], X_OK) == 0) {
+ xauth = xauthpaths[j];
+ break;
+ }
+ }
+ if (xauth == NULL) {
+ /* xauth executable not found - nothing to do */
+ return PAM_SUCCESS;
+ }
+ }
+
+ /* If DISPLAY isn't set, we don't really care, now do we? */
+ if ((display = getenv("DISPLAY")) == NULL) {
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "user has no DISPLAY, doing nothing");
+ }
+ return PAM_SUCCESS;
+ }
+
+ /* Read the target user's name. */
+ if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE, "cannot determine user name");
+ retval = PAM_SESSION_ERR;
+ goto cleanup;
+ }
+ rpwd = pam_modutil_getpwuid(pamh, getuid());
+ if (rpwd == NULL) {
+ pam_syslog(pamh, LOG_ERR,
+ "error determining invoking user's name");
+ retval = PAM_SESSION_ERR;
+ goto cleanup;
+ }
+
+ /* Get the target user's UID and primary GID, which we'll need to set
+ * on the xauthority file we create later on. */
+ tpwd = pam_modutil_getpwnam(pamh, user);
+ if (tpwd == NULL) {
+ pam_syslog(pamh, LOG_NOTICE,
+ "error determining target user's UID");
+ retval = PAM_SESSION_ERR;
+ goto cleanup;
+ }
+
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "requesting user %lu/%lu, target user %lu/%lu",
+ (unsigned long) rpwd->pw_uid,
+ (unsigned long) rpwd->pw_gid,
+ (unsigned long) tpwd->pw_uid,
+ (unsigned long) tpwd->pw_gid);
+ }
+
+ /* If the UID is a system account (and not the superuser), forget
+ * about forwarding keys. */
+ if ((tpwd->pw_uid != 0) &&
+ (tpwd->pw_uid != targetuser) &&
+ (tpwd->pw_uid <= systemuser)) {
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "not forwarding cookies to user ID %lu",
+ (unsigned long) tpwd->pw_uid);
+ }
+ retval = PAM_SESSION_ERR;
+ goto cleanup;
+ }
+
+
+ /* If current user and the target user are the same, don't
+ check the ACL list, but forward X11 */
+ if (strcmp (rpwd->pw_name, tpwd->pw_name) != 0) {
+
+ /* Check that both users are amenable to this. By default, this
+ * boils down to this policy:
+ * export(ruser=root): only if <user> is listed in .xauth/export
+ * export(ruser=*) if <user> is listed in .xauth/export, or
+ * if .xauth/export does not exist
+ * import(user=*): if <ruser> is listed in .xauth/import, or
+ * if .xauth/import does not exist */
+ i = (getuid() != 0 || tpwd->pw_uid == 0) ? PAM_SUCCESS : PAM_PERM_DENIED;
+ i = check_acl(pamh, "export", rpwd->pw_name, user, i, debug);
+ if (i != PAM_SUCCESS) {
+ retval = PAM_SESSION_ERR;
+ goto cleanup;
+ }
+ i = PAM_SUCCESS;
+ i = check_acl(pamh, "import", user, rpwd->pw_name, i, debug);
+ if (i != PAM_SUCCESS) {
+ retval = PAM_SESSION_ERR;
+ goto cleanup;
+ }
+ } else {
+ if (debug)
+ pam_syslog (pamh, LOG_DEBUG, "current and target user are the same, forward X11");
+ }
+
+ /* Figure out where the source user's .Xauthority file is. */
+ if (getenv(XAUTHENV) != NULL) {
+ cookiefile = strdup(getenv(XAUTHENV));
+ } else {
+ cookiefile = malloc(strlen(rpwd->pw_dir) + 1 +
+ strlen(XAUTHDEF) + 1);
+ if (cookiefile == NULL) {
+ retval = PAM_SESSION_ERR;
+ goto cleanup;
+ }
+ strcpy(cookiefile, rpwd->pw_dir);
+ strcat(cookiefile, "/");
+ strcat(cookiefile, XAUTHDEF);
+ }
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG, "reading keys from `%s'",
+ cookiefile);
+ }
+
+ /* Read the user's .Xauthority file. Because the current UID is
+ * the original user's UID, this will only fail if something has
+ * gone wrong, or we have no cookies. */
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "running \"%s %s %s %s %s\" as %lu/%lu",
+ xauth, "-f", cookiefile, "nlist", display,
+ (unsigned long) getuid(), (unsigned long) getgid());
+ }
+ if (run_coprocess(pamh, NULL, &cookie,
+ getuid(), getgid(),
+ xauth, "-f", cookiefile, "nlist", display,
+ NULL) == 0) {
+#ifdef WITH_SELINUX
+ char *context_raw = NULL;
+#endif
+ PAM_MODUTIL_DEF_PRIVS(privs);
+
+ /* Check that we got a cookie. If not, we get creative. */
+ if (((cookie == NULL) || (strlen(cookie) == 0)) &&
+ (pam_str_skip_prefix(display, "localhost:") != NULL ||
+ pam_str_skip_prefix(display, "localhost/unix:") != NULL)) {
+ char *t, *screen;
+ size_t tlen, slen;
+ /* Free the useless cookie string. */
+ if (cookie != NULL) {
+ free(cookie);
+ cookie = NULL;
+ }
+ /* Allocate enough space to hold an adjusted name. */
+ tlen = strlen(display) + LINE_MAX + 1;
+ t = malloc(tlen);
+ if (t != NULL) {
+ memset(t, 0, tlen);
+ if (gethostname(t, tlen - 1) != -1) {
+ /* Append the protocol and then the
+ * screen number. */
+ if (strlen(t) < tlen - 6) {
+ strcat(t, "/unix:");
+ }
+ screen = strchr(display, ':');
+ if (screen != NULL) {
+ screen++;
+ slen = strlen(screen);
+ if (strlen(t) + slen < tlen) {
+ strcat(t, screen);
+ }
+ }
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "no key for `%s', "
+ "trying `%s'",
+ display, t);
+ }
+ /* Read the cookie for this display. */
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "running "
+ "\"%s %s %s %s %s\" as "
+ "%lu/%lu",
+ xauth,
+ "-f",
+ cookiefile,
+ "nlist",
+ t,
+ (unsigned long) getuid(),
+ (unsigned long) getgid());
+ }
+ run_coprocess(pamh, NULL, &cookie,
+ getuid(), getgid(),
+ xauth, "-f", cookiefile,
+ "nlist", t, NULL);
+ }
+ free(t);
+ t = NULL;
+ }
+ }
+
+ /* Check that we got a cookie, this time for real. */
+ if ((cookie == NULL) || (strlen(cookie) == 0)) {
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG, "no key");
+ }
+ retval = PAM_SESSION_ERR;
+ goto cleanup;
+ }
+
+ /* Generate the environment variable
+ * "XAUTHORITY=<homedir>/filename". */
+ if (asprintf(&xauthority, "%s=%s/%s",
+ XAUTHENV, tpwd->pw_dir, XAUTHTMP) < 0) {
+ xauthority = NULL;
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG, "out of memory");
+ }
+ retval = PAM_SESSION_ERR;
+ goto cleanup;
+ }
+
+ /* Generate a new file to hold the data. */
+ if (pam_modutil_drop_priv(pamh, &privs, tpwd)) {
+ retval = PAM_SESSION_ERR;
+ goto cleanup;
+ }
+#ifdef WITH_SELINUX
+ if (is_selinux_enabled() > 0) {
+ struct selabel_handle *ctx = selabel_open(SELABEL_CTX_FILE, NULL, 0);
+ if (ctx != NULL) {
+ if (selabel_lookup_raw(ctx, &context_raw,
+ xauthority + sizeof(XAUTHENV), S_IFREG) != 0) {
+ pam_syslog(pamh, LOG_WARNING,
+ "could not get SELinux label for '%s'",
+ xauthority + sizeof(XAUTHENV));
+ }
+ selabel_close(ctx);
+ if (setfscreatecon_raw(context_raw)) {
+ pam_syslog(pamh, LOG_WARNING,
+ "setfscreatecon_raw(%s) failed: %m", context_raw);
+ }
+ }
+ }
+#endif /* WITH_SELINUX */
+ fd = mkstemp(xauthority + sizeof(XAUTHENV));
+ if (fd < 0)
+ pam_syslog(pamh, LOG_ERR,
+ "error creating temporary file `%s': %m",
+ xauthority + sizeof(XAUTHENV));
+#ifdef WITH_SELINUX
+ if (context_raw != NULL) {
+ free(context_raw);
+ setfscreatecon_raw(NULL);
+ }
+#endif /* WITH_SELINUX */
+ if (fd >= 0)
+ close(fd);
+ if (pam_modutil_regain_priv(pamh, &privs) || fd < 0) {
+ retval = PAM_SESSION_ERR;
+ goto cleanup;
+ }
+
+ /* Get a copy of the filename to save as a data item for
+ * removal at session-close time. */
+ free(cookiefile);
+ cookiefile = strdup(xauthority + sizeof(XAUTHENV));
+
+ /* Save the filename. */
+ if (pam_set_data(pamh, DATANAME, cookiefile, cleanup) != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_ERR,
+ "error saving name of temporary file `%s'",
+ cookiefile);
+ unlink(cookiefile);
+ retval = PAM_SESSION_ERR;
+ goto cleanup;
+ }
+
+ /* Set the new variable in the environment. */
+ if (pam_putenv (pamh, xauthority) != PAM_SUCCESS)
+ pam_syslog(pamh, LOG_ERR,
+ "can't set environment variable '%s'",
+ xauthority);
+ putenv (xauthority); /* The environment owns this string now. */
+ xauthority = NULL; /* Don't free environment variables. */
+
+ /* set $DISPLAY in pam handle to make su - work */
+ {
+ char *d;
+
+ if (asprintf(&d, "DISPLAY=%s", display) < 0)
+ {
+ pam_syslog(pamh, LOG_CRIT, "out of memory");
+ cookiefile = NULL;
+ retval = PAM_SESSION_ERR;
+ goto cleanup;
+ }
+
+ if (pam_putenv (pamh, d) != PAM_SUCCESS)
+ pam_syslog (pamh, LOG_ERR,
+ "can't set environment variable '%s'", d);
+ free (d);
+ }
+
+ /* set XAUTHLOCALHOSTNAME to make sure that su - work under gnome */
+ if ((xauthlocalhostname = getenv("XAUTHLOCALHOSTNAME")) != NULL) {
+ char *d;
+
+ if (asprintf(&d, "XAUTHLOCALHOSTNAME=%s", xauthlocalhostname) < 0) {
+ pam_syslog(pamh, LOG_CRIT, "out of memory");
+ retval = PAM_SESSION_ERR;
+ goto cleanup;
+ }
+
+ if (pam_putenv (pamh, d) != PAM_SUCCESS)
+ pam_syslog (pamh, LOG_ERR,
+ "can't set environment variable '%s'", d);
+ free (d);
+ }
+
+ /* Merge the cookie we read before into the new file. */
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "writing key `%s' to temporary file `%s'",
+ cookie, cookiefile);
+ }
+ if (debug) {
+ pam_syslog(pamh, LOG_DEBUG,
+ "running \"%s %s %s %s %s\" as %lu/%lu",
+ xauth, "-f", cookiefile, "nmerge", "-",
+ (unsigned long) tpwd->pw_uid,
+ (unsigned long) tpwd->pw_gid);
+ }
+ run_coprocess(pamh, cookie, &tmp,
+ tpwd->pw_uid, tpwd->pw_gid,
+ xauth, "-f", cookiefile, "nmerge", "-", NULL);
+
+ /* We don't need to keep a copy of these around any more. */
+ cookiefile = NULL;
+ free(tmp);
+ }
+cleanup:
+ /* Unset any old XAUTHORITY variable in the environment. */
+ if (retval != PAM_SUCCESS && getenv (XAUTHENV))
+ unsetenv (XAUTHENV);
+ free(cookiefile);
+ free(cookie);
+ free(xauthority);
+ return retval;
+}
+
+int
+pam_sm_close_session (pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ int i, debug = 0;
+ const char *user;
+ const void *data;
+ const char *cookiefile;
+ struct passwd *tpwd;
+ PAM_MODUTIL_DEF_PRIVS(privs);
+
+ /* Try to retrieve the name of a file we created when
+ * the session was opened. */
+ if (pam_get_data(pamh, DATANAME, &data) != PAM_SUCCESS)
+ return PAM_SUCCESS;
+ cookiefile = data;
+
+ /* Parse arguments. We don't understand many, so
+ * no sense in breaking this into a separate function. */
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "debug") == 0) {
+ debug = 1;
+ continue;
+ }
+ if (pam_str_skip_prefix(argv[i], "xauthpath=") != NULL)
+ continue;
+ if (pam_str_skip_prefix(argv[i], "systemuser=") != NULL)
+ continue;
+ if (pam_str_skip_prefix(argv[i], "targetuser=") != NULL)
+ continue;
+ pam_syslog(pamh, LOG_WARNING, "unrecognized option `%s'",
+ argv[i]);
+ }
+
+ if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS) {
+ pam_syslog(pamh, LOG_NOTICE, "cannot determine user name");
+ return PAM_SESSION_ERR;
+ }
+ if (!(tpwd = pam_modutil_getpwnam(pamh, user))) {
+ pam_syslog(pamh, LOG_NOTICE,
+ "error determining target user's UID");
+ return PAM_SESSION_ERR;
+ }
+
+ if (debug)
+ pam_syslog(pamh, LOG_DEBUG, "removing `%s'", cookiefile);
+ if (pam_modutil_drop_priv(pamh, &privs, tpwd))
+ return PAM_SESSION_ERR;
+ if (unlink(cookiefile) == -1 && errno != ENOENT)
+ pam_syslog(pamh, LOG_WARNING, "Couldn't remove `%s': %m", cookiefile);
+ if (pam_modutil_regain_priv(pamh, &privs))
+ return PAM_SESSION_ERR;
+
+ return PAM_SUCCESS;
+}
diff --git a/modules/pam_xauth/tst-pam_xauth b/modules/pam_xauth/tst-pam_xauth
new file mode 100755
index 0000000..3294896
--- /dev/null
+++ b/modules/pam_xauth/tst-pam_xauth
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_xauth.so