Kök olarak çalışan bir damon tarafından başlatılan bir işlemim var, şimdi bu işlemin ayrıcalıklarını ortalama kullanıcınızın ayrıcalıklarına "düşürmek" istiyorum. Mümkün mü? Evet ise nasıl?
Not: Mac'te unix çalıştırma
Kök olarak çalışan bir damon tarafından başlatılan bir işlemim var, şimdi bu işlemin ayrıcalıklarını ortalama kullanıcınızın ayrıcalıklarına "düşürmek" istiyorum. Mümkün mü? Evet ise nasıl?
Not: Mac'te unix çalıştırma
Yanıtlar:
Sürecin kendisi setuid (2) 'i çağırmalıdır. Henüz yapmadıysanız, kroot (8) içinde çalıştırmayı da araştırmalısınız. Bildiğim kadarıyla, kökün başka bir sürecin uid'ini değiştirmesinin bir yolu yok.
Kök olarak çalıştırmanın nedeni bağlantı noktalarını bağlamaksa, daha yüksek bir bağlantı noktasında normal bir kullanıcı olarak çalıştırmayı ve 80/443 / vb. Bağlantı noktasını daha yüksek bağlantı noktasına iletmek için OS X'te ipfw (8) kullanmanızı öneririm:
http://support.crashplanpro.com/doku.php/recipe/forward_port_443_to_pro_server_on_mac_osx
setuid()
yalnız aramak kesinlikle yeterli değil.
sudo tcpdump -Z
kendi işleminin kök ayrıcalıklarını bırakmak için initgroups (3), setgid (2) ve setuid (2) kullanır.
# code taken from:
# http://www.opensource.apple.com/source/tcpdump/tcpdump-32/tcpdump/tcpdump.c
/* Drop root privileges and chroot if necessary */
static void
droproot(const char *username, const char *chroot_dir)
{
...
if (initgroups(pw->pw_name, pw->pw_gid) != 0 ||
setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) {
fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n",
username,
(unsigned long)pw->pw_uid,
(unsigned long)pw->pw_gid,
pcap_strerror(errno));
exit(1);
}
...
}
initgroups
, setgid
, setuid
(Son!) Tam UNix sağ paradigma ve her zaman takip edilmelidir. Buna ek olarak, sorumlu bir "droproot" işlevi, üç temel işlev de başarı döndürse bile uid ve gid ayarının gerçekten yapılıp yapılmadığını kontrol eder.
Komutları aşağıdakileri kullanarak diğer kullanıcılar gibi çalıştırabilirsiniz su
:
su USERNAME -c COMMAND
Ayrılacak COMMAND
ayrıcalıklarla çalışacak USER
.
Varsayılan olarak, su
komutu çalıştırmak için hedef kullanıcının kabuk yorumlayıcısını kullanacağını unutmayın. Bunun aksine, varsayılan davranışı , geçerli ortamı çalıştıran bağımsız bir program olarak sudo
davranmaktır COMMAND
. Elbette bu varsayılan davranışlar çeşitli anahtarlar ve ortam değişkenleri ile değiştirilebilir.
su
USERNAME tanımlı bir kabuk yoksa (veya /bin/false
), sudo ise çalışmıyor gibi görünüyor .
su
bunu yansıtacaktır. Ancak, -s
anahtar kullanılarak her zaman geçersiz kılınabilir. su
Amacının belirli bir kullanıcının normalde kabuğundan etkilenen davranışını taklit etmek olduğunu unutmayın . Buna karşılık, sudo
(varsayılan olarak) hedef kullanıcının kabuk ayarını yok sayar.
Ayrıcalıkları bırakmak için, root olmayan bir kullanıcıya bırakmanız gerekir. O zaman sadece bu kullanıcıya geçme meselesi:
#define UNPRIV_UID 48
#define UNPRIV_GID 48
if (getuid() == 0) { // we are root
// setting UID/GID requires root privileges, so if you don't set
// the GID first, you won't be able to do it at all.
if (setgid(UNPRIV_GID)!=0) die("Failed to set nonroot GID");
if (setuid(UNPRIV_UID)!=0) die("Failed to set nonroot UID");
}
ASSERT(getuid() != 0);
Bunun bir sarmalayıcı komut dosyası yerine programın kendi içinde yapıldığını unutmayın . Birçok program belirli bir amaç için kök ayrıcalıkları gerektirir (örneğin, düşük numaralı bir bağlantı noktasına bağlanmak için), ancak bundan sonra root'a gerek yoktur. Bu nedenle bu programlar kök olarak başlayacak, ancak artık ihtiyaç duyulmadığında ayrıcalıkları bırakacaktır.
Kök ayrıcalıklarına ihtiyacınız yoksa, root olarak çalıştırmayın. Örneğin:
# Change this:
myprog -C /my/config/file
# To this:
sudo -u someuser myprog -C /my/config/file
# Or this
su someuser -c "myprog -C /my/config/file"
setuid
İşlevi yalnızca setleri etkili UID değil gerçek UID. setreuid
Sürecin ayrıcalıkları geri alabilmesini istemiyorsanız kullanmalısınız . (Ve yukarıdaki kod ek grup ayrıcalıklarıyla da ilgili değildir. Sadece çoğunlukla güvenilir kodun başlatılması için uygundur.)
setuid()
gerçek ve kaydedilmiş kullanıcı kimlikleri ayarlar; düşünüyor olabilirsiniz seteuid()
. Tüm sistemlerde setreuid()
bulunmaz, bu yüzden her yerde kullanılamaz. Tam anlambilimi setuid()
karmaşıktır, ancak 0 Euro'ya sahipseniz, tüm geleneksel kullanıcı kimliği ayrıcalıklarını bırakabilirsiniz setuid()
. Bu cevap en büyük ihmal olduğunu initgroups
veya setgroups
yanı sıra çağrılmalıdır setgid
ve setuid
ve bu daha kapsamlı iddialar sonunda yapılmalıdır.
Farklı bir yürütülebilir dosya yürütüyorsanız, örneğin , belki de dolaylı olarak veya gibi bir işlev aracılığıyla çağırırsınız veya işlev ailesinin execve
başka bir exec
parçasını çalıştırıyorsanız ve alt işlem başlangıçtan itibaren ayrıcalıklar olmadan çalışmalıdır, o zaman en basit yol bir kabuk dahil ve çağrı . Aşağıda Perl'de kodun nasıl görünebileceğine ilişkin genel bir bakış, ihtiyaç duyduğunuz alıntıyı gösterir:system
popen
su
$shell_command = quotemeta($path_to_executable) . " --option";
$shell_command =~ s/'/'\\''/; # protect single quotes for the use as argument to su
$su_command = sprintf("su -c '%s' %s", $shell_command, quotemeta($user_name));
open(PIPE, "$su_command |") or die;
Alt işlemin kök olarak başlatılması, ancak ayrıcalıkların daha sonra bırakılması gerekiyorsa , bu yanıtta , bir işlemdeki ayrıcalıkların nasıl eski sürüme geçirileceğini gösteren koda bakın .