Sudoer ayrıcalığımın zaman aşımına uğramadığını nasıl öğrenebilirim?


20

Sudo olarak bir komut çalıştıran bir komut dosyası üzerinde çalışıyorum ve Sudo ayrıcalıklarım zaman aşımına uğramışsa SADECE bir metin satırı yankılanıyor, bu yüzden yalnızca sudo ile bir komut çalıştırmak kullanıcı (root değil) tekrar parolasını yazmak gerekir.

Bunu nasıl doğrularım? Sudo $(id -u)olarak çalışırken bile geçerli kullanıcı kimliğimi döndüreceğini unutmayın, böylece 0 ile eşleştirmek için kontrol edilemez ...

Bunu sessizce kontrol edecek bir yönteme ihtiyacım var.

Yanıtlar:


28

-nHala ayrıcalıklarınız olup olmadığını kontrol etmek için seçeneği kullanın ; from man sudo:

-n , - etkileşimli olmayan

Kullanıcıdan herhangi bir girdi girmesini istemeyin. Komutun çalışması için bir parola gerekiyorsa, sudo bir hata mesajı görüntüler ve çıkar.

Örneğin,

sudo -n true 2>/dev/null && echo Privileges active || echo Privileges inactive

İmtiyazların, kontrol etme sudo -n trueve gerçekte kullanma arasındaki sürenin dolmasının mümkün olabileceğini unutmayın . Doğrudan sudo -n command...bir mesajla denemek ve bir hata durumunda bir mesajı görüntülemek ve muhtemelen sudoetkileşimli olarak çalışmayı tekrar deneyebilirsiniz .

Düzenleme: Ayrıca ruakh'ın açıklamasına bakınız.


Teşekkürler Daha önce benzer bir şey denedim ama istediğim gibi çalışamadım.
TonyMorello

3
Re: " sudo -n trueOnlarla kontrol ve aslında onları kullanma arasında ayrıcalıkların süresinin dolmasının mümkün olduğunu unutmayın ": Belgeler bu noktada biraz belirsiz, ama bence bir sudokomut çalıştırmanın sudo -n truezaman aşımını yeniden ayarlayacağını düşünüyorum saat. Her iki durumda da -v, açıkça bu şekilde belgelenmiştir ve sudo -n -vmuhtemelen sudo -n truebu amaç için olduğundan daha uygundur .
ruakh

Bu gerçekten de sessiz olacak olsa imtiyaz yoktur, eğer sistem dergide hatayı kaydeder: hostname sudo[8870]: username : a password is required ; TTY=pts/0 ; PWD=/home/username ; USER=root ; COMMAND=/usr/bin/true. Örneğin bash isteminde kullanırsanız, birçok hata iletisine neden olur.
Rogach

Ayrıcalıklar varsa, pam_unix ve sudo command execution'dan hata ayıklama günlüğü olacaktır.
Rogach

8

Çalıştırmak:

sudo -nv

Sudo ayrıcalıklarınız zaman aşımına uğradıysa, bu çıkış kodu 1 ve çıkış ile çıkar:

sudo: a password is required

Geçerli önbelleğe alınmış kimlik bilgileriniz varsa, bu komut başarılı olur ve hiçbir şey vermez.

Yani, hepsini bir araya getirmek için, geçerli önbelleğe alınmış kimlik bilgilerinizin olup olmadığını sessizce kontrol edecek bir komut dosyası :

if sudo -nv 2>/dev/null; then
  echo "no sudo password required"
else
  echo "sudo password expired"
fi

Belirtilen diğer yanıtlar / yorumlar gibi, -vsudo önbelleğe alma kimlik bilgileri oluşturmak için kimlik doğrulaması isteyen veya başka herhangi bir istek varsa sudo sessizce silen seçeneği ("doğrulama") ve sudo'nun oluşturulmasını -nönler kimlik doğrulama istemi gibi etkileşimli istemler.


Bu iyi bir çözüm ... Daha önce denedim ama AlexP'nin cevabı tam olarak ihtiyacım olanı yapıyor ... Sanırım -n parametresini daha önce yanlış
anladım

1

sudo -nviyi ç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, &current_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(&timestamp_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, &current_time, &time_since_sudo);
        found = time_since_sudo.tv_sec < TIMEOUT * 60;
        break;
      }
    }

    offset += timestamp_entry_header[1];
  }

  fclose(timestamp_fd);

  return !found;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.