blob: 37108f2faaee6011716dd6dfcf9037e433628b29 [file] [log] [blame]
import java.nio.ByteBuffer;
import java.util.*;
import jcifs.smb.*;
import java.io.*;
public class Acl {
public static final String NAME = "system.cifs_acl";
public static final int BUFFER_SIZE = 1024;
public static final int UINT_MAX = 0xFFFF;
/** number of authority fields */
public static final int NUM_AUTHS = 6;
public static final int SIZEOF_CIFS_CTRL_ACL = 8;
private SidLookup lookup;
private String owner;
private String group;
private int revision;
private int osidoffset;
private int gsidoffset;
private int dacloffset;
private List<Ace> aces;
static {
System.loadLibrary("acl");
}
public Acl(String path, SidLookup lookup) throws IOException, SmbException {
this.lookup = lookup;
ByteBuffer buffer = readRaw(path);
revision = extractInt(2, 2, buffer);
osidoffset = extractInt(4, 4, buffer);
gsidoffset = extractInt(8, 4, buffer);
dacloffset = extractInt(16, 4, buffer);
owner = lookup.resolve(extractSid(osidoffset, buffer));
group = lookup.resolve(extractSid(gsidoffset, buffer));
aces = new LinkedList<>();
extractAces(dacloffset, buffer);
}
private native int getxattr(String path, String attributeName, ByteBuffer buffer);
public String getOwner() {
return owner;
}
public String getGroup() {
return group;
}
// TODO: immutability
public List<Ace> getAces() {
return aces;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("OWNER: ").append(owner).append("\n");
sb.append("GROUP: ").append(group).append("\n");
sb.append("ACES:\n");
for (Ace ace : aces) {
sb.append("\t").append(ace.toString()).append("\n");
}
return sb.toString();
}
private ByteBuffer readRaw(String path) {
ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
getxattr(path, NAME, buffer);
return buffer;
}
private int extractInt(int offset, int bytes, ByteBuffer buffer) {
int value = 0;
for (int i = (offset + bytes - 1); i >= offset; i--) {
value |= (buffer.get(i) & 0xff) << ((i - offset) * 8);
}
return value;
}
private long extractLong(int offset, int bytes, ByteBuffer buffer) {
long value = buffer.get(offset + bytes - 1) & 0xff;
value <<= 8 * (bytes - 1);
for (int i = (offset + bytes - 2); i >= offset; i--) {
value |= (buffer.get(i) & 0xff) << ((i - offset) * 8);
}
return value;
}
private String extractSid(int offset, ByteBuffer buffer) {
StringBuilder sb = new StringBuilder("S-");
// revision, bytes: offset
int revision = extractInt(offset, 1, buffer);
sb.append(revision);
// number of subauthorities, bytes: offset+1
int subauth_num = extractInt(offset+1, 1, buffer);
// authorities, bytes: offset+1+1:offset+1+NUM_AUTHS
long id_auth_val = buffer.get(offset + 1 + 6) & 0xff;
id_auth_val += (buffer.get(offset + 1 + 5) & 0xff) << 8;
id_auth_val += (buffer.get(offset + 1 + 4) & 0xff) << 16;
id_auth_val += (buffer.get(offset + 1 + 3) & 0xff) << 24;
id_auth_val += (buffer.get(offset + 1 + 2) & 0xff) << 32;
id_auth_val += (buffer.get(offset + 1 + 1) & 0xff) << 48;
if (id_auth_val <= UINT_MAX) {
sb.append("-" + id_auth_val);
} else {
sb.append("-0x" + Long.toHexString(id_auth_val));
}
// actual subauthorities, bytes: offset+2+NUM_AUTHS+1:subauth_num
long val = 0;
int subauth_array_offset = offset + 1 + NUM_AUTHS + 1;
for (int i = 0; i < subauth_num; i++) {
val = extractLong(subauth_array_offset, 4, buffer);
sb.append("-" + val);
subauth_array_offset += 4;
}
return sb.toString();
}
private void extractAces(int offset, ByteBuffer buffer) throws IOException, SmbException {
int acl_size = extractInt(offset + 2, 2, buffer);
long ace_num = extractLong(offset + 4, 4, buffer);
int ace_offset = offset + SIZEOF_CIFS_CTRL_ACL;
int ace_size = SIZEOF_CIFS_CTRL_ACL;
if (ace_num > 0) {
for (int i = 0; i < ace_num; i++) {
int type = buffer.get(ace_offset);
int flags = buffer.get(ace_offset + 1);
ace_size = extractInt(ace_offset + 2, 2, buffer);
aces.add(new Ace(flags, type, lookup.resolve(extractSid(ace_offset + 8, buffer))));
ace_offset += ace_size;
}
}
}
public static void main(String[] args) throws Exception {
SidLookup lookup = new SidLookup("172.25.51.36", "gsa-connectors", "Administrator", "p@assword123");
Acl acl = new Acl("/mnt/10M-Windows/PDF/site11/0/11005.pdf", lookup);
System.out.println(acl);
}
}