我正在研究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
   ...
   }

奇迹般有效。

07-27 22:03