sudo -nv
iyi çalışıyor, ancak sudo hataları ve pam kimlik doğrulama bilgileri ile sistem günlüklerini kirletiyor. Bash istemim için sudo ayrıcalıklarını kontrol etmem gerekiyordu, bu yüzden oldukça sık çalıştırıldı ve günlüklerim neredeyse sadece bu gürültüyü içeriyordu.
Sudo timestamp dosyasını doğrudan ayrıştırmak mümkündür - bunun için küçük bir C util yazdım:
/* compile and set permissions: */
/* $ gcc checksudo.c -o checksudo -std=gnu99 -O2 */
/* $ chown root:root checksudo */
/* $ chmod +s checksudo */
#define USERNAME "replace-with-your-username"
#define TIMEOUT 5
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <time.h>
void timespec_diff(struct timespec *start, struct timespec *stop, struct timespec *result) {
if ((stop->tv_nsec - start->tv_nsec) < 0) {
result->tv_sec = stop->tv_sec - start->tv_sec - 1;
result->tv_nsec = stop->tv_nsec - start->tv_nsec + 1000000000;
} else {
result->tv_sec = stop->tv_sec - start->tv_sec;
result->tv_nsec = stop->tv_nsec - start->tv_nsec;
}
return;
}
int main(int argc, char** argv) {
if (geteuid() != 0) {
printf("uid is not 0 - checksudo must be owned by uid 0 and have the setuid bit set\n");
return 2;
}
struct timespec current_time;
if (clock_gettime(CLOCK_BOOTTIME, ¤t_time) != 0) {
printf("Unable to get current time: %s\n", strerror(errno));
return 2;
}
struct stat ttypath_stat;
if (stat(ttyname(0), &ttypath_stat) != 0) {
printf("Unable to stat current tty: %s\n", strerror(errno));
return 2;
}
FILE* timestamp_fd = fopen("/var/run/sudo/ts/" USERNAME, "rb");
if (timestamp_fd == NULL) {
printf("Unable to open sudo timestamp file: %s\n", strerror(errno));
return 2;
}
long offset = 0;
int found = 0;
while (1) {
if (fseek(timestamp_fd, offset, SEEK_SET) != 0) {
printf("Failed to seek timestamp file: %s\n", strerror(errno));
return 2;
}
unsigned short timestamp_entry_header[4];
if (feof(timestamp_fd)) {
printf("matching timestamp not found\n");
return 2;
}
if (fread(×tamp_entry_header, sizeof(unsigned short), 4, timestamp_fd) < 4) {
break;
}
if (ferror(timestamp_fd)) {
printf("IO error when reading timestamp file\n");
return 2;
}
// read tty device id
if (timestamp_entry_header[2] == 2 && timestamp_entry_header[3] == 0) {
if (fseek(timestamp_fd, offset + 32, SEEK_SET) != 0) {
printf("Failed to seek timestamp file: %s\n", strerror(errno));
return 2;
}
dev_t tty_dev_id;
if (fread(&tty_dev_id, sizeof(dev_t), 1, timestamp_fd) < 1) {
printf("EOF when reading tty device id\n");
return 2;
}
if (tty_dev_id == ttypath_stat.st_rdev) {
// read timestamp
if (fseek(timestamp_fd, offset + 16, SEEK_SET) != 0) {
printf("Failed to seek timestamp file: %s\n", strerror(errno));
return 2;
}
struct timespec sudo_time;
if (fread(&sudo_time, sizeof(struct timespec), 1, timestamp_fd) < 1) {
printf("EOF when reading timestamp\n");
return 2;
}
struct timespec time_since_sudo;
timespec_diff(&sudo_time, ¤t_time, &time_since_sudo);
found = time_since_sudo.tv_sec < TIMEOUT * 60;
break;
}
}
offset += timestamp_entry_header[1];
}
fclose(timestamp_fd);
return !found;
}