2008年10月28日火曜日

Samba 3.2.4のACL設定を解析

source/smbd/posix_acl.cより

create_canon_ace_lists()でACLを設定

ここで、NT4形式のACLをPOSIX形式のACLにマッピングしている様子。

if (nt4_compatible_acls()) {
/*
* The security mask may be UNIX_ACCESS_NONE which should map into
* no permissions (we overload the WRITE_OWNER bit for this) or it
* should be one of the ALL/EXECUTE/READ/WRITE bits. Arrange for this
* to be so. Any other bits override the UNIX_ACCESS_NONE bit.
*/

/*
* Convert GENERIC bits to specific bits.
*/

se_map_generic(&psa->access_mask, &file_generic_mapping);

psa->access_mask &= (UNIX_ACCESS_NONE|FILE_ALL_ACCESS);

if(psa->access_mask != UNIX_ACCESS_NONE)
psa->access_mask &= ~UNIX_ACCESS_NONE;
}

se_map_generic()は後で調査してみよう。

次のこの部分では、Windowsの継承ACLを、PosixのDefault ACLに変換。

/*
* Deal with the fact that NT 4.x re-writes the canonical format
* that we return for default ACLs. If a directory ACE is identical
* to a inherited directory ACE then NT changes the bits so that the
* first ACE is set to OI|IO and the second ACE for this SID is set
* to CI. We need to repair this. JRA.
*/

for(i = 0; i < dacl->num_aces; i++) {
SEC_ACE *psa1 = &dacl->aces[i];

for (j = i + 1; j < dacl->num_aces; j++) {
SEC_ACE *psa2 = &dacl->aces[j];

if (psa1->access_mask != psa2->access_mask)
continue;

if (!sid_equal(&psa1->trustee, &psa2->trustee))
continue;

/*
* Ok - permission bits and SIDs are equal.
* Check if flags were re-written.
*/

if (psa1->flags & SEC_ACE_FLAG_INHERIT_ONLY) {

psa1->flags |= (psa2->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT));
psa2->flags &= ~(SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT);

} else if (psa2->flags & SEC_ACE_FLAG_INHERIT_ONLY) {

psa2->flags |= (psa1->flags & (SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT));
psa1->flags &= ~(SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_OBJECT_INHERIT);

}
}
}


最後に個々のACLを、Posix ACLに変換

1. Everyoneは、Posixのotherに変換。

if( sid_equal(¤t_ace->trustee, &global_sid_World)) {
current_ace->owner_type = WORLD_ACE;
current_ace->unix_ug.world = -1;
current_ace->type = SMB_ACL_OTHER;


2. ファイル所有者は、Posixのownerに設定

} else if (sid_equal(¤t_ace->trustee, &global_sid_Creator_Owner)) {
current_ace->owner_type = UID_ACE;
current_ace->unix_ug.uid = pst->st_uid;
current_ace->type = SMB_ACL_USER_OBJ;


3. ファイル所有グループは、Posixのgroupに設定

} else if (sid_equal(¤t_ace->trustee, &global_sid_Creator_Group)) {
current_ace->owner_type = GID_ACE;
current_ace->unix_ug.gid = pst->st_gid;
current_ace->type = SMB_ACL_GROUP_OBJ;


4. ACLが操作中のユーザーと同じならownerに設定。それ以外なら、拡張ACLとして設定。

} else if (sid_to_uid( ¤t_ace->trustee, ¤t_ace->unix_ug.uid)) {
current_ace->owner_type = UID_ACE;
/* If it's the owning user, this is a user_obj, not
* a user. */
if (current_ace->unix_ug.uid == pst->st_uid) {
current_ace->type = SMB_ACL_USER_OBJ;
} else {
current_ace->type = SMB_ACL_USER;
}


5. ACLが操作中のユーザーのプライマリグループなら、Posixのgroupに設定。それ以外なら、拡張ACLとして設定。

} else if (sid_to_gid( ¤t_ace->trustee, ¤t_ace->unix_ug.gid)) {
current_ace->owner_type = GID_ACE;
/* If it's the primary group, this is a group_obj, not
* a group. */
if (current_ace->unix_ug.gid == pst->st_gid) {
current_ace->type = SMB_ACL_GROUP_OBJ;
} else {
current_ace->type = SMB_ACL_GROUP;
}

こんな感じかな。


0 件のコメント:

コメントを投稿