C++で自分が管理者で実行されているか調べる

Windowsではユーザー毎に権限が設定されおり、それによってアプリケーションの行動が制限されます。

例えば管理者権限を持っていないと特定のフォルダにアクセスできなかったり、レジストリの登録ができなかったりなどなど。

 

またWindows Vista以降では、UAC(ユーザーアカウント制御)という仕組みが導入されていて、これが有効になっていると、管理者のユーザーでログインしていても、通常は標準ユーザーと同じ権限でアプリケーションが実行される事になります。

アプリケーションを管理者として行動させるためには、右クリックして「管理者として実行(A)」とかしないといけません。 

 

 

アプリケーションでレジストリを変更したりする場合は、事前に管理者の権限を持っているかを確認したいですよね。C++では以下のようにして権限を確認する事が出来ます。 


アプリケーションが管理者権限を持つか確認する

BOOL IsAdministrator()
{
        SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY;
        PSID                     adminiGroup;
        BOOL                     isMember;

        if ( ! ::AllocateAndInitializeSid( &authority, 2,
                                           SECURITY_BUILTIN_DOMAIN_RID,
                                           DOMAIN_ALIAS_RID_ADMINS,
                                           0, 0, 0, 0, 0, 0, &adminiGroup ) ) return FALSE;
        if ( ! ::CheckTokenMembership( NULL, adminiGroup, &isMember ) ) {
                ::FreeSid( adminiGroup );
                return FALSE;
        }
        ::FreeSid( adminiGroup );
        return isMember;
}

SID(セキュリティ識別子)の作成 (7~10行目)

WindowsNT系のOSではユーザーや所属グループなどはSIDで管理されています。

権限の確認にはSIDが必要なので、まずはAdministratorsグループのSIDを作成します。

 

SIDはAllocateAndInitializeSid関数で作成する事ができます。

作成後は必ずFreeSid関数で解放します。

AdministratorsグループのSIDはOSによって固定の値が定義されているので、以下の引数を使って作成していきます。

 

権限   SECURITY_NT_AUTHORITY

副権限  SECURITY_BUILTIN_DOMAIN_RID

副権限  DOMAIN_ALIAS_RID_ADMINS

 

 

SIDの有効・無効を調べる (11行目)

CheckTokenMembership関数を使うとSIDが有効になっているかどうかを調べる事ができます。

第1引数はアクセストークンのハンドルですが、NULLを指定すると呼び出し側スレッドのトークンが使われます。 


ローカルグループSID

OSによって定義されているSIDは以下のような感じになっています。

SID 表示名 参考

S-1-5-32-544

Administrators

#define SECURITY_NT_AUTHORITY         {0,0,0,0,0,5}
#define SECURITY_BUILTIN_DOMAIN_RID   (0x00000020L)
#define DOMAIN_ALIAS_RID_ADMINS       (0x00000220L)

S-1-5-32-545

Users

#define SECURITY_NT_AUTHORITY         {0,0,0,0,0,5}
#define SECURITY_BUILTIN_DOMAIN_RID   (0x00000020L)
#define DOMAIN_ALIAS_RID_USERS        (0x00000221L)

S-1-5-32-546

Guests

#define SECURITY_NT_AUTHORITY         {0,0,0,0,0,5}
#define SECURITY_BUILTIN_DOMAIN_RID   (0x00000020L)
#define DOMAIN_ALIAS_RID_GUESTS       (0x00000222L)

S-1-5-32-547

#define SECURITY_NT_AUTHORITY         {0,0,0,0,0,5}
#define SECURITY_BUILTIN_DOMAIN_RID   (0x00000020L)
#define DOMAIN_ALIAS_RID_POWER_USERS  (0x00000223L)