David G
David G

Reputation: 5784

ACLs in Mac OS X - lookup GUID

I am investigating ACLs on Mac OS X 10.8 Mountain Lion. I have made some headway with the APIs (the documentation is poor) and can retrieve a list of ACL entries for a given file or directory. What I don not know how to do is to translate the GUID/UUID returned by acl_get_qualifier() into a UID or GID. I am using C++ (C really). Here's some code:

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);
            }
         }
      }
   }

So the question is, what API do I use to map UUIDs onto the corresponding user or group? For groups it's actually quite easy as the trailing bytes of the GUID give the GID, but for users it is not so straightforward.

Upvotes: 1

Views: 484

Answers (1)

David G
David G

Reputation: 5784

OK, after a bit of hunting around I found the answer. It is the mbr_uuid_to_id() function, which is part of the Membership API (/usr/include/membership.h). So the code now becomes

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
   ...
   }

Works like a charm.

Upvotes: 1

Related Questions