2013-04-22 5 views
7

Zajmuję się tworzeniem biblioteki (zespołu CLI) dla systemu Linux. Chcę udostępnić metodę dla użytkowników biblioteki, aby przełączyć bieżącego efektywnego użytkownika i grupę. Głównym powodem jest zapewnienie kontroli dostępu (niektóre czynności są dozwolone tylko przez niektórych użytkowników), a po drugie, umożliwienie modyfikacji systemu plików jako określonego użytkownika.Zmienić bieżącego użytkownika systemu Linux w aplikacji C# działającej z Mono?

ja zidentyfikowali dwa możliwe podejścia:

1. Uruchom jako administrator i Mono P/Invoke libc rutyny jak seteuid itp

Po to realizowane przez ustawienie ów kawałek/usr/bin/mono, a następnie ustawienie z powrotem skuteczną użytkownika z mojej biblioteki (czyli po okresie czasu mono jest uruchomiony) powoduje awarię w mono, gdy kończy:

ERROR:handles.c:1940:_wapi_handle_update_refs: assertion failed: (thr_ret == 0) 

Native stacktrace: 

mono2 [0x8bb6c] 
    /lib/libc.so.6(__default_rt_sa_restorer_v2+0) [0x4020a5a0] 
    /lib/libc.so.6(gsignal+0x40) [0x4020920c] 

Logicznie rozumiem, że mogą być problemy wi zmieniając efektywnego użytkownika Mono, ponieważ zarządza on wieloma zasobami i może to powodować problemy.

2. Uchwyt uwierzytelniania w natywnej demona i nie zmienić Mono skuteczne użytkownikowi

Nie jestem pewien, czy są jakieś rozwiązania off-the-shelf do tego, ale koncepcyjnie myślę mieć demona działającego jako root, z którym biblioteka będzie się komunikować (na przykład poprzez kolejki komunikatów POSIX) w celu przeprowadzenia uwierzytelnienia. Demon działa jako root, aby móc odczytać/etc/shadow. Efektywny użytkownik Mono nie zostanie zmieniony, ale moja biblioteka będzie śledzić, którego "równoważnego użytkownika" proces jest uruchomiony. Niestety takie podejście nie pozwoli bibliotece na dostęp do systemu plików jako inny użytkownik.

Pytanie

Am I zakleszczony z drugiej opcji, czy jest jakiś sposób, aby rzeczywiście zmienić skuteczną użytkownikowi procesu Mono?

Dziękujemy!

Odpowiedz

5

Poniższe działa na moim oknie :)

EDIT # 1: Ten powinien być wykonywany jako root. (Fragment zaczerpnięty z: http://msdn.microsoft.com/en-us/library/w070t6ka.aspx)

using System; 
using System.Security.Permissions; 
using System.Security.Principal; 

public class ImpersonationDemo 
{ 
// Test harness. 
// If you incorporate this code into a DLL, be sure to demand FullTrust. 
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")] 
public static void Main (string[] args) 
{ 
    try { 
     // Check the identity. 
     Console.WriteLine ("Before impersonation: " + WindowsIdentity.GetCurrent().Name); 

     // Impersonate a user 
     using (WindowsIdentity newId = new WindowsIdentity("Your user name")) 
     using (WindowsImpersonationContext impersonatedUser = newId.Impersonate()) 
     { 
      // Check the identity. 
      Console.WriteLine ("After impersonation: " + WindowsIdentity.GetCurrent().Name); 
     } 

     // Releasing the context object stops the impersonation 
     // Check the identity. 
     Console.WriteLine ("After closing the context: " + WindowsIdentity.GetCurrent().Name); 
    } catch (Exception ex) { 
     Console.WriteLine ("Exception occurred. " + ex.Message); 
    } 
} 
} 
+0

Nie wiedziałem, że Mono wdrożył WindowsIdentity jako coś użytecznego - dzięki za wskazanie! Z przykładowym kodem wciąż mam problem z segmentacją, który miałem podczas używania seteuid(). Przyjmowanie tej odpowiedzi w każdym przypadku. – d99kris

+0

Z jakiej wersji mono korzystasz? Używam mono 3.0.7-1 na systemie x64 i kieruję do frameworka 4.0. – dna