Используйте механизм аудита изменений файлов, например как LoggedFS или подсистема аудита Linux . См. Также Как определить, какой процесс создает файл? , Регистрировать каждый вызов каждой программы SUID? , Stump the Chump with Auditd 01 ...
Если предположить, что сервер работает под управлением Linux, система аудита выглядит лучшим решением. Регистрируйте все операции переименования файлов в соответствующем дереве каталогов, например / var / www
:
auditctl -a exit,always -S rename -F dir=/var/www
Журналы аудита обычно находятся в /var/log/audit/audit.log
. Вот пример протокола с cd / var / www; mv foo bar
с правилом выше:
type=SYSCALL msg=audit(1489528471.598:669): arch=c000003e syscall=82 success=yes exit=0 a0=7ffd38079c14 a1=7ffd38079c18 a2=20 a3=7ffd38077940 items=4 ppid=5661 pid=5690 auid=1001 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts11 ses=1 comm="mv" exe="/bin/mv" key=(null)
type=CWD msg=audit(1489528471.598:669): cwd="/var/www"
type=PATH msg=audit(1489528471.598:669): item=0 name="/var/www" inode=22151424 dev=fc:01 mode=040755 ouid=0 ogid=0 rdev=00:00 nametype=PARENT
type=PATH msg=audit(1489528471.598:669): item=1 name="/var/www" inode=22151424 dev=fc:01 mode=040755 ouid=0 ogid=0 rdev=00:00 nametype=PARENT
type=PATH msg=audit(1489528471.598:669): item=2 name="foo" inode=22152394 dev=fc:01 mode=0100644 ouid=0 ogid=0 rdev=00:00 nametype=DELETE
type=PATH msg=audit(1489528471.598:669): item=3 name="bar" inode=22152394 dev=fc:01 mode=0100644 ouid=0 ogid=0 rdev=00:00 nametype=CREATE
$ cut -d: -f1 /etc/passwd | sort | uniq -d
Будет извлечено первое поле (имена пользователей) из :
-delimited / etc / passwd
- файл, отсортируйте результаты и сообщите о любых дубликатах.
Чтобы также получить UID и остальные дублированные записи passwd
:
cut -d: -f1 /etc/passwd | sort | uniq -d |
while read -r username; do
grep "^$username:" /etc/passwd
done
Чтобы получить только повторяющиеся имена пользователей и их UID:
cut -d: -f1 /etc/passwd | sort | uniq -d |
while read -r username; do
awk -F: -vu="$username" '$1 == u { print $1, $3 }' /etc/passwd
done
Небольшая заметка о вашем скрипте.Синтаксис выглядит в основном нормально, но вам понадобится ;
после break
и пробел после обоих \
(это может быть сокращение -and-paste error (теперь удалена редактированием)). Кроме того, я бы не стал указывать полные пути к стандартным утилитам, если для этого нет веских причин, а программе awk
не требуется GNU awk
, поэтому просто awk
] Сделаю.
do
где-то между while
и done
-
обычно сразу после read
, или после проверки того, что вы получили данные. set - $x
должен быть на отдельной строке,
или, по крайней мере, отделена от break
точкой с запятой (;
).
(Возможно, это хорошее место для размещения do
.)Предложения:
Вдохновленный ответом ebal , эта единственная команда awk
воспроизводит предполагаемую функциональность Сценарий OP:
awk -F: '{ uids[$1] = uids[$1] " " $3; }
END { for (u in uids) { if (uids[u] ~ /. /)
print "Duplicate User Name (" u "):" uids[u]; } }'
Как и в ответе ebal, он создает ассоциативный массив с записью для каждого уникального имени пользователя. Он устанавливает значение каждой записи для конкатенации пробела и UID для каждой строки для пользователя. Затем, после прочтения всего файла, он перебирает уникальные имена пользователей и проверяет, встречается ли это более одного раза - распознается по тому факту, что в списке UID есть пробел , отличный от первого символа, и он сообщает желаемую информацию.
Это будет вести себя странно, если UID в файле содержат пробелы.
Я бы сделал что-то подобное с помощью awk (однострочный):
awk -F: '{if ($1 in users) print "Duplicate Username: "$1 ; else users[$1]}' /etc/passwd
найти имя пользователя в переменной массива пользователей, при дублировании печати msg иначе добавьте пользователя в массив