1*671dfc47SDavid du Colombier #include <u.h>
2*671dfc47SDavid du Colombier #include <libc.h>
3*671dfc47SDavid du Colombier #include <fcall.h>
4*671dfc47SDavid du Colombier #include <thread.h>
5*671dfc47SDavid du Colombier #include <9p.h>
6*671dfc47SDavid du Colombier #include "cifs.h"
7*671dfc47SDavid du Colombier
8*671dfc47SDavid du Colombier static Pkt *
tnthdr(Session * s,Share * sp,int cmd)9*671dfc47SDavid du Colombier tnthdr(Session *s, Share *sp, int cmd)
10*671dfc47SDavid du Colombier {
11*671dfc47SDavid du Colombier Pkt *p;
12*671dfc47SDavid du Colombier
13*671dfc47SDavid du Colombier p = cifshdr(s, sp, SMB_COM_NT_TRANSACT);
14*671dfc47SDavid du Colombier p->tbase = p8(p, 0); /* 0 Max setup count to return */
15*671dfc47SDavid du Colombier pl16(p, 0); /* 1 reserved */
16*671dfc47SDavid du Colombier pl32(p, 0); /* 3 Total parameter count */
17*671dfc47SDavid du Colombier pl32(p, 0); /* 7 Total data count */
18*671dfc47SDavid du Colombier pl32(p, 64); /* 11 Max parameter count to return */
19*671dfc47SDavid du Colombier pl32(p, (MTU - T2HDRLEN)-64); /* 15 Max data count to return */
20*671dfc47SDavid du Colombier pl32(p, 0); /* 19 Parameter count (in this buffer) */
21*671dfc47SDavid du Colombier pl32(p, 0); /* 23 Offset to parameters (in this buffer) */
22*671dfc47SDavid du Colombier pl32(p, 0); /* 27 Count of data in this buffer */
23*671dfc47SDavid du Colombier pl32(p, 0); /* 31 Offset to data in this buffer */
24*671dfc47SDavid du Colombier p8(p, 1); /* 35 Count of setup words */
25*671dfc47SDavid du Colombier pl16(p, cmd); /* 37 setup[0] */
26*671dfc47SDavid du Colombier pl16(p, 0); /* padding ??!?!? */
27*671dfc47SDavid du Colombier pbytes(p);
28*671dfc47SDavid du Colombier return p;
29*671dfc47SDavid du Colombier }
30*671dfc47SDavid du Colombier
31*671dfc47SDavid du Colombier static void
ptntparam(Pkt * p)32*671dfc47SDavid du Colombier ptntparam(Pkt *p)
33*671dfc47SDavid du Colombier {
34*671dfc47SDavid du Colombier uchar *pos = p->pos;
35*671dfc47SDavid du Colombier assert(p->tbase != 0);
36*671dfc47SDavid du Colombier
37*671dfc47SDavid du Colombier p->pos = p->tbase +23;
38*671dfc47SDavid du Colombier pl32(p, (pos - p->buf) - NBHDRLEN); /* param offset */
39*671dfc47SDavid du Colombier
40*671dfc47SDavid du Colombier p->tparam = p->pos = pos;
41*671dfc47SDavid du Colombier }
42*671dfc47SDavid du Colombier
43*671dfc47SDavid du Colombier static void
ptntdata(Pkt * p)44*671dfc47SDavid du Colombier ptntdata(Pkt *p)
45*671dfc47SDavid du Colombier {
46*671dfc47SDavid du Colombier uchar *pos = p->pos;
47*671dfc47SDavid du Colombier assert(p->tbase != 0);
48*671dfc47SDavid du Colombier assert(p->tparam != 0);
49*671dfc47SDavid du Colombier
50*671dfc47SDavid du Colombier p->pos = p->tbase +3;
51*671dfc47SDavid du Colombier pl32(p, pos - p->tparam); /* total param count */
52*671dfc47SDavid du Colombier
53*671dfc47SDavid du Colombier p->pos = p->tbase +19;
54*671dfc47SDavid du Colombier pl32(p, pos - p->tparam); /* param count */
55*671dfc47SDavid du Colombier
56*671dfc47SDavid du Colombier p->pos = p->tbase +31;
57*671dfc47SDavid du Colombier pl32(p, (pos - p->buf) - NBHDRLEN); /* data offset */
58*671dfc47SDavid du Colombier p->tdata = p->pos = pos;
59*671dfc47SDavid du Colombier }
60*671dfc47SDavid du Colombier
61*671dfc47SDavid du Colombier static int
tntrpc(Pkt * p)62*671dfc47SDavid du Colombier tntrpc(Pkt *p)
63*671dfc47SDavid du Colombier {
64*671dfc47SDavid du Colombier int got;
65*671dfc47SDavid du Colombier uchar *pos;
66*671dfc47SDavid du Colombier assert(p->tbase != 0);
67*671dfc47SDavid du Colombier assert(p->tdata != 0);
68*671dfc47SDavid du Colombier
69*671dfc47SDavid du Colombier pos = p->pos;
70*671dfc47SDavid du Colombier
71*671dfc47SDavid du Colombier p->pos = p->tbase +7;
72*671dfc47SDavid du Colombier pl32(p, pos - p->tdata); /* total data count */
73*671dfc47SDavid du Colombier
74*671dfc47SDavid du Colombier p->pos = p->tbase +27;
75*671dfc47SDavid du Colombier pl32(p, pos - p->tdata); /* data count */
76*671dfc47SDavid du Colombier
77*671dfc47SDavid du Colombier p->pos = pos;
78*671dfc47SDavid du Colombier if((got = cifsrpc(p)) == -1)
79*671dfc47SDavid du Colombier return -1;
80*671dfc47SDavid du Colombier
81*671dfc47SDavid du Colombier g8(p); /* Reserved */
82*671dfc47SDavid du Colombier g8(p); /* Reserved */
83*671dfc47SDavid du Colombier g8(p); /* Reserved */
84*671dfc47SDavid du Colombier gl32(p); /* Total parameter count */
85*671dfc47SDavid du Colombier gl32(p); /* Total data count */
86*671dfc47SDavid du Colombier gl32(p); /* Parameter count in this buffer */
87*671dfc47SDavid du Colombier p->tparam = p->buf +NBHDRLEN +gl32(p); /* Parameter offset */
88*671dfc47SDavid du Colombier gl32(p); /* Parameter displacement */
89*671dfc47SDavid du Colombier gl32(p); /* Data count (this buffer); */
90*671dfc47SDavid du Colombier p->tdata = p->buf +NBHDRLEN +gl32(p); /* Data offset */
91*671dfc47SDavid du Colombier gl32(p); /* Data displacement */
92*671dfc47SDavid du Colombier g8(p); /* Setup count */
93*671dfc47SDavid du Colombier gl16(p); /* padding ??? */
94*671dfc47SDavid du Colombier
95*671dfc47SDavid du Colombier return got;
96*671dfc47SDavid du Colombier }
97*671dfc47SDavid du Colombier
98*671dfc47SDavid du Colombier static void
gtntparam(Pkt * p)99*671dfc47SDavid du Colombier gtntparam(Pkt *p)
100*671dfc47SDavid du Colombier {
101*671dfc47SDavid du Colombier p->pos = p->tparam;
102*671dfc47SDavid du Colombier }
103*671dfc47SDavid du Colombier
104*671dfc47SDavid du Colombier static void
gtntdata(Pkt * p)105*671dfc47SDavid du Colombier gtntdata(Pkt *p)
106*671dfc47SDavid du Colombier {
107*671dfc47SDavid du Colombier p->pos = p->tdata;
108*671dfc47SDavid du Colombier }
109*671dfc47SDavid du Colombier
110*671dfc47SDavid du Colombier
111*671dfc47SDavid du Colombier int
TNTquerysecurity(Session * s,Share * sp,int fh,char ** usid,char ** gsid)112*671dfc47SDavid du Colombier TNTquerysecurity(Session *s, Share *sp, int fh, char **usid, char **gsid)
113*671dfc47SDavid du Colombier {
114*671dfc47SDavid du Colombier Pkt *p;
115*671dfc47SDavid du Colombier uchar *base;
116*671dfc47SDavid du Colombier Fmt fmt, *f = &fmt;
117*671dfc47SDavid du Colombier int n, i, off2owner, off2group;
118*671dfc47SDavid du Colombier
119*671dfc47SDavid du Colombier p = tnthdr(s, sp, NT_TRANSACT_QUERY_SECURITY_DESC);
120*671dfc47SDavid du Colombier ptntparam(p);
121*671dfc47SDavid du Colombier
122*671dfc47SDavid du Colombier pl16(p, fh); /* File handle */
123*671dfc47SDavid du Colombier pl16(p, 0); /* Reserved */
124*671dfc47SDavid du Colombier pl32(p, QUERY_OWNER_SECURITY_INFORMATION |
125*671dfc47SDavid du Colombier QUERY_GROUP_SECURITY_INFORMATION);
126*671dfc47SDavid du Colombier
127*671dfc47SDavid du Colombier ptntdata(p);
128*671dfc47SDavid du Colombier
129*671dfc47SDavid du Colombier if(tntrpc(p) == -1){
130*671dfc47SDavid du Colombier free(p);
131*671dfc47SDavid du Colombier return -1;
132*671dfc47SDavid du Colombier }
133*671dfc47SDavid du Colombier
134*671dfc47SDavid du Colombier gtntdata(p);
135*671dfc47SDavid du Colombier
136*671dfc47SDavid du Colombier base = p->pos;
137*671dfc47SDavid du Colombier gl16(p); /* revision */
138*671dfc47SDavid du Colombier gl16(p); /* type */
139*671dfc47SDavid du Colombier off2owner = gl32(p); /* offset to owner */
140*671dfc47SDavid du Colombier off2group = gl32(p); /* offset to group */
141*671dfc47SDavid du Colombier gl32(p);
142*671dfc47SDavid du Colombier gl32(p);
143*671dfc47SDavid du Colombier
144*671dfc47SDavid du Colombier if(off2owner){
145*671dfc47SDavid du Colombier p->pos = base + off2owner;
146*671dfc47SDavid du Colombier fmtstrinit(f);
147*671dfc47SDavid du Colombier fmtprint(f, "S-%ud", g8(p)); /* revision */
148*671dfc47SDavid du Colombier n = g8(p); /* num auth */
149*671dfc47SDavid du Colombier fmtprint(f, "-%llud", gb48(p)); /* authority */
150*671dfc47SDavid du Colombier for(i = 0; i < n; i++)
151*671dfc47SDavid du Colombier fmtprint(f, "-%ud", gl32(p)); /* sub-authorities */
152*671dfc47SDavid du Colombier *usid = fmtstrflush(f);
153*671dfc47SDavid du Colombier }
154*671dfc47SDavid du Colombier
155*671dfc47SDavid du Colombier if(off2group){
156*671dfc47SDavid du Colombier p->pos = base + off2group;
157*671dfc47SDavid du Colombier fmtstrinit(f);
158*671dfc47SDavid du Colombier fmtprint(f, "S-%ud", g8(p)); /* revision */
159*671dfc47SDavid du Colombier n = g8(p); /* num auth */
160*671dfc47SDavid du Colombier fmtprint(f, "-%llud", gb48(p)); /* authority */
161*671dfc47SDavid du Colombier for(i = 0; i < n; i++)
162*671dfc47SDavid du Colombier fmtprint(f, "-%ud", gl32(p)); /* sub-authorities */
163*671dfc47SDavid du Colombier *gsid = fmtstrflush(f);
164*671dfc47SDavid du Colombier }
165*671dfc47SDavid du Colombier free(p);
166*671dfc47SDavid du Colombier return 0;
167*671dfc47SDavid du Colombier }
168