Setuid Yazılım Örneği
Önceki XXIX. Oylum - Kullanıcılar ve Gruplar Sonraki
Setuid Yazılım Örneği
Buradaki örnekte, kendi etkin kullanıcı kimliğini değiştiren bir yazılım gösterilmiştir.
Örnek, caber-toss diye bilinen bir oyundan alınmıştır. Örnek, sadece oyun sürecinin yazabildiği scores dosyasının değiştirilmesi için yapılan işlemleri içerir. Oyunun çalıştırılabilir dosyasının setuid bitinin scores dosyasının sahibi olan kullanıcı için etkin olarak kaydedildiğini varsayıyoruz. Genellikle sistem yöneticisinin yaptığı bir işlemin sonucu olarak bu amaçla games kullanıcısının kullanıldığını varsayalım.
Çalıştırılabilir dosyanın kipinin 4755 olduğunu varsayarsak, ls -l komutu şöyle bir çıktı üretir:
-rwsr-xr-x   1 games    184422 Jul 30 15:17 caber-toss
Setuid biti dosya kiplerinde s olarak gösterilir.
scores dosyasının kipinin ise 644 olduğunu varsayarak aynı komut şu çıktıyı üretir:
-rw-r--r--  1 games           0 Jul 31 15:33 scores
Buradaki yazılım parçası kullanıcı kimliklerin nasıl değiştirildiğini gösterir. Yazılım, dosya kimliği desteği varsa bu özelliği yoksa etkin ve gerçek kullanıcıları takaslamak için setreuid işlevini kullanmak üzere koşullandırılmıştır.
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>


/* Etkin ve gerçek kullanıcı kimlikleri hatırlayalım. */

static uid_t euid, ruid;


/* Etkin kullanıcı kimliği özgün değerine ayarlayalım. */

void
do_setuid (void)
{
  int status;

#ifdef _POSIX_SAVED_IDS
  status = seteuid (euid);
#else
  status = setreuid (ruid, euid);
#endif
  if (status < 0) {
    fprintf (stderr, "Kullanıcı kimliği etkinleştirilemedi.\n");
    exit (status);
    }
}


/* Etkin kullanıcı kimliği gerçek kullanıcı kimliğe ayarlayalım. */

void
undo_setuid (void)
{
  int status;

#ifdef _POSIX_SAVED_IDS
  status = seteuid (ruid);
#else
  status = setreuid (euid, ruid);
#endif
  if (status < 0) {
    fprintf (stderr, "Kullanıcı kimliği etkinleştirilemedi.\n");
    exit (status);
    }
}

/* Asıl kod. */

int
main (void)
{
  /* Etkin ve gerçek kullanıcı kimlikleri hatırlayalım.  */
  ruid = getuid ();
  euid = geteuid ();
  undo_setuid ();

  /* Oynayalım ve puanları kaydedelim.  */
  ...
}
main işlevinin yaptığı ilk işlem etkin kullanıcı kimliğe gerisin geriye gerçek kullanıcı kimliğe ayarlamaktır. Kullanıcı oyunu oynarken bir dosya erişimi yapmak isterse erişim yetkileri gerçek kullanıcı kimliğe göre saptansın diye böyle yapılır. Oyun yazılımı sadece scores dosyasına puanı yazacağı zaman etkin kullanıcı kimliğini dosyanın kullanıcı kimliği yapar:
/* Puanı kaydedelim. */

int
record_score (int score)
{
  FILE *stream;
  char *myname;

  /* scores dosyasını açalım. */
  do_setuid ();
  stream = fopen (SCORES_FILE, "a");
  undo_setuid ();

  /* Puanı dosyaya yazalım. */
  if (stream)
    {
      myname = cuserid (NULL);
      if (score < 0)
        fprintf (stream, "%10s: Couldn't lift the caber.\n", myname);
      else
        fprintf (stream, "%10s: %d feet.\n", myname, score);
      fclose (stream);
      return 0;
    }
  else
    return -1;
}
Önceki Üst Ana Başlık Sonraki
Setuid Erişiminin Etkinleştirilmesi ve İptali Başlangıç Setuid Yazılımları Geliştirmek için İpuçları
Bir Linux Kitaplığı Sayfası