我正在研究Mac OS X 10.8 Mountain Lion上的ACL。我在使用API方面取得了一些进展(文档不多),可以检索给定文件或目录的ACL条目列表。我不知道该怎么做,就是将acl_get_qualifier()
返回的GUID / UUID转换为UID或GID。我正在使用C++(实际上是C)。这是一些代码:
int acleid=ACL_FIRST_ENTRY;
int aclgeres;
// got an ACL in acl, loop on entries ...
if((aclgeres=acl_get_entry(acl,acleid,&ace))==0)
{
int aclgttres;
acl_tag_t tag;
void *aclgq;
acleid=ACL_NEXT_ENTRY;
if((aclgttres=acl_get_tag_type(ace,&tag))<0)
exit(errno);
else
{
switch(tag)
{
case ACL_UNDEFINED_TAG:
{
// error
break;
}
case ACL_EXTENDED_ALLOW:
{
printf(" TAG ALLOW\n");
break;
}
case ACL_EXTENDED_DENY:
{
printf(" TAG DENY\n");
break;
}
}
if(tag!=ACL_UNDEFINED_TAG)
{
if((aclgq=acl_get_qualifier(ace))==NULL)
exit(errno);
else
{
guid_t *guid=static_cast<guid_t*>(aclgq);
/**********************************************/
guid is now a 16-byte buffer containing a semi-
opaque 128-bit UUID entry. This maps into a
user ID or group ID, but I do not know how
/**********************************************/
free(aclgq);
}
}
}
}
所以问题是,我使用什么API将UUID映射到相应的用户或组?对于组来说,实际上很容易,因为GUID的尾随字节给出了GID,但是对于用户而言,并不是那么简单。
最佳答案
好吧,经过一番狩猎,我找到了答案。它是mbr_uuid_to_id()
函数,它是Membership API(/usr/include/membership.h
)的一部分。现在代码变成了
int mbridres,idtype;
id_t ugid;
if((mbridres=mbr_uuid_to_id(static_cast<unsigned char*>(aclgq),&ugid,&idtype))<0)
exit(errno);
if(idtype==ID_TYPE_UID)
{
// do something with UID in ugid
...
}
else // idtype = ID_TYPE_GID
{
// do something with GID in ugid
...
}
奇迹般有效。