मुझे कैसे पता चलेगा कि मेरा सुडोल विशेषाधिकार समाप्त हो गया है?


20

मैं एक स्क्रिप्ट पर काम कर रहा हूं, जो कि sudo के रूप में एक कमांड चलाता है और केवल पाठ की एक पंक्ति को तब ही echoes करता है यदि मेरे sudo विशेषाधिकार समाप्त हो गए हैं, इसलिए केवल sudo के साथ कमांड चलाने पर मेरे उपयोगकर्ता (रूट) को अपना पासवर्ड फिर से टाइप करने की आवश्यकता होगी।

मैं इसे कैसे सत्यापित करूं? ध्यान रखें कि $(id -u)सुडो के रूप में चलने पर भी मेरी वर्तमान उपयोगकर्ता आईडी वापस आ जाएगी ताकि इसे 0 से मिलान करने के लिए जाँच न की जा सके ...

मुझे एक ऐसी विधि की आवश्यकता है जो इसे चुपचाप जाँच ले।

जवाबों:


28

-nयह जांचने के लिए विकल्प का उपयोग करें कि क्या आपके पास अभी भी विशेषाधिकार हैं; से man sudo:

-n , - गन-इंटरेक्टिव

किसी भी प्रकार के इनपुट के लिए उपयोगकर्ता को संकेत देने से बचें। यदि कमांड चलाने के लिए पासवर्ड की आवश्यकता होती है, तो sudo एक एरर मैसेज और एक्जिट प्रदर्शित करेगा।

उदाहरण के लिए,

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

ज्ञात हो कि विशेषाधिकारों के साथ जाँच करना sudo -n trueऔर वास्तव में उनका उपयोग करने के बीच समाप्त होना संभव है। आप सीधे साथ प्रयास करना चाहते हैं sudo -n command...और विफलता के मामले में एक संदेश प्रदर्शित करते हैं और संभवतः sudoअंतःक्रियात्मक रूप से चल रहे हैं।

संपादित करें: नीचे भी रुख की टिप्पणी देखें।


धन्यवाद, मैंने पहले भी ऐसा ही कुछ करने की कोशिश की है, लेकिन मैं अभी उस तरह से काम नहीं कर पाया जैसा मैं चाहता था।
टोनीमोर्लो

3
पुन: "इस बात से अवगत रहें कि विशेषाधिकारों के साथ जाँच करना sudo -n trueऔर वास्तव में उनका उपयोग करने के बीच समय सीमा समाप्त हो जाना संभव है": प्रलेखन इस बिंदु पर थोड़ा अस्पष्ट है, लेकिन मुझे लगता है कि एक sudoकमांड चलाना , यहां तक ​​कि बस sudo -n true, टाइमआउट फिर से सेट होगा। घड़ी। किसी भी तरह से, -vस्पष्ट रूप से ऐसा करने के रूप में प्रलेखित है, और sudo -n -vसंभवतः sudo -n trueइस उद्देश्य के लिए वैसे भी अधिक उपयुक्त है ।
बरबाद

हालांकि यह वास्तव में चुप होगा, यह सिस्टम जर्नल में त्रुटि करेगा यदि कोई विशेषाधिकार नहीं हैं hostname sudo[8870]: username : a password is required ; TTY=pts/0 ; PWD=/home/username ; USER=root ; COMMAND=/usr/bin/true:। यदि आप इसे bash प्रॉम्प्ट में उपयोग करते हैं, उदाहरण के लिए, इसके परिणामस्वरूप बहुत सारे त्रुटि संदेश मिलेंगे।
रोज डेच

और यदि विशेषाधिकार हैं, तो pam_unix और sudo कमांड निष्पादन से डिबग लॉगिंग होगी।
दुष्ट 12

8

Daud:

sudo -nv

यदि आपके sudo विशेषाधिकार समाप्त हो गए हैं, तो यह 1 और आउटपुट के एक्जिट कोड के साथ बाहर निकल जाएगा:

sudo: a password is required

यदि आपके पास वैध कैश क्रेडेंशियल हैं, तो यह कमांड सफल होगा और कुछ भी आउटपुट नहीं करेगा।

तो, यह सब एक साथ रखने के लिए, यहाँ एक स्क्रिप्ट है जो चुपचाप जाँच करेगा कि आपके पास वैध कैश क्रेडेंशियल हैं:

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

उल्लेखित अन्य उत्तरों / टिप्पणियों के अनुसार, -vविकल्प ("मान्य") सूडो को चुपचाप कैश की गई साख को नवीनीकृत करता है यदि कोई प्रमाणिकता उत्पन्न करने के लिए प्रमाणीकरण के लिए कोई या कोई अन्य संकेत हैं, और -nविकल्प ("गैर-संवादात्मक") सूडो को उत्पन्न होने से रोकता है। किसी भी इंटरैक्टिव संकेत, जैसे प्रमाणीकरण शीघ्र।


यह एक अच्छा समाधान है ... मैंने इसे पहले भी आजमाया था, लेकिन एलेक्सपी का जवाब ठीक वही है जो मुझे चाहिए था ... मुझे लगता है कि मैंने पहले एक गलत समझा था
टोनीमोरेलो

1

sudo -nvठीक काम करता है, लेकिन सिस्टम सिस्टम sudo त्रुटियों और pam प्रमाणीकरण जानकारी के साथ लॉग करता है। मुझे अपने बैश प्रॉम्प्ट के लिए sudo विशेषाधिकारों की जांच करने की आवश्यकता थी, इसलिए इसे काफी बार निष्पादित किया गया था और मेरे लॉग में लगभग केवल इसी शोर शामिल था।

सूडो टाइमस्टैम्प फ़ाइल को सीधे पार्स करना संभव है - मैंने इसके लिए एक छोटा सी उपयोग लिखा है:

/* 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;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.