getUID() setUID()

Post Reply
Message
Author
pcAlko
Posts: 70
Joined: 14. May 2007 19:27

getUID() setUID()

#1 Post by pcAlko »

Hallo Community!

Ich habe mir ein Programm gebastelt
das als demon rennen soll.
Also es wird vom root gestartet.
Jetzt möchte ich natürlich das Programm als zb. Nobody rennen lassen.

Ich versteh aber nicht wie ich da von Nobody auf die UID kommen soll.
Würde das gerne in einem Configfile angeben
Da mehrere Threads unter verschiedenen User laufen sollen.
Möchte ich sowas wie in der art
config:
server= nobody
measure= runner
starter= georg

hat jemand eine Idee wie ich das realisieren kann?
Danke im vorraus!
8) pcAlko

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#2 Post by Janka »

Threads eines Prozesses haben grundsätzlich immer dieselben UIDs. Du musst also statt Threads getrennte Prozesse benutzen, und diese beispielsweise über Pipes, Sockets oder Shared Memory miteinander kommunizieren lassen.

man fork
man setuid
man seteuid

Vom Namen auf die UID kommst du, indem du die Datei /etc/passwd ausliest.

Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

pcAlko
Posts: 70
Joined: 14. May 2007 19:27

#3 Post by pcAlko »

Hallo Janka!

was ist der unterschied zwischen einem
efektiven Benutzer
und dem realen Benutzer

in den manpages steht für seteuid
"Unprivileged user processes may only set the effective user ID to the real user ID, the
effective user ID or the saved set-user-ID"

heißt das das auch Unprivilegierte user Prozesse die ID ändern können???

8) pcAlko

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#4 Post by Janka »

Der effektive Benutzer ist der, der für Systemaufrufe wirksam wird. Der reale Benutzer ist der, der aus root heraus umgewandelt wurde. login, kdm etc. starten selbst als root, forken beim Login eine Shell bzw. xsession und wandeln diese in den *realen* Benutzer um. Dazu benutzen sie den Systemaufruf setuid(), den nur root verwenden kann. Der reale Benutzer kann dann z.B. ein SUID-Programm aufrufen. Dabei wird dann aber nur der *effektive* Benutzer umgewandelt, der Mechanismus ist im Prinzip derselbe, als wenn ein Programm seteuid() aufruft.

Nur wenige Programme müssen zwischen realem Benutzer und effektivem Benutzer einen Unterschied machen. Wenn du nicht gerade ein Login-Programm schreiben willst, nimm seteuid().

Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

pcAlko
Posts: 70
Joined: 14. May 2007 19:27

#5 Post by pcAlko »

Hallo Janka!

Zuerst hab ich Deinen Beitrag nicht verstanden,
aber umso öfter ich in lese ... (geht mit ein Licht auf :idea: )

Also folgendes Szenario! (berichtige mich bitte wenn ich falsh liege)

Wenn mein Programm als Deamon vom root gestartet wird,
ich den realen Benutzer mit setuid() auf meinen Account zb. pcAlko ändere
und ich mit dem Programm eine Desktop-Aplikation starte zb. tvtime
startet die Aplikation auf meinem Desktop
und nicht auf dem Desktop von zb. Georg.
(sollte dieser auf meinem Computer ebenfalls seinen Account aktiviert haben)

Ändere ich jetzt mit seteuid() den effektiven User auf Georg
startet tvtime ebenfalls in meinem Account nur aber mit der User Berechtigung von Georg.

Hab ich das so richtig verstanden?
Was ist jetzt aber wenn ich mich zweimal als pcAlko angemeldet habe?
Auf welchem desktop startet dann tvtime??
oder kommt da dann setreuid() ins Spiel?

8) pcAlko

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#6 Post by Janka »

Mit dem Desktop hat das gar nichts zu tun. Die Rechte auf einen bestimmten X-Server werden von X selbst verwaltet (der X-Server läuft als root!) und alle Benutzerprogramme, die irgendetwas auf dem Desktop darstellen wollen müssen über Sockets oder Shared Memory Nachrichten an den X-Server schicken. Selbst root darf nicht ohne weiteres auf einen Xserver zugreifen, der einem anderen Benutzer gehört. Dazu ist jeweils ein "Magic Cookie" notwendig.

Auf welchem X-Server ein Programm seine Fenster darstellt, kann man z.B. mit der Umgebungsvariable DISPLAY beeinflussen:

Code: Select all

$ export DISPLAY=entfernter_host:0
$ xterm
Voraussetzung dafür, dass der xterm auf dem Display 0 von entfernter_host erscheint, ist, dass der xterm ausführende Benutzer das richtige Magic Cookie für dieses Display besitzt.

man xauth

Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

pcAlko
Posts: 70
Joined: 14. May 2007 19:27

#7 Post by pcAlko »

He super,
danke für die Info!
Wieder mal was dazu gelernt.

Aber dazu später ..
sonst kommen wir vom 100 fachen
ins 1000 fache :D

Zurück zu setuid()
Aber im Prenzip wenn wir das mit dem Desktop weg lassen
habe ich doch rechnt, oder?
Linux ist ja ein Multi-User system.
nur das hat dann für mich eh keine relevaz!

Ich bin jetzt beim Testen auf folgendes Problem gestossen:
wenn ich setuid() oder seteuid() auf eimem Thread ausführe
haben auch alle anderen Threads die gleiche UID.

Kann man die nicht einzeln vergeben?

Ich hab mir da ja einen Server zusammengestrickt der auf
ein paar Threads läuft.
Jetzt habe ich natürlich auch andere Threads
die über die Serielle messungen durchführt
oder auch daten einliest.

bei den messungen ist es ja kein Problem,
da ich nach dem ioperm ruhig auf zb. Nobody umschalten kann.
Aber was ist wenn ich daten einlese od. schreibe
Da bleibt mir zwar die Möglichkeit
zb. eine Gruppe auf /dev/tty zu setzen.

Aber wenn jetzt ein Road Kiddy irgend einen Buffer-Overflow
auf meinem server entdeckt und eine Shell öffnen kann
hat er dann ja auch zugriff auf die Serielle.
Ok, wenn ein Profi diese Lücke entdeckt
kann er natürlich, hab ich mir sagen lassen,
ohne weiters root rechte erlangen,
auch bei Nobody.

Trotzdem würde ich mir bei verschiedenen UID's
doch etwas sicherer vorkommen.

Ich muss dazu sagen
dass ich mit den pthreads arbeite.
da ich nicht weiß wie ich mit fork()
die einzelnen threads beim zugriff auf Variablen sperren kann.

Was verwendest Du?
und wäre es mit fork() möglich den Threads
verschiedene UID's zu geben?

8) pcAlko

User avatar
Janka
Posts: 3585
Joined: 11. Feb 2006 19:10

#8 Post by Janka »

Threads eines Prozesses haben immer dieselbe UID, EUID usw.. Du *musst* mit mehreren Prozessen statt mit Threads arbeiten. Wenn du fork() benutzt, wird ein neuer Prozess mit einem getrennten Datensegment gestartet. Daher existieren dann alle Variablen *zweimal*. Die Werte werden kopiert, sobald einer der Prozesse seine Variable ändert -- das geschieht transparent, so dass es so aussieht, als ob die Variablen in jedem Kindprozess mit den Werten zum Zeitpunkt des fork() vorinitialisiert werden.

Um gemeinsame Variablen zu haben, musst du *vor* dem fork() ein Shared Memory beispielsweise mit mmap() anfordern und da eine Datenstruktur mit den Variablen reinlegen.

Den Programmcode teilen sich die beiden Prozesse -- aber der ist ja sowieso read-only. Es gibt nun zwei Fälle: Entweder, der geforkte Prozess lädt kurz darauf mittels exec() oder execve etc. neuen Programmcode -- das ist der häufigere Fall --, oder er behält halt den Programmcode des Vaterprozesses und läuft mit einem anderen Programmzähler etc. weiter.


Das klingt jetzt alles sehr kompliziert, wenn du Programmieren mit Threads gewohnt bist, aber es ist der unter UNIX übliche (und vor allem alle Funktionalität ermöglichende) Weg, Nebenläufigkeit zu realisieren. Man gewinnt dabei auch Übersicht, weil man sich Gedanken machen muss, wo zwischen den Nebenläufigen Programmteilen auf welche Weise wann Daten ausgetauscht werden. Kurz: Es hilft ungemein, Spaghetticode (und damit Deadlocks und falsche Synchronisierung) zu vermeiden.

Überhaupt wird der ganze Threadkram oft völlig sinnlos eingesetzt, um nichtblockierendes Warten zu ermöglichen. Das geht bei UNIX aber bereits problemlos mit select() oder poll() *ohne* Threads und sonstige Kopfstände.

Janka
Ich vertonne Spam immer in /dev/dsp statt /dev/null.
Ich mag die Schreie.

pcAlko
Posts: 70
Joined: 14. May 2007 19:27

#9 Post by pcAlko »

He super!
Da purzeln ja nur so die Infos!
Da muss ich mal nach regagieren,
wenn ich etwas mehr Zeit dafür habe.

Dann sag ich nochmals Danke
und hoffe ich darf Dein Wissen wieder einmal
in anspruch nehmen.

Noch ein schönes Wochenende

8) pcAlko

Post Reply