Windows 2008 , 2012 Server RunAsUser Olayı

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Windows 2008 , 2012 Server RunAsUser Olayı

Mesaj gönderen vkamadan »

Merhaba değerli üyeler ,
windows 2003 üzerinde kısıtlı kullanıcı hesaplarında oturum açıldığında yönetimsel yetki isteyen programları çalıştırabilmesi için aşağıdaki CreateProcessWithLogonW API sini baz alan fonksiyon yardımıyla bir ara yazılım oluşturmuştuk, şifreli bir dosyadan yönetici kullanıcı adı şifresi ve domain bilgisi okuyup parametre geçtiğim EXE yi ilgili kullanıcı yetkileriyle başarıyla çalıştırıyordu , foksiyonun tamamı aşağıdaki gibi ;

Kod: Tümünü seç

function CreateProcessWithLogonW(
  lpUsername,
  lpDomain,
  lpPassword:PWideChar;
  dwLogonFlags:dword;
  lpApplicationName: PWideChar;
  lpCommandLine: PWideChar;
  dwCreationFlags: DWORD;
  lpEnvironment: Pointer;
  lpCurrentDirectory: PWideChar;
  const lpStartupInfo: tSTARTUPINFO;
  var lpProcessInformation: TProcessInformation
  ): BOOL; stdcall; external 'advapi32.dll';

  function RunAsUser(const Filename, Domain, Username, Password: string):
  Boolean;
  var
  StartupInfo: TStartupInfo;
  ProcessInfo: TProcessInformation;
  wFilename, wDomain, wUsername, wPassword: PWideChar;
  begin
  FillChar (StartupInfo, SizeOf(StartupInfo), #0);
  StartupInfo.cb := SizeOf(StartupInfo);
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow := SW_SHOWNORMAL;
 
  GetMem(wFilename, Length(Filename) * SizeOf(WideChar) +
  SizeOf(WideChar));
  GetMem(wDomain, Length(Domain) * SizeOf(WideChar) +
  SizeOf(WideChar));
  GetMem(wUsername, length(Username) * SizeOf(WideChar) +
  SizeOf(WideChar));
  GetMem(wPassword, length(Password) * SizeOf(WideChar) +
  SizeOf(WideChar));
 
  StringToWideChar(Filename, wFilename, Length(Filename) *
SizeOf(WideChar)
  + SizeOf(WideChar));
  StringToWideChar(Domain, wDomain, Length(Domain) *
SizeOf(WideChar)
  + SizeOf(WideChar));
  StringToWideChar(Username, wUsername, Length(Username) *
SizeOf(WideChar)
  + SizeOf(WideChar));
  StringToWideChar(Password, wPassword, Length(Password) *
SizeOf(WideChar)
  + SizeOf(WideChar));
 
  Result := CreateProcessWithLogonW(
  wUsername,
  wDomain,
  wPassword,
  0,
  wFilename,
  nil,
  0,
  nil,
  nil,
  StartupInfo,
  ProcessInfo);
 
  if Result then begin
  WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
  CloseHandle(ProcessInfo.hProcess);
  CloseHandle(ProcessInfo.hThread);
  end else
  RaiseLastOSError;
 
  FreeMem(wFilename);
  FreeMem(wDomain);
  FreeMem(wUsername);
  FreeMem(wPassword);
  end;
Fakat Windows 2008 ve 2012 de hata vermemesine rağmen çalıştırılan program yönetici yetkilerine sahip değilmiş gibi davranmaya devam ediyor alternatif bir yöntem önerinmiz var mı?
Volkan KAMADAN
www.polisoft.com.tr
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3077
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Re: Windows 2008 , 2012 Server RunAsUser Olayı

Mesaj gönderen sabanakman »

Vista ile gelen kullanıcı hesabı denetimi daha sonra çıkan tüm windowslarda gelişerek devam etti. Bu durum çoğu uygulamanın sistemden yönetici (Admin) yetkisi isteyerek çalışmasını gerektirmektedir. Muhtemelen yukarıdaki kodu çalıştıran programı sağ tıklayıp yönetici olarak çalıştır derseniz amacınıza ulaşabilirsiniz. Eğer çalışırsa o uygulamanız için..:
-dpr dosyasına

Kod: Tümünü seç

{$R 'ExecutionLevelRequireAdministratorManifest.RES' 'ExecutionLevelRequireAdministratorManifest.rc'}
yazın ve ekteki dosyaları proje .dpr dosyasıyla aynı klasöre yerleştirin. Bu sistemden yönetici yetkisi isteyerek uygulamanızın açılmasını sağlayacaktır.
Dosya ekleri
ExecutionLevelRequireAdministrator.zip
(1.39 KiB) 135 kere indirildi
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Re: Windows 2008 , 2012 Server RunAsUser Olayı

Mesaj gönderen vkamadan »

Merhaba @sabanakman,

cevabınız için teşekkür ederim ,

kısıtlı kullanıcıda ilgili ara programı yönetici olarak çalıştır dediğim zamanda windows kimlik doğrulama ekranı açılarak benden yönetici login bilgilerini istiyor,
sanırım programları yönetici kullanıcısıyla çalıştırmak için oluşturduğumuz ara yazılımı da Yönetici olarak çalıştırmak gerekiyor bu durumda olay sarpa sarıyor, bahsettiğiniz yöntemi UAC için denemiştim bu programın mutlaka yönetici yetkileriyle çalıştırması için gerçekten işe yarıyor, kabullenmek çok zor ama galiba yapacak birşey yok... yoksa var mı? :)
Volkan KAMADAN
www.polisoft.com.tr
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3077
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Re: Windows 2008 , 2012 Server RunAsUser Olayı

Mesaj gönderen sabanakman »

Windows kullanıcı yetki ayarlarıyla uğraşarak belki çözülebilir ama program yüklenince direkt çalıştırmalı derseniz bildiğim bir başka yolu yok maalesef.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Re: Windows 2008 , 2012 Server RunAsUser Olayı

Mesaj gönderen vkamadan »

Ozaman programı yönetici yetkileriyle çalıştırma ihtiyacını ortadan kaldırmanın yollarını aramaya başlayım,
aslında sorun şu, .NET ile yazılmış bir COM Objesi var Framework 3.5 ihtiyacı duyuyor, eğer programı yönetici yetkileriyle çalıştırmazsam Com Objesini kullanmak istediğim anda ekrana daha düşük versiyonlu bir framework ten bu framework uygun değildir hatası dönüyor 3.5 i göremiyor böyle bir durum var bunun nedeni hakkında fikriniz var mı?
Volkan KAMADAN
www.polisoft.com.tr
omurolmez
Üye
Mesajlar: 187
Kayıt: 31 Eki 2012 11:41

Re: Windows 2008 , 2012 Server RunAsUser Olayı

Mesaj gönderen omurolmez »

Windows, programlarımızın yetki gereken ve gerekmeyen kısımlarımızı ayırmamızı istiyor. Böylece, yetki gerekmeyen kısım yetki gereken kısımı çağırırsa, Windows araya UAC diyaloğu ekliyor ve yeni proses yetkili kullanıcının uzayında/oturumunda başlatılıyor. Ancak bu yöntem her zaman faydalı olmuyor. Öyle ki, bu yöntem ile başlayan iki proses iki farklı kullanıcı uzayında olduğu için birbirleri ile haberleşmeleri neredeyse imkansız.

Diğer bir yöntem, impersonation. Kısaca, prosesin herhangibir anda başka bir kullanıcı yetkilerini alarak çalışmaya devam etmesi oluyor.

Vaktiyle bir takım denemeler yapmışım. Kod derleniyor ancak çalışıp çalışmadığını hatırlamıyorum (En azından aranacak api lere fikir verir umarım).

Kod: Tümünü seç


unit libRunAs;
{ CREATED: 091007

}
interface

uses
  Windows;

const
  LOGON_WITH_PROFILE              =$00000001;
  LOGON_NETCREDENTIALS_ONLY       =$00000002;
  LOGON_ZERO_PASSWORD_BUFFER      =$80000000;

function CreateProcessWithLogonW(
  lpUsername: PWideChar;lpDomain: PWideChar;lpPassword: PWideChar;
  dwLogonFlags: DWORD; lpApplicationName: PWideChar;
  lpCommandLine: PWideChar; dwCreationFlags: DWORD; lpEnvironment: Pointer; lpCurrentDirectory: PWideChar;
  const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): BOOL; stdcall;

procedure RunAs(const
  ADomain, AUsername, APassword,
  AApplicationName, ACommandLine, ACurrentDirectory :WideString);

{Impersonate işlevi ile bu process, girilen kullanıcı yetkilerine sahip
 olur(disk işlemleri yapabilir). Ancak CreateProcess ve ShellExecute
 işlevlerini kullanarak, girilen kullanıcı hesabı içinde çalışan yeni
 prosesler oluşturamaz}
procedure Impersonate(const AUsername, ADomain, APassword :PChar);
procedure UnImpersonate;

implementation

uses
  SysUtils;

function CreateProcessWithLogonW; external 'advapi32.dll' name 'CreateProcessWithLogonW';

{source: http://yoy.be/item.asp?i269}
procedure RunAs(const
  ADomain, AUsername, APassword,
  AApplicationName, ACommandLine, ACurrentDirectory :WideString);
var
 si :TStartupInfo;
 pi :TProcessInformation;
begin
 {MSDN help te bir işlev için, işleve geçilen PWideChar değişkenlerin
 işlev tarafından değiştirebileceği, bu nedenle const olmamaları gerektiği,
 aksi halde AV oluşabileceği notu vardı. Bu yüzden işlev parametreleri const
 PWideChar yerine const PWideString yapıldı. Eğer yine de AV oluşursa,
 const niteleyicisi de kaldırılmalıdır.}
 ZeroMemory(@si, sizeof(si));
 ZeroMemory(@pi, sizeof(pi));
 si.cb :=sizeof(si);
 if not CreateProcessWithLogonW(
   PWideChar(AUsername), PWideChar(ADomain), PWideChar(APassword),
   LOGON_WITH_PROFILE,
   PWideChar(AApplicationName),
   PWideChar(ACommandLine),
   0,
   nil,
   PWideChar(ACurrentDirectory),
   si,
   pi) then
   RaiseLastOSError;
end;

{Elde edilen token ve sa, CreateProcessAsUser işlevine geçilir. Fakat,
 CreateProcessAsUser işlevi, "A required privilege is not held by the
 client" hatası döndürür. Kullanıcı hesabının SE_ASSIGNPRIMARYTOKEN_NAME ,
 SE_INCREASE_QUOTA_NAME ve SE_TCB_NAME("Act as Part of Operating System")
 izinleri olmalıdır (MSDN). Fakat AdjustTokenPrivileges access token e
 yeni izinler ekleyemez. İşlev sadece, varolan izinleri aktif veya pasif
 hale getirebilir (MSDN). Bu nedenle PrepareImpersonateToken işlevi _en
 azından Xp Home Edition üzerinde_ çalışmıyor.
 Not: To grant a user this privilege, go to User Manager, select
      Policies/User Rights, check "Show Advanced User Rights",
      select "Act as Part of Operating System", and add your user account.  
 }
procedure PrepareImpersonateToken(
  var AToken: THandle;
  var ASecAttr :TSecurityAttributes;
  const ADomain, AUsername, APassword :PChar);
var
// sa       :TSecurityAttributes;
 NewToken :THandle;
begin
 if not LogonUser(
   AUsername,
   ADomain,
   APassword,
   LOGON32_LOGON_BATCH,
   LOGON32_PROVIDER_DEFAULT,
   AToken) then
   RaiseLastOSError;
 with ASecAttr do begin
   nLength :=Sizeof(ASecAttr);
   bInheritHandle :=false;
   lpSecurityDescriptor :=nil;
   end;

 if not DuplicateTokenEx(
   AToken,
   TOKEN_ALL_ACCESS or TOKEN_READ or TOKEN_EXECUTE,//GENERIC_ALL,
   @ASecAttr,
   SecurityImpersonation,
   TokenImpersonation,
   NewToken) then
   RaiseLastOSError;
end;

procedure UnprepareImpersonateToken(const AToken: THandle);
begin
 CloseHandle(AToken);
end;

procedure Impersonate(const AUsername, ADomain, APassword :PChar);
var
 hToken :THandle;
begin
 if not LogonUser(
   AUsername, ADomain, APassword,
   LOGON32_LOGON_BATCH,
   LOGON32_PROVIDER_DEFAULT,
   hToken) then
   RaiseLastOSError;
 if not ImpersonateLoggedOnUser(hToken) then
   RaiseLastOSError;
end;

procedure UnImpersonate;
begin
 if not RevertToSelf then
   RaiseLastOsError;
end;

end.
Ömür Ölmez
Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Re: Windows 2008 , 2012 Server RunAsUser Olayı

Mesaj gönderen vkamadan »

Merhaba @omurolmez ,

Öncelikle cevabınız için teşekkür ederim ,

Örneklerinizden yola çıkarak uzun denemeler sonucunda bir sonuca varamadım, aslında kodlar işini yapıyor gibi görünüyor processlist içinde işlem gerçekten istediğim kullanıcı adıyla çalışıyor görünüyor lakin bizim sorunumuz sağ clickteki "Yönetici Olarak Çalıştır" kısmını simüle edememek çünkü zaten tam yetkili bir hesapla oturum açtığımızda ilgili uygulamayı yönetici olarak çalıştır demeden de çalışmıyor sorun burda.

Belirttiğim gibi uygulamayı elden geçirip bu gerekliliğe neden olan kısımları tespit etme yoluna yöneldik, peki böyle bir araç varmı çalışan EXE yönetimsel olarak yetki duyduğu için neye erişmek isteyipde erişemedi bunları gösteren bir araç var mı?
Volkan KAMADAN
www.polisoft.com.tr
omurolmez
Üye
Mesajlar: 187
Kayıt: 31 Eki 2012 11:41

Re: Windows 2008 , 2012 Server RunAsUser Olayı

Mesaj gönderen omurolmez »

Rica ederim, keşke yardım edebilseydim.

Böyle bir araç var mı bilmiyorum, gerçekten ihtiyaç (Ama olabilir de, Microsoft un SDK larıyla gelen çok ilginç araçlar var).

Prosesslist de yetkili kullanıcı adını görüyorsak, hala yetki sorununun aşılamaması ilginç geldi bana. Hangi com objeyi çalıştırmak istiyorsunuz (haftasonu denemek isterim) ?
Ömür Ölmez
Kullanıcı avatarı
vkamadan
Kıdemli Üye
Mesajlar: 1935
Kayıt: 17 Mar 2004 03:52
Konum: Adapazarı
İletişim:

Re: Windows 2008 , 2012 Server RunAsUser Olayı

Mesaj gönderen vkamadan »

c# ta yazdığımız bir Type Library var özel bir proje ve 3.5 framework ihtiyacı duyuyor, type lib i çağıracak projeyi yönetimsel yetkilerle çalıştırmadığımızda ilgili obje içinden versiyonu uyumsuz framework hatası dönüyor..
Volkan KAMADAN
www.polisoft.com.tr
Cevapla