よろしくお願いいたします。
VisualStudio 2005 pro
Windows Server 2003 SP2
ユーザーアカウントを多数(数百件)作成したいのですが、セキュリティの関係上、作成
アカウントにアクセス権限を詳細に設定しなくてはならない、状況です。
具体的には、Dドライブに、ユーザフォルダFooを作成し
Fooのプロパティ、セキュリティの詳細設定、アクセス許可の
種類 名前 アクセス権
許可 Users(ROOM\Users) 読み取りと実行
許可 Users(ROOM\Users) 読み取り
上記2項目の、アクセス許可を削除したいのですが、この条件に合致するような、
Win32API、またはMFCのクラスライブラリィを教えて頂けないでしょうか。
以上です。
SetNamedSecurityInfo 関数が基本です。
http://msdn.microsoft.com/en-us/library/aa379579.aspx
あとは、この関数に渡す引数を作るために、さらにいくつかの関数が必要になります。
この辺が大変参考になります。
http://eternalwindows.jp/security/accesscontrol/accesscontrol00.html
aetos さんお世話になります。
大変有意義な情報ありがとうございます。
いろいろ調べて、このようなラッパークラスを作成しました、
多様なアクセスコントロールを行う場合、オーバーロードを用いて、下記のように
実装してみましたが、class templateを用いて、EXPLICIT_ACCESS 構造体の数と2番目の
引数に渡す、ユーザ名を任意に可変できるようなものを作りたいのですが、私には力不足
です、どなたか、ご教示願えないでしょうか。
よろしくお願いします。
//SecurityInfo.h
#ifndef SECURITYINFO_H_
#define SECURITYINFO_H_
#pragma once
#include <aclapi.h>
class CSecurityInfo
{
protected:
DWORD ret;
PACL pDACL;
EXPLICIT_ACCESS ea[2];
public:
DWORD SetSecurity(wchar_t* szFilename);
CSecurityInfo(void);
~CSecurityInfo(void);
};
class CSecurityInfo_2 : CSecurityInfo
{
EXPLICIT_ACCESS ea[3];
public:
DWORD SetSecurity(wchar_t* szFilename);
CSecurityInfo_2(void);
~CSecurityInfo_2(void);
};
#endif // #ifndef SECURITYINFO_H_
//SecurityInfo.cpp
#include SecurityInfo.h
//コンストラクタ
CSecurityInfo::CSecurityInfo(void)
{
}
//デストラクタ
CSecurityInfo::~CSecurityInfo(void)
{
LocalFree(pDACL);
}
DWORD CSecurityInfo::SetSecurity(wchar_t* szFilename)
{
//EXPLICIT_ACCESS構造体を初期化
BuildExplicitAccessWithName(
&ea[0],
LAdministrators,
FILE_ALL_ACCESS,
SET_ACCESS,
SUB_CONTAINERS_AND_OBJECTS_INHERIT
);
//EXPLICIT_ACCESS構造体を初期化
BuildExplicitAccessWithName(
&ea[1],
LSYSTEM,
FILE_ALL_ACCESS,
SET_ACCESS,
SUB_CONTAINERS_AND_OBJECTS_INHERIT
);
//アクセス制御リスト作成
ret = SetEntriesInAcl(
2,
&ea[0],
NULL,
&pDACL
);
if (ret != ERROR_SUCCESS) {
return ret;
}
//セキュリティ情報を設定
ret = SetNamedSecurityInfo(
szFilename,
SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
NULL,
NULL,
pDACL,
NULL
);
return ret;
}
DWORD CSecurityInfo_2::SetSecurity(wchar_t* szFilename)
{
BuildExplicitAccessWithName(
&ea[0],
LAdministrators,
FILE_ALL_ACCESS,
SET_ACCESS,
SUB_CONTAINERS_AND_OBJECTS_INHERIT
);
BuildExplicitAccessWithName(
&ea[1],
LSYSTEM,
FILE_ALL_ACCESS,
SET_ACCESS,
SUB_CONTAINERS_AND_OBJECTS_INHERIT
);
BuildExplicitAccessWithName(
&ea[2],
LUSERS,
FILE_ALL_ACCESS,
SET_ACCESS,
SUB_CONTAINERS_AND_OBJECTS_INHERIT
);
ret = SetEntriesInAcl(
3,
&ea[0],
NULL,
&pDACL
);
if (ret != ERROR_SUCCESS) {
return ret;
}
ret = SetNamedSecurityInfo(
szFilename,
SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION | PROTECTED_DACL_SECURITY_INFORMATION,
NULL,
NULL,
pDACL,
NULL
);
return ret;
}
//コンストラクタ
CSecurityInfo_2::CSecurityInfo_2(void)
{
}
//デストラクタ
CSecurityInfo_2::~CSecurityInfo_2(void)
{
}
int main(int argc, char* argv[])
{
CSecurityInfo csi1;
//フォルダ作成
CreateDirectory(LC:\\CreateDirectoryTest1, NULL );
//フォルダにセキュリティ情報を設定
csi1.SetSecurity(LC:\\CreateDirectoryTest1);
CSecurityInfo_2 csi2;
CreateDirectory(LC:\\CreateDirectoryTest2, NULL );
csi2.SetSecurity(LC:\\CreateDirectoryTest2);
return 0;
}
メンバ変数に持つ配列の要素数なら、テンプレート引数として int 型のを取れば可能で
しょう。
template< int count > class CSecurityInfo { ... };
ユーザ名は SetSecurity 関数の引数に配列で渡せばよいのではないでしょうか。
また、EXPLICIT_ACCESS 配列もメンバ変数に持たなければ、テンプレートを使う必要も
ありません。同様に SetSecurity の引数でいけるでしょう。
セキュリティ的なことを考えると、DACL は CreateDirectory の第2引数で指定すべき
です。
あと、各セキュリティ関係関数の引数が正しいかどうかは詳しく見ていません。
忘れてた。
1つの CSecurityInfo で複数回の SetSecurity 関数を呼ぶとメモリリークしますよ
ね。