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