OXIESEC PANEL
- Current Dir:
/
/
usr
/
sbin
Server IP: 139.59.38.164
Upload:
Create Dir:
Name
Size
Modified
Perms
📁
..
-
10/21/2019 03:48:12 PM
rwxr-xr-x
📄
a2disconf
15.89 KB
02/23/2021 04:35:16 PM
rwxr-xr-x
📄
a2dismod
15.89 KB
02/23/2021 04:35:16 PM
rwxr-xr-x
📄
a2dissite
15.89 KB
02/23/2021 04:35:16 PM
rwxr-xr-x
📄
a2enconf
15.89 KB
02/23/2021 04:35:16 PM
rwxr-xr-x
📄
a2enmod
15.89 KB
02/23/2021 04:35:16 PM
rwxr-xr-x
📄
a2ensite
15.89 KB
02/23/2021 04:35:16 PM
rwxr-xr-x
📄
a2query
9.64 KB
03/08/2023 05:34:33 PM
rwxr-xr-x
📄
aa-remove-unknown
2.85 KB
06/20/2023 11:51:13 PM
rwxr-xr-x
📄
aa-status
8.41 KB
06/20/2023 11:51:13 PM
rwxr-xr-x
📄
accessdb
10.23 KB
08/04/2018 07:16:12 PM
rwxr-xr-x
📄
acpid
50.84 KB
04/28/2017 04:28:10 AM
rwxr-xr-x
📄
add-shell
860 bytes
12/30/2017 06:15:02 PM
rwxr-xr-x
📄
addgnupghome
3.01 KB
07/04/2022 04:20:59 PM
rwxr-xr-x
📄
addgroup
36.45 KB
12/05/2017 04:57:20 PM
rwxr-xr-x
📄
adduser
36.45 KB
12/05/2017 04:57:20 PM
rwxr-xr-x
📄
apache2
659.69 KB
03/08/2023 05:34:33 PM
rwxr-xr-x
📄
apache2ctl
7.06 KB
03/04/2022 10:48:50 AM
rwxr-xr-x
📄
apachectl
7.06 KB
03/04/2022 10:48:50 AM
rwxr-xr-x
📄
apparmor_status
8.41 KB
06/20/2023 11:51:13 PM
rwxr-xr-x
📄
applygnupgdefaults
2.17 KB
07/04/2022 04:20:59 PM
rwxr-xr-x
📄
arp
61.3 KB
01/10/2017 04:25:08 AM
rwxr-xr-x
📄
arpd
54.03 KB
01/26/2021 01:33:08 PM
rwxr-xr-x
📄
atd
26.01 KB
02/20/2018 06:59:43 AM
rwxr-xr-x
📄
bcache-super-show
13.99 KB
08/05/2020 08:44:05 PM
rwxr-xr-x
📄
biosdecode
18.87 KB
01/27/2020 06:09:10 PM
rwxr-xr-x
📄
check_forensic
952 bytes
04/26/2011 03:10:00 PM
rwxr-xr-x
📄
chgpasswd
57.83 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
chmem
42.08 KB
09/16/2020 06:43:15 PM
rwxr-xr-x
📄
chpasswd
53.86 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
chroot
38.18 KB
01/18/2018 09:43:49 AM
rwxr-xr-x
📄
cpgr
55.96 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
cppw
55.96 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
cron
46.3 KB
05/10/2022 08:59:19 PM
rwxr-xr-x
📄
cryptdisks_start
1.11 KB
08/03/2020 09:28:48 PM
rwxr-xr-x
📄
cryptdisks_stop
1.16 KB
08/03/2020 09:28:48 PM
rwxr-xr-x
📄
delgroup
16.11 KB
12/05/2017 04:57:20 PM
rwxr-xr-x
📄
deluser
16.11 KB
12/05/2017 04:57:20 PM
rwxr-xr-x
📄
dmidecode
106.54 KB
01/27/2020 06:09:10 PM
rwxr-xr-x
📄
dnsmasq
379.6 KB
04/18/2023 08:21:55 AM
rwxr-xr-x
📄
dpkg-preconfigure
3.58 KB
05/06/2019 04:30:30 PM
rwxr-xr-x
📄
dpkg-reconfigure
4.34 KB
05/06/2019 04:30:30 PM
rwxr-xr-x
📄
e2freefrag
14.07 KB
06/02/2022 02:37:00 PM
rwxr-xr-x
📄
e4crypt
22.07 KB
06/02/2022 02:37:00 PM
rwxr-xr-x
📄
e4defrag
25.99 KB
06/02/2022 02:37:00 PM
rwxr-xr-x
📄
escapesrc
22.16 KB
10/19/2021 07:44:28 PM
rwxr-xr-x
📄
faillock
13.99 KB
02/02/2023 09:24:07 AM
rwxr-xr-x
📄
fdformat
30.08 KB
09/16/2020 06:43:15 PM
rwxr-xr-x
📄
filefrag
14.02 KB
06/02/2022 02:37:00 PM
rwxr-xr-x
📄
genccode
10.36 KB
10/19/2021 07:44:28 PM
rwxr-xr-x
📄
gencmn
10.44 KB
10/19/2021 07:44:28 PM
rwxr-xr-x
📄
genl
58.05 KB
01/26/2021 01:33:08 PM
rwxr-xr-x
📄
gennorm2
54.59 KB
10/19/2021 07:44:28 PM
rwxr-xr-x
📄
gensprep
18.5 KB
10/19/2021 07:44:28 PM
rwxr-xr-x
📄
groupadd
61.92 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
groupdel
70.37 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
groupmems
57.87 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
groupmod
68.18 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
grpck
53.8 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
grpconv
49.68 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
grpunconv
49.68 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
grub-install
1003.51 KB
02/01/2023 05:49:01 PM
rwxr-xr-x
📄
grub-macbless
780.84 KB
02/01/2023 05:49:01 PM
rwxr-xr-x
📄
grub-mkconfig
8.03 KB
02/01/2023 05:49:01 PM
rwxr-xr-x
📄
grub-mkdevicemap
207.62 KB
02/01/2023 05:49:01 PM
rwxr-xr-x
📄
grub-probe
793.09 KB
02/01/2023 05:49:01 PM
rwxr-xr-x
📄
grub-reboot
4.73 KB
02/01/2023 05:49:01 PM
rwxr-xr-x
📄
grub-set-default
832 bytes
03/24/2018 12:56:45 AM
rwxr-xr-x
📄
grub-set-default-legacy-ec2
3.13 KB
03/24/2018 12:56:45 AM
rwxr-xr-x
📄
grub-set-default.real
3.47 KB
02/01/2023 05:49:01 PM
rwxr-xr-x
📄
httxt2dbm
9.99 KB
03/08/2023 05:34:33 PM
rwxr-xr-x
📄
iconvconfig
30.25 KB
05/03/2022 10:19:39 AM
rwxr-xr-x
📄
icupkg
18.77 KB
10/19/2021 07:44:28 PM
rwxr-xr-x
📄
init.lxc
38.5 KB
05/05/2023 12:06:12 PM
rwxr-xr-x
📄
init.lxc.static
1005.91 KB
05/05/2023 12:06:12 PM
rwxr-xr-x
📄
invoke-rc.d
15.66 KB
10/25/2017 03:38:42 PM
rwxr-xr-x
📄
ip6tables-apply
6.85 KB
05/09/2023 06:42:18 PM
rwxr-xr-x
📄
iptables-apply
6.85 KB
05/09/2023 06:42:18 PM
rwxr-xr-x
📄
irqbalance
62.68 KB
01/09/2019 10:38:44 AM
rwxr-xr-x
📄
irqbalance-ui
34.06 KB
01/09/2019 10:38:44 AM
rwxr-xr-x
📄
iscsi-iname
9.99 KB
04/06/2022 07:19:56 PM
rwxr-xr-x
📄
iscsi_discovery
5.16 KB
09/29/2016 06:33:24 PM
rwxr-xr-x
📄
iscsid
398.15 KB
04/06/2022 07:19:56 PM
rwxr-xr-x
📄
iscsistart
358.13 KB
04/06/2022 07:19:56 PM
rwxr-xr-x
📄
ldattach
30.08 KB
09/16/2020 06:43:15 PM
rwxr-xr-x
📄
locale-gen
4.3 KB
12/07/2020 04:38:09 PM
rwxr-xr-x
📄
logrotate
74.09 KB
08/21/2017 11:01:27 PM
rwxr-xr-x
📄
luksformat
3.32 KB
08/03/2020 09:28:48 PM
rwxr-xr-x
📄
maidag
69.88 KB
11/07/2017 09:06:00 PM
rwxr-xr-x
📄
make-bcache
18.07 KB
08/05/2020 08:44:05 PM
rwxr-xr-x
📄
make-ssl-cert
3.78 KB
04/28/2017 07:58:22 PM
rwxr-xr-x
📄
mkinitramfs
10.89 KB
07/01/2021 01:11:48 PM
rwxr-xr-x
📄
mklost+found
9.99 KB
06/02/2022 02:37:00 PM
rwxr-xr-x
📄
mysqld
23.16 MB
04/23/2023 02:08:47 PM
rwxr-xr-x
📄
netplan
798 bytes
09/07/2021 03:19:37 PM
rwxr-xr-x
📄
newusers
82.39 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
nfnl_osf
13.99 KB
05/09/2023 06:42:18 PM
rwxr-xr-x
📄
nologin
5.99 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
overlayroot-chroot
2.45 KB
09/20/2018 01:29:41 PM
rwxr-xr-x
📄
ownership
10.13 KB
01/27/2020 06:09:10 PM
rwxr-xr-x
📄
pam-auth-update
19.38 KB
07/21/2020 11:40:59 PM
rwxr-xr-x
📄
pam_getenv
2.82 KB
08/23/2018 11:37:53 PM
rwxr-xr-x
📄
pam_timestamp_check
9.99 KB
02/02/2023 09:24:07 AM
rwxr-xr-x
📄
paperconfig
4.07 KB
04/28/2017 05:17:56 AM
rwxr-xr-x
📄
php-fpm7.2
4.65 MB
02/23/2023 01:29:25 PM
rwxr-xr-x
📄
phpdismod
7.11 KB
01/17/2018 11:50:00 PM
rwxr-xr-x
📄
phpenmod
7.11 KB
01/17/2018 11:50:00 PM
rwxr-xr-x
📄
phpquery
6.24 KB
01/17/2018 11:50:00 PM
rwxr-xr-x
📄
popcon-largest-unused
543 bytes
02/22/2018 05:15:22 AM
rwxr-xr-x
📄
popularity-contest
4.92 KB
02/22/2018 05:15:22 AM
rwxr-xr-x
📄
postalias
17.99 KB
08/12/2021 12:43:19 PM
rwxr-xr-x
📄
postcat
18.06 KB
08/12/2021 12:43:19 PM
rwxr-xr-x
📄
postconf
179.47 KB
08/12/2021 12:43:19 PM
rwxr-xr-x
📄
postdrop
14.12 KB
08/12/2021 12:43:19 PM
r-xr-xr-x
📄
postfix
14.07 KB
08/12/2021 12:43:19 PM
rwxr-xr-x
📄
postfix-add-filter
4.9 KB
08/12/2021 12:43:19 PM
rwxr-xr-x
📄
postfix-add-policy
3.83 KB
08/12/2021 12:43:19 PM
rwxr-xr-x
📄
postkick
9.99 KB
08/12/2021 12:43:19 PM
rwxr-xr-x
📄
postlock
9.99 KB
08/12/2021 12:43:19 PM
rwxr-xr-x
📄
postlog
10.15 KB
08/12/2021 12:43:19 PM
rwxr-xr-x
📄
postmap
17.99 KB
08/12/2021 12:43:19 PM
rwxr-xr-x
📄
postmulti
26.38 KB
08/12/2021 12:43:19 PM
rwxr-xr-x
📄
postqueue
22.07 KB
08/12/2021 12:43:19 PM
r-xr-xr-x
📄
postsuper
22.32 KB
08/12/2021 12:43:19 PM
rwxr-xr-x
📄
posttls-finger
34.09 KB
08/12/2021 12:43:19 PM
rwxr-xr-x
📄
pwck
49.8 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
pwconv
45.7 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
pwunconv
45.68 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
qmqp-sink
13.99 KB
08/12/2021 12:43:19 PM
rwxr-xr-x
📄
qmqp-source
18.01 KB
08/12/2021 12:43:19 PM
rwxr-xr-x
📄
qshape
12.55 KB
08/12/2021 12:43:19 PM
rwxr-xr-x
📄
readprofile
18.11 KB
09/16/2020 06:43:15 PM
rwxr-xr-x
📄
remove-shell
904 bytes
12/30/2017 06:15:02 PM
rwxr-xr-x
📄
rmail
13.99 KB
08/12/2021 12:43:19 PM
rwxr-xr-x
📄
rmt
58.39 KB
02/15/2023 02:55:10 PM
rwxr-xr-x
📄
rmt-tar
58.39 KB
02/15/2023 02:55:10 PM
rwxr-xr-x
📄
rsyslogd
668.54 KB
05/03/2022 09:20:37 AM
rwxr-xr-x
📄
rtcwake
42.08 KB
09/16/2020 06:43:15 PM
rwxr-xr-x
📄
sendmail
26.15 KB
08/12/2021 12:43:19 PM
rwxr-xr-x
📄
service
9.04 KB
10/25/2017 03:38:42 PM
rwxr-xr-x
📄
setvesablank
14.07 KB
01/22/2018 01:49:48 PM
rwxr-xr-x
📄
slapacl
1.2 MB
05/12/2022 01:52:38 PM
rwxr-xr-x
📄
slapadd
1.2 MB
05/12/2022 01:52:38 PM
rwxr-xr-x
📄
slapauth
1.2 MB
05/12/2022 01:52:38 PM
rwxr-xr-x
📄
slapcat
1.2 MB
05/12/2022 01:52:38 PM
rwxr-xr-x
📄
slapd
1.2 MB
05/12/2022 01:52:38 PM
rwxr-xr-x
📄
slapdn
1.2 MB
05/12/2022 01:52:38 PM
rwxr-xr-x
📄
slapindex
1.2 MB
05/12/2022 01:52:38 PM
rwxr-xr-x
📄
slappasswd
1.2 MB
05/12/2022 01:52:38 PM
rwxr-xr-x
📄
slapschema
1.2 MB
05/12/2022 01:52:38 PM
rwxr-xr-x
📄
slaptest
1.2 MB
05/12/2022 01:52:38 PM
rwxr-xr-x
📄
smtp-sink
30.93 KB
08/12/2021 12:43:19 PM
rwxr-xr-x
📄
smtp-source
22.02 KB
08/12/2021 12:43:19 PM
rwxr-xr-x
📄
split-logfile
2.36 KB
03/08/2023 05:34:33 PM
rwxr-xr-x
📄
sshd
772.41 KB
03/30/2022 01:17:14 PM
rwxr-xr-x
📄
tarcat
936 bytes
02/15/2023 02:55:10 PM
rwxr-xr-x
📄
tcpdump
999.6 KB
02/10/2023 06:11:16 PM
rwxr-xr-x
📄
tzconfig
106 bytes
04/03/2023 11:03:22 AM
rwxr-xr-x
📄
ufw
4.82 KB
10/25/2021 05:30:24 PM
rwxr-xr-x
📄
update-ca-certificates
5.27 KB
05/18/2023 01:09:37 PM
rwxr-xr-x
📄
update-grub
64 bytes
02/01/2023 05:49:01 PM
rwxr-xr-x
📄
update-grub-legacy-ec2
43.96 KB
03/24/2018 12:56:45 AM
rwxr-xr-x
📄
update-grub2
64 bytes
02/01/2023 05:49:01 PM
rwxr-xr-x
📄
update-gsfontmap
450 bytes
04/13/2023 01:09:22 PM
rwxr-xr-x
📄
update-icon-caches
596 bytes
04/02/2019 03:46:36 PM
rwxr-xr-x
📄
update-info-dir
1.66 KB
02/05/2018 02:48:18 PM
rwxr-xr-x
📄
update-initramfs
8.04 KB
03/18/2021 06:48:17 PM
rwxr-xr-x
📄
update-java-alternatives
3.09 KB
01/06/2017 12:03:20 PM
rwxr-xr-x
📄
update-locale
2.99 KB
05/03/2022 04:27:41 AM
rwxr-xr-x
📄
update-mime
8.84 KB
07/15/2016 12:06:12 PM
rwxr-xr-x
📄
update-passwd
30.41 KB
09/12/2017 09:48:16 PM
rwxr-xr-x
📄
update-pciids
2.84 KB
02/10/2019 06:25:12 PM
rwxr-xr-x
📄
update-rc.d
16.12 KB
10/25/2017 03:38:42 PM
rwxr-xr-x
📄
update-secureboot-policy
7.43 KB
01/31/2023 11:57:37 AM
rwxr-xr-x
📄
update-usbids
1.05 KB
04/21/2017 08:59:17 PM
rwxr-xr-x
📄
useradd
123.28 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
userdel
82.48 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
usermod
123.06 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
uuidd
34.16 KB
09/16/2020 06:43:15 PM
rwxr-xr-x
📄
validlocale
1.73 KB
12/07/2020 04:38:09 PM
rwxr-xr-x
📄
vcstime
9.99 KB
01/22/2018 01:49:48 PM
rwxr-xr-x
📄
vigr
60.18 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
vipw
60.18 KB
11/29/2022 12:25:19 PM
rwxr-xr-x
📄
visudo
208.8 KB
04/04/2023 12:44:58 PM
rwxr-xr-x
📄
vpddecode
14.27 KB
01/27/2020 06:09:10 PM
rwxr-xr-x
📄
xfs_admin
1.35 KB
04/18/2018 06:44:31 AM
rwxr-xr-x
📄
xfs_bmap
638 bytes
04/18/2018 06:44:31 AM
rwxr-xr-x
📄
xfs_copy
394.31 KB
04/18/2018 06:44:31 AM
rwxr-xr-x
📄
xfs_db
667.63 KB
04/18/2018 06:44:31 AM
rwxr-xr-x
📄
xfs_estimate
10.01 KB
04/18/2018 06:44:31 AM
rwxr-xr-x
📄
xfs_freeze
767 bytes
04/18/2018 06:44:31 AM
rwxr-xr-x
📄
xfs_fsr
30.02 KB
04/18/2018 06:44:31 AM
rwxr-xr-x
📄
xfs_growfs
382.27 KB
04/18/2018 06:44:31 AM
rwxr-xr-x
📄
xfs_info
472 bytes
04/18/2018 06:44:31 AM
rwxr-xr-x
📄
xfs_io
130.93 KB
04/18/2018 06:44:31 AM
rwxr-xr-x
📄
xfs_logprint
414.27 KB
04/18/2018 06:44:31 AM
rwxr-xr-x
📄
xfs_mdrestore
370.28 KB
04/18/2018 06:44:31 AM
rwxr-xr-x
📄
xfs_metadump
747 bytes
04/18/2018 06:44:31 AM
rwxr-xr-x
📄
xfs_mkfile
1007 bytes
04/18/2018 06:44:31 AM
rwxr-xr-x
📄
xfs_ncheck
650 bytes
04/18/2018 06:44:31 AM
rwxr-xr-x
📄
xfs_quota
86.01 KB
04/18/2018 06:44:31 AM
rwxr-xr-x
📄
xfs_rtcp
13.99 KB
04/18/2018 06:44:31 AM
rwxr-xr-x
📄
zerofree
9.99 KB
11/14/2016 02:44:00 PM
rwxr-xr-x
📄
zic
54.14 KB
05/03/2022 10:19:39 AM
rwxr-xr-x
Editing: pam-auth-update
Close
#!/usr/bin/perl -w # pam-auth-update: update /etc/pam.d/common-* from /usr/share/pam-configs # # Update the /etc/pam.d/common-* files based on the per-package profiles # provided in /usr/share/pam-configs/ taking into consideration user's # preferences (as determined via debconf prompting). # # Written by Steve Langasek <steve.langasek@canonical.com> # # Copyright (C) 2008 Canonical Ltd. # # This program is free software; you can redistribute it and/or modify # it under the terms of version 3 of the GNU General Public License as # published by the Free Software Foundation. # # # 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 St, Fifth Floor, Boston, MA 02110-1301, # USA. use strict; use Debconf::Client::ConfModule ':all'; use IPC::Open2 'open2'; version('2.0'); my $capb=capb('backup escape'); my $inputdir = '/usr/share/pam-configs'; my $template = 'libpam-runtime/profiles'; my $errtemplate = 'libpam-runtime/conflicts'; my $overridetemplate = 'libpam-runtime/override'; my $blanktemplate = 'libpam-runtime/no_profiles_chosen'; my $titletemplate = 'libpam-runtime/title'; my $confdir = '/etc/pam.d'; my $savedir = '/var/lib/pam'; my (%profiles, @sorted, @enabled, @conflicts, @new, %removals, %to_enable); my $force = 0; my $package = 0; my $priority = 'high'; my %md5sums = ( 'auth' => ['8d4fe17e66ba25de16a117035d1396aa'], 'account' => ['3c0c362eaf3421848b679d63fd48c3fa'], 'password' => [ '50fce2113dfda83ac8bdd5a6e706caec', '4bd7610f2e85f8ddaef79c7db7cb49eb', '9ba753d0824276b44bcadfee1f87b6bc', ], 'session' => [ '240fb92986c885b327cdb21dd641da8c', '4a25673e8b36f1805219027d3be02cd2', '73144a2f4e609a922a51e301cd66a57e', ], 'session-noninteractive' => [ 'ad2b78ce1498dd637ef36469430b6ac6', 'a20e8df3469bfe25c13a3b39161b30f0', ], ); opendir(DIR, $inputdir) || die "could not open config directory: $!"; while (my $profile = readdir(DIR)) { next if ($profile eq '.' || $profile eq '..'); %{$profiles{$profile}} = parse_pam_profile($inputdir . '/' . $profile); } closedir DIR; # use a '--force' arg to specify that /etc/pam.d should be overwritten; # used only on upgrades where the postinst has already determined that the # checksums match. Module packages other than libpam-runtime itself must # NEVER use this option! Document with big skullses and crossboneses! It # needs to be exposed for libpam-runtime because that's the package that # decides whether we have a pristine config to be converted, and knows # whether the version being upgraded from is one for which the conversion # should be done. while ($#ARGV >= 0) { my $opt = shift; if ($opt eq '--force') { $force = 1; } elsif ($opt eq '--package') { $package = 1; } elsif ($opt eq '--remove') { while ($#ARGV >= 0) { last if ($ARGV[0] =~ /^--/); $removals{shift @ARGV} = 1; } # --remove implies --package $package = 1 if (keys(%removals)); } elsif ($opt eq '--enable') { while ($#ARGV >= 0) { last if ($ARGV[0] =~ /^--/); $to_enable{shift @ARGV} = 1; } # --enable implies --package $package = 1 if (keys(%to_enable)); } } $priority = 'medium' if ($package); x_loadtemplatefile('/var/lib/dpkg/info/libpam-runtime.templates','libpam-runtime'); # always sort by priority, so we have consistency and don't have to # shuffle later @sorted = sort { $profiles{$b}->{'Priority'} <=> $profiles{$a}->{'Priority'} || $b cmp $a } keys(%profiles); # If we're being called for package removal, filter out those options here @sorted = grep { !$removals{$_} } @sorted; subst($template, 'profile_names', join(', ',@sorted)); subst($template, 'profiles', join(', ', map { $profiles{$_}->{'Name'} } @sorted)); my $diff = diff_profiles($confdir,$savedir); if ($diff) { @enabled = grep { !$removals{$_} } @{$diff->{'mods'}}; } else { @enabled = split(/, /,get($template)); } # find out what we've seen, so we can ignore those defaults my %seen; if (-e $savedir . '/seen') { open(SEEN,$savedir . '/seen'); while (<SEEN>) { chomp; $seen{$_} = 1; } close(SEEN); } # filter out any options that are no longer available for any reason @enabled = grep { $profiles{$_} } @enabled; # an empty module set is an error, so in that case grab all the defaults if (!@enabled) { %seen = (); $priority = 'high' unless ($force); } # add configs to enable push(@enabled, grep { $to_enable{$_} } @sorted); # add any previously-unseen configs push(@enabled, grep { $profiles{$_}->{'Default'} eq 'yes' && !$seen{$_} } @sorted); @enabled = sort { $profiles{$b}->{'Priority'} <=> $profiles{$a}->{'Priority'} || $b cmp $a } @enabled; my $prev = ''; @enabled = grep { $_ ne $prev && (($prev) = $_) } @enabled; # Do we have any new options to show? If not, we shouldn't reprompt the # user, at any priority level, unless explicitly called. @new = grep { !$seen{$_} } @sorted; settitle($titletemplate); # if diff_profiles() fails, and we weren't passed a 'force' argument # (because this isn't an upgrade from an old version, or the checksum # didn't match, or we're being called by some other module package), prompt # the user whether to override. If the user declines (the default), we # never again manage this config unless manually called with '--force'. if (!$diff && !$force) { input('high',$overridetemplate); go(); $force = 1 if (get($overridetemplate) eq 'true'); } if (!$diff && !$force) { print STDERR <<EOF; pam-auth-update: Local modifications to /etc/pam.d/common-*, not updating. pam-auth-update: Run pam-auth-update --force to override. EOF exit; } umask(0022); do { @conflicts = (); if (@new || !$package) { fset($template,'seen','false'); } set($template,join(', ', @enabled)); input($priority,$template); go(); @enabled = split(/, /, get($template)); # in case of conflicts, automatically unset the lower priority # item of each pair foreach my $elem (@enabled) { for (my $i=$#enabled; $i >= 0; $i--) { my $conflict = $enabled[$i]; if ($profiles{$elem}->{'Conflicts'}->{$conflict}) { splice(@enabled,$i,1); my $desc = $profiles{$elem}->{'Name'} . ', ' . $profiles{$conflict}->{'Name'}; push(@conflicts,$desc); } } } if (@conflicts) { subst($errtemplate, 'conflicts', join("\\n", @conflicts)); input('high',$errtemplate); } set($template, join(', ', @enabled)); if (!@enabled) { input('high',$blanktemplate); # we can only end up here by user error, but give them another # shot at selecting a correct config anyway. fset($template,'seen','false'); } } while (@conflicts || !@enabled); # the decision has been made about what configs to use, so even if # something fails after this, we shouldn't go munging the default # options again. Save the list of known configs to /var/lib/pam. open(SEEN,"> $savedir/seen"); for my $i (@sorted) { print SEEN "$i\n"; } close(SEEN); # @enabled now contains our list of profiles to use for piecing together # a config # we have: # - templates into which we insert the specialness # - magic comments denoting the beginning and end of our managed block; # looking at only the functional config lines would potentially let us # handle more cases, at the expense of much greater complexity, so # pass on this at least for the first round # - a representation of the autogenerated config stored in /var/lib/pam, # that we can diff against in order to account for changed options or # manually dropped modules # - a hash describing the local modifications the user has made to the # config; these are always preserved unless manually overridden with # the --force option write_profiles(\%profiles, \@enabled, $confdir, $savedir, $diff, $force); # take a single line from a stock config, and merge it with the # information about local admin edits sub merge_one_line { my ($line,$diff,$count) = @_; my (@opts,$modline); my ($adds,$removes); $line =~ /^((\[[^]]+\]|\w+)\s+\S+)\s*(.*)/; @opts = split(/\s+/,$3); $modline = $1; $modline =~ s/end/$count/g; if ($diff) { my $mod = $modline; $mod =~ s/(\[[^0-9]*)[0-9]+(.*\])/$1$2/g; $adds = \%{$diff->{'add'}{$mod}}; $removes = \%{$diff->{'remove'}{$mod}}; } else { $adds = $removes = undef; } for (my $i = 0; $i <= $#opts; $i++) { if ($adds->{$opts[$i]}) { delete $adds->{$opts[$i]}; } if ($removes->{$opts[$i]}) { splice(@opts,$i,1); $i--; } } return $modline . " " . join(' ',@opts,sort keys(%{$adds})) . "\n"; } # return the lines for a given config name, type, and position in the stack sub lines_for_module_and_type { my ($profiles, $mod, $type, $modpos) = @_; if ($modpos == 0 && $profiles->{$mod}{$type . '-Initial'}) { return $profiles->{$mod}{$type . '-Initial'}; } return $profiles->{$mod}{$type}; } # create a single PAM config from the indicated template and selections, # writing to a new file sub create_from_template { my($template,$dest,$profiles,$enabled,$diff,$type) = @_; my $state = 0; my $uctype = ucfirst($type); $type =~ s/-noninteractive//; open(INPUT,$template) || return 0; open(OUTPUT,">$dest") || return 0; while (<INPUT>) { if ($state == 1) { if (/^# here's the fallback if no module succeeds/) { print OUTPUT; $state++; } next; } if ($state == 3) { if (/^# end of pam-auth-update config/) { print OUTPUT; $state++; } next; } print OUTPUT; my ($pattern,$val); if ($state == 0) { $pattern = '^# here are the per-package modules \(the "Primary" block\)'; $val = 'Primary'; } elsif ($state == 2) { $pattern = '^# and here are more per-package modules \(the "Additional" block\)'; $val = 'Additional'; } else { next; } if (/$pattern/) { my $i = 0; my $count = 0; # first we need to get a count of lines that we're # going to output, so we can fix up the jumps correctly for my $mod (@{$enabled}) { my $output; next if (!$profiles->{$mod}{$uctype . '-Type'}); next if $profiles->{$mod}{$uctype . '-Type'} ne $val; $output = lines_for_module_and_type($profiles, $mod, $uctype, $i++); # bypasses a perl warning about @_, sigh my @tmparr = split("\n+",$output); $count += @tmparr; } # in case anything tries to jump in the 'additional' # block, let's try not to jump off the stack... $count-- if ($val eq 'Additional'); # no primary block, so output a stock pam_permit line # to keep the stack intact if ($val eq 'Primary' && $count == 0) { print OUTPUT "$type\t[default=1]\t\t\tpam_permit.so\n"; } $i = 0; for my $mod (@{$enabled}) { my $output; my @output; next if (!$profiles->{$mod}{$uctype . '-Type'}); next if $profiles->{$mod}{$uctype . '-Type'} ne $val; $output = lines_for_module_and_type($profiles, $mod, $uctype, $i++); for my $line (split("\n",$output)) { $line = merge_one_line($line,$diff, $count); print OUTPUT "$type\t$line"; $count--; } } $state++; } } close(INPUT); close(OUTPUT); if ($state < 4) { unlink($dest); return 0; } return 1; } # take a template file, strip out everything between the markers, and # return the md5sum of the remaining contents. Used for testing for # local modifications of the boilerplate. sub get_template_md5sum { my($template) = @_; my $state = 0; open(INPUT,$template) || return ''; my($md5sum_fd,$output_fd); my $pid = open2($md5sum_fd, $output_fd, 'md5sum'); return '' if (!$pid); while (<INPUT>) { if ($state == 1) { if (/^# here's the fallback if no module succeeds/) { print $output_fd $_; $state++; } next; } if ($state == 3) { if (/^# end of pam-auth-update config/) { print $output_fd $_; $state++; } next; } print $output_fd $_; my ($pattern,$val); if ($state == 0) { $pattern = '^# here are the per-package modules \(the "Primary" block\)'; } elsif ($state == 2) { $pattern = '^# and here are more per-package modules \(the "Additional" block\)'; } else { next; } if (/$pattern/) { $state++; } } close(INPUT); close($output_fd); my $md5sum = <$md5sum_fd>; close($md5sum_fd); waitpid $pid, 0; $md5sum = (split(/\s+/,$md5sum))[0]; return $md5sum; } # merge a set of module declarations into a set of new config files, # using the information returned from diff_profiles(). sub write_profiles { my($profiles,$enabled,$confdir,$savedir,$diff,$force) = @_; if (! -d $savedir) { mkdir($savedir); } # because we can't atomically replace both /var/lib/pam/$foo and # /etc/pam.d/common-$foo at the same time, take steps to make this # somewhat robust for my $type ('auth','account','password','session', 'session-noninteractive') { my $target = $confdir . '/common-' . $type; my $template = $target; my $dest = $template . '.pam-new'; my $diff = $diff; if ($diff) { $diff = \%{$diff->{$type}}; } # Detect if the template is unmodified, and if so, use # the version from /usr/share. Depends on knowing the # md5sums of the originals. my $md5sum = get_template_md5sum($template); for my $i (@{$md5sums{$type}}) { if ($md5sum eq $i) { $template = '/usr/share/pam/common-' . $type; last; } } # first, write out the new config if (!create_from_template($template,$dest,$profiles,$enabled, $diff,$type)) { if (!$force) { return 0; } $template = '/usr/share/pam/common-' . $type; if (!create_from_template($template,$dest,$profiles, $enabled,$diff,$type)) { return 0; } } # then write out the saved config if (!open(OUTPUT, "> $savedir/$type.new")) { unlink($dest); return 0; } my $i = 0; my $uctype = ucfirst($type); for my $mod (@{$enabled}) { my $output; next if (!$profiles->{$mod}{$uctype . '-Type'}); next if ($profiles->{$mod}{$uctype . '-Type'} eq 'Additional'); $output = lines_for_module_and_type($profiles, $mod, $uctype, $i++); if ($output) { print OUTPUT "Module: $mod\n"; print OUTPUT $output . "\n"; } } # no primary block, so output a stock pam_permit line if ($i == 0) { print OUTPUT "Module: null\n"; print OUTPUT "[default=1]\t\t\tpam_permit.so\n"; } $i = 0; for my $mod (@{$enabled}) { my $output; next if (!$profiles->{$mod}{$uctype . '-Type'}); next if ($profiles->{$mod}{$uctype . '-Type'} eq 'Primary'); $output = lines_for_module_and_type($profiles, $mod, $uctype, $i++); if ($output) { print OUTPUT "Module: $mod\n"; print OUTPUT $output . "\n"; } } close(OUTPUT); # then do the renames, back-to-back # we have to use system because File::Copy is in # perl-modules, not perl-base if (-e "$target" && $force) { system('cp','-f',$target,$target . '.pam-old'); } rename($dest,$target); rename("$savedir/$type.new","$savedir/$type"); } # at the end of a successful write, reset the 'seen' flag and the # value of the debconf override question. fset($overridetemplate,'seen','false'); set($overridetemplate,'false'); } # reconcile the current config in /etc/pam.d with the saved ones in # /var/lib/pam; returns a hash of profile names and the corresponding # options that should be added/removed relative to the stock config. # returns false if any of the markers are missing that permit a merge, # or on any other failure. sub diff_profiles { my ($sourcedir,$savedir) = @_; my (%diff); @{$diff{'mods'}} = (); # Load the saved config from /var/lib/pam, then iterate through all # lines in the current config that are in the managed block. # If anything fails here, just return immediately since we then # have nothing to merge; instead, the caller will decide later # whether to force an overwrite. for my $type ('auth','account','password','session', 'session-noninteractive') { my (@saved,$modname); open(SAVED,$savedir . '/' . $type) || return 0; while (<SAVED>) { if (/^Module: (.*)/) { $modname = $1; next; } chomp; # trim out the destination of any jumps; this saves # us from having to re-parse everything just to fix # up the jump lengths, when changes to these will # already show up as inconsistencies elsewhere s/(\[[^0-9]*)[0-9]+(.*\])/$1$2/g; s/(\[.*)end(.*\])/$1$2/g; my (@temp) = ($modname,$_); push(@saved,\@temp); } close(SAVED); my $state = 0; my (@prev_opts,$curmod); my $realtype = $type; $realtype =~ s/-noninteractive//; open(CURRENT,$sourcedir . '/common-' . $type) || return 0; while (<CURRENT>) { if ($state == 0) { $state = 1 if (/^# here are the per-package modules \(the "Primary" block\)/); next; } if ($state == 1) { s/^$realtype\s+//; if (/^# here's the fallback if no module succeeds/) { $state = 2; next; } } if ($state == 2) { $state = 3 if (/^# and here are more per-package modules \(the "Additional" block\)/); next; } if ($state == 3) { last if (/^# end of pam-auth-update config/); s/^$realtype\s+//; } my $found = 0; my $curopts; while (!$found && $#saved >= 0) { my $line; ($modname,$line) = @{$saved[0]}; shift(@saved); $line =~ /^((\[[^]]+\]|\w+)\s+\S+)\s*(.*)/; @prev_opts = split(/\s+/,$3); $curmod = $1; # FIXME: the key isn't derived from the config # name, so collisions are possible if more # than one config references the same module $_ =~ s/(\[[^0-9]*)[0-9]+(.*\])/$1$2/g; # check if this is a match for the current line if ($_ =~ /^\Q$curmod\E\s*(.*)$/) { $found = 1; $curopts = $1; push(@{$diff{'mods'}},$modname); } } # there's a line in the live config that doesn't # correspond to anything from the saved config. # treat this as a failure; it's very error-prone # to decide what to do with an added line that # didn't come from a package. return 0 if (!$found); for my $opt (split(/\s+/,$curopts)) { my $found = 0; for (my $i = 0; $i <= $#prev_opts; $i++) { if ($prev_opts[$i] eq $opt) { $found = 1; splice(@prev_opts,$i,1); } } $diff{$type}{'add'}{$curmod}{$opt} = 1 if (!$found); } for my $opt (@prev_opts) { $diff{$type}{'remove'}{$curmod}{$opt} = 1; } } close(CURRENT); # we couldn't parse the config, so the merge fails return 0 if ($state < 3); } return \%diff; } # simple function to parse a provided config file, in pseudo-RFC822 # format, sub parse_pam_profile { my ($profile) = $_[0]; my $fieldname; my %profile; open(PROFILE, $profile) || die "could not read profile $profile: $!"; while (<PROFILE>) { if (/^(\S+):\s+(.*)\s*$/) { $fieldname = $1; # compatibility with the first implementation round; # "Auth-Final" is now just called "Auth" $fieldname =~ s/-Final$//; if ($fieldname eq 'Conflicts') { foreach my $elem (split(/, /, $2)) { $profile{'Conflicts'}->{$elem} = 1; } } else { $profile{$fieldname} = $2; } } else { chomp; s/^\s+//; s/\s+$//; $profile{$fieldname} .= "\n$_" if ($_); $profile{$fieldname} =~ s/^[\n\s]+//; } } close(PROFILE); if (!defined($profile{'Session-Interactive-Only'})) { $profile{'Session-noninteractive-Type'} = $profile{'Session-Type'}; $profile{'Session-noninteractive'} = $profile{'Session'}; $profile{'Session-noninteractive-Initial'} = $profile{'Session-Initial'}; } return %profile; }