ref: a70b93a356662355214f5405edda066786f6dd03
dir: /sys/src/cmd/cifs/transnt.c/
#include <u.h> #include <libc.h> #include <fcall.h> #include <thread.h> #include <9p.h> #include "cifs.h" static Pkt * tnthdr(Session *s, Share *sp, int cmd) { Pkt *p; p = cifshdr(s, sp, SMB_COM_NT_TRANSACT); p->tbase = p8(p, 0); /* 0 Max setup count to return */ pl16(p, 0); /* 1 reserved */ pl32(p, 0); /* 3 Total parameter count */ pl32(p, 0); /* 7 Total data count */ pl32(p, 64); /* 11 Max parameter count to return */ pl32(p, (MTU - T2HDRLEN)-64); /* 15 Max data count to return */ pl32(p, 0); /* 19 Parameter count (in this buffer) */ pl32(p, 0); /* 23 Offset to parameters (in this buffer) */ pl32(p, 0); /* 27 Count of data in this buffer */ pl32(p, 0); /* 31 Offset to data in this buffer */ p8(p, 1); /* 35 Count of setup words */ pl16(p, cmd); /* 37 setup[0] */ pl16(p, 0); /* padding ??!?!? */ pbytes(p); return p; } static void ptntparam(Pkt *p) { uchar *pos = p->pos; assert(p->tbase != 0); p->pos = p->tbase +23; pl32(p, (pos - p->buf) - NBHDRLEN); /* param offset */ p->tparam = p->pos = pos; } static void ptntdata(Pkt *p) { uchar *pos = p->pos; assert(p->tbase != 0); assert(p->tparam != 0); p->pos = p->tbase +3; pl32(p, pos - p->tparam); /* total param count */ p->pos = p->tbase +19; pl32(p, pos - p->tparam); /* param count */ p->pos = p->tbase +31; pl32(p, (pos - p->buf) - NBHDRLEN); /* data offset */ p->tdata = p->pos = pos; } static int tntrpc(Pkt *p) { int got; uchar *pos; assert(p->tbase != 0); assert(p->tdata != 0); pos = p->pos; p->pos = p->tbase +7; pl32(p, pos - p->tdata); /* total data count */ p->pos = p->tbase +27; pl32(p, pos - p->tdata); /* data count */ p->pos = pos; if((got = cifsrpc(p)) == -1) return -1; g8(p); /* Reserved */ g8(p); /* Reserved */ g8(p); /* Reserved */ gl32(p); /* Total parameter count */ gl32(p); /* Total data count */ gl32(p); /* Parameter count in this buffer */ p->tparam = p->buf +NBHDRLEN +gl32(p); /* Parameter offset */ gl32(p); /* Parameter displacement */ gl32(p); /* Data count (this buffer); */ p->tdata = p->buf +NBHDRLEN +gl32(p); /* Data offset */ gl32(p); /* Data displacement */ g8(p); /* Setup count */ gl16(p); /* padding ??? */ return got; } static void gtntparam(Pkt *p) { p->pos = p->tparam; } static void gtntdata(Pkt *p) { p->pos = p->tdata; } int TNTquerysecurity(Session *s, Share *sp, int fh, char **usid, char **gsid) { Pkt *p; uchar *base; Fmt fmt, *f = &fmt; int n, i, off2owner, off2group; p = tnthdr(s, sp, NT_TRANSACT_QUERY_SECURITY_DESC); ptntparam(p); pl16(p, fh); /* File handle */ pl16(p, 0); /* Reserved */ pl32(p, QUERY_OWNER_SECURITY_INFORMATION | QUERY_GROUP_SECURITY_INFORMATION); ptntdata(p); if(tntrpc(p) == -1){ free(p); return -1; } gtntdata(p); base = p->pos; gl16(p); /* revision */ gl16(p); /* type */ off2owner = gl32(p); /* offset to owner */ off2group = gl32(p); /* offset to group */ gl32(p); gl32(p); if(off2owner){ p->pos = base + off2owner; fmtstrinit(f); fmtprint(f, "S-%ud", g8(p)); /* revision */ n = g8(p); /* num auth */ fmtprint(f, "-%llud", gb48(p)); /* authority */ for(i = 0; i < n; i++) fmtprint(f, "-%ud", gl32(p)); /* sub-authorities */ *usid = fmtstrflush(f); } if(off2group){ p->pos = base + off2group; fmtstrinit(f); fmtprint(f, "S-%ud", g8(p)); /* revision */ n = g8(p); /* num auth */ fmtprint(f, "-%llud", gb48(p)); /* authority */ for(i = 0; i < n; i++) fmtprint(f, "-%ud", gl32(p)); /* sub-authorities */ *gsid = fmtstrflush(f); } free(p); return 0; }