Skip to content

Instantly share code, notes, and snippets.

@maxymania
Created September 10, 2015 05:03
Show Gist options
  • Save maxymania/c2bd9d34bfd80793838f to your computer and use it in GitHub Desktop.
Save maxymania/c2bd9d34bfd80793838f to your computer and use it in GitHub Desktop.
Get POSIX File ACLs on Linux
/*
* Copyright 2015 Simon Schmidt
*
* Usage of the works is permitted provided that this instrument is
* retained with the works, so that any entity that uses the works
* is notified of this instrument.
* DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/xattr.h>
/* All values are Little Endian */
/* On Big Endian archs, the program needs modifications */
typedef struct{
uint16_t tag;
uint16_t perm;
uint32_t id;
} pacl_ent;
/* pacl_ent.tag values */
/*
const uint16_t PAET_USER_OWNER = 0x0001;
const uint16_t PAET_USER = 0x0002;
const uint16_t PAET_GROUP_OWNER = 0x0004;
const uint16_t PAET_GROUP = 0x0008;
const uint16_t PAET_MASK = 0x0010;
const uint16_t PAET_OTHERS = 0x0020;
*/
#define PAET_USER_OWNER 0x0001
#define PAET_USER 0x0002
#define PAET_GROUP_OWNER 0x0004
#define PAET_GROUP 0x0008
#define PAET_MASK 0x0010
#define PAET_OTHERS 0x0020
typedef struct{
uint32_t ver;
pacl_ent e[0];
} pacl_head;
/* pacl_head.ver = 2 */
const uint32_t NOID = 0xffffffffU;
char permb[10];
char buf[1<<16];
inline char *decodeperm(int perm) {
char *c = permb;
if(perm&4)*(c++)='r';
if(perm&2)*(c++)='w';
if(perm&1)*(c++)='x';
*c = 0;
return permb;
}
int main(int argc,const char **argv){
int i,j=0;
for(i=0;i<(1<<16);++i)buf[i]=0;
if(argc<2)return 1;
int s = lgetxattr(argv[1],"system.posix_acl_access",buf,1<<16);
if(s>(1<<16))s=1<<16;
char *b = buf;
pacl_ent *e = (pacl_ent*)(b+s);
if(0>s)return 1;
pacl_head *ph = (pacl_head*)b;
pacl_ent *pe = ph->e;
if(ph->ver!=2)return 1;
printf("ACL\n");
for(;;pe++){
if(pe>=e)break;
switch(pe->tag) {
case PAET_USER_OWNER:
printf(" usr.OWNER.%s\n",decodeperm(pe->perm)); break;
case PAET_USER:
printf(" usr.%d.%s\n",(int)(pe->id),decodeperm(pe->perm)); break;
case PAET_GROUP_OWNER:
printf(" rol.OWNER.%s\n",decodeperm(pe->perm)); break;
case PAET_GROUP:
printf(" rol.%d.%s\n",(int)(pe->id),decodeperm(pe->perm)); break;
}
//printf("%x; %x; %x\n",(unsigned)(pe->tag),(unsigned)(pe->perm),(unsigned)(pe->id));
}
printf(";;\n");
printf("\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment