2017-02-01 6 views
2

私は、マシンの電源が入っている限り、生き続ける必要があるJobObjectを作成するWindowsサービスを持っています。このJobObjectを使用していつでも終了/開始できます。私はサービスを起動してプロセスが実行されていることを確認するためにそれを作成しており、通常のユーザーはそのプロセスを終了することはできません。サービスで作成されたJobObjectを、ユーザーセッションプロセスから開きます。

しかし、私はユーザーセッションからこのJobObjectへのハンドルを開くことができないようですが、NULL DACLで作成しているにも関わらず、常にアクセス拒否(5)エラーが発生します。

Open an Event object created by my service from my application私は幾分関連する質問を見つけましたが、NULL DACLの場合でもJOB_OBJECT_ASSIGN_PROCESS権限を求めるときにアクセス拒否(たとえばSYNCHRONIZEの動作を要求)が表示されます。

サービスコード:

PSECURITY_DESCRIPTOR psd = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); 
InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION); 
SetSecurityDescriptorDacl(psd, TRUE, NULL, FALSE); 

SECURITY_ATTRIBUTES secAttr= {0}; 
secAttr.nLength = sizeof(secAttr); 
secAttr.bInheritHandle = false; 
secAttr.lpSecurityDescriptor = psd; 

hJobObject = CreateJobObject(&secAttr, SCL_JOBOBJECTNAME); 
LocalFree(psd); 

ユーザセッションコード:

hJobObject = OpenJobObject(JOB_OBJECT_ASSIGN_PROCESS, FALSE, SCL_JOBOBJECTNAME); 
if (hJobObject == NULL) 
{ 
    DWORD wError = GetLastError(); 
    printf("Error: %d\n", wError); // this always pops 5 
    return 1; 
} 

任意のアイデア?テストとして、私はサービス内からユーザセッションプロセスを生成し、サービスコードを介してJobObjectを割り当てようとしましたが、それは働いていました。私は、NULL DACLにもかかわらず、 。

+0

なぜ別のセッションからジョブオブジェクトを開くことができると思われますか?とにかくそれをやる必要があるのはなぜですか? –

+0

他のカーネルオブジェクトをこのように使うことができますが、そうでなければJobObjectsを提案しているドキュメントは見つかりませんでした。たぶんこれを行うより良い方法がありますが、私は、特定のRAM使用量を決して超えないように、同じJobObject内で数日/週の間にユーザーセッション全体で独立して開始されたプロセスを維持する必要があります。ユーザーセッションでJobObjectを作成した場合、最初に '管理された'プロセスが起動する前に開始することはできません。サービスはこれのためのツールのように思えました。別の方法にアプローチする方法はありますか? –

+0

あなたはそれをグローバルネームスペースに作成しましたか?グローバル名前空間のオブジェクトにアクセスするために昇格して実行する必要はありませんか? –

答えて

1

サービスでジョブを作成する場合、このオブジェクトはデフォルトでWinSystemLabelSidラベルSID: S-1-16-16384-システム必須レベルです。 (私はちょうどこれをチェックする)ので、あなたはDaclを設定する必要はありませんが、Saclも設定する必要はありません。たとえば、

ULONG cb = MAX_SID_SIZE; 
    PSID LowLabelSid = (PSID)alloca(MAX_SID_SIZE); 
    if (CreateWellKnownSid(WinLowLabelSid, 0, LowLabelSid, &cb)) 
    { 
     PACL Sacl = (PACL)alloca(cb += sizeof(ACL) + sizeof(ACE_HEADER) + sizeof(ACCESS_MASK)); 
     InitializeAcl(Sacl, cb, ACL_REVISION); 
     if (AddMandatoryAce(Sacl, ACL_REVISION, 0, 0, LowLabelSid)) 
     { 
      SECURITY_DESCRIPTOR sd; 
      InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION); 
      SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE); 
      SetSecurityDescriptorSacl(&sd, TRUE, Sacl, FALSE); 

      SECURITY_ATTRIBUTES sa= { sizeof(sa), &sd, FALSE }; 

      if (HANDLE hJob = CreateJobObject(&sa, L"Global\\{58BFC6DB-BE93-4cdb-919C-4C713ACB5A32}")) 
      { 
       CloseHandle(hJob); 
      } 
     } 
    } 
+0

ありがとう、それは素晴らしい作品です!確かに、SACLはSYSTEMレベルに設定されていました。 –

+0

@LaszloSebo - これはすべてのオブジェクトではないことに興味があります。 'Job'オブジェクトの場合、デフォルトでは' System Mandatory Level'に設定されています。たとえば、 'Event'オブジェクトを作成した場合、それは必須ラベルではありません。 – RbMm

関連する問題