1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4 #include <fcall.h>
5 #include <thread.h>
6 #include <9p.h>
7 #include "cifs.h"
8
9 static char *period(long sec);
10
11 int
shareinfo(Fmt * f)12 shareinfo(Fmt *f)
13 {
14 int i, j, n;
15 char *type;
16 Shareinfo2 si2;
17 Share *sp, *sip;
18
19 if((n = RAPshareenum(Sess, &Ipc, &sip)) < 1){
20 fmtprint(f, "can't enumerate shares: %r\n");
21 return 0;
22 }
23
24 for(i = 0; i < n; i++){
25 fmtprint(f, "%-13q ", sip[i].name);
26
27 sp = &sip[i];
28 for(j = 0; j < Nshares; j++)
29 if(strcmp(Shares[j].name, sip[i].name) == 0){
30 sp = &Shares[j];
31 break;
32 }
33 if(j >= Nshares)
34 sp->tid = Ipc.tid;
35
36 if(RAPshareinfo(Sess, sp, sp->name, &si2) != -1){
37 switch(si2.type){
38 case STYPE_DISKTREE: type = "disk"; break;
39 case STYPE_PRINTQ: type = "printq"; break;
40 case STYPE_DEVICE: type = "device"; break;
41 case STYPE_IPC: type = "ipc"; break;
42 case STYPE_SPECIAL: type = "special"; break;
43 case STYPE_TEMP: type = "temp"; break;
44 default: type = "unknown"; break;
45 }
46
47 fmtprint(f, "%-8s %5d/%-5d %s", type,
48 si2.activeusrs, si2.maxusrs, si2.comment);
49 free(si2.name);
50 free(si2.comment);
51 free(si2.path);
52 free(si2.passwd);
53 }
54 fmtprint(f, "\n");
55
56 }
57 free(sip);
58 return 0;
59 }
60
61 int
openfileinfo(Fmt * f)62 openfileinfo(Fmt *f)
63 {
64 int got, i;
65 Fileinfo *fi;
66
67 fi = nil;
68 if((got = RAPFileenum2(Sess, &Ipc, "", "", &fi)) == -1){
69 fmtprint(f, "RAPfileenum: %r\n");
70 return 0;
71 }
72
73 for(i = 0; i < got; i++){
74 fmtprint(f, "%c%c%c %-4d %-24q %q ",
75 (fi[i].perms & 1)? 'r': '-',
76 (fi[i].perms & 2)? 'w': '-',
77 (fi[i].perms & 4)? 'c': '-',
78 fi[i].locks, fi[i].user, fi[i].path);
79 free(fi[i].path);
80 free(fi[i].user);
81 }
82 free(fi);
83 return 0;
84 }
85
86 int
conninfo(Fmt * f)87 conninfo(Fmt *f)
88 {
89 int i;
90 typedef struct {
91 int val;
92 char *name;
93 } Tab;
94 static Tab captab[] = {
95 { 1, "raw-mode" },
96 { 2, "mpx-mode" },
97 { 4, "unicode" },
98 { 8, "large-files" },
99 { 0x10, "NT-smbs" },
100 { 0x20, "rpc-remote-APIs" },
101 { 0x40, "status32" },
102 { 0x80, "l2-oplocks" },
103 { 0x100, "lock-read" },
104 { 0x200, "NT-find" },
105 { 0x1000, "Dfs" },
106 { 0x2000, "info-passthru" },
107 { 0x4000, "large-readx" },
108 { 0x8000, "large-writex" },
109 { 0x800000, "Unix" },
110 { 0x20000000, "bulk-transfer" },
111 { 0x40000000, "compressed" },
112 { 0x80000000, "extended-security" },
113 };
114 static Tab sectab[] = {
115 { 1, "user-auth" },
116 { 2, "challange-response" },
117 { 4, "signing-available" },
118 { 8, "signing-required" },
119 };
120
121 fmtprint(f, "%q %q %q %q %+ldsec %dmtu %s\n",
122 Sess->auth->user, Sess->cname,
123 Sess->auth->windom, Sess->remos,
124 Sess->slip, Sess->mtu, Sess->isguest? "as guest": "");
125
126 fmtprint(f, "caps: ");
127 for(i = 0; i < nelem(captab); i++)
128 if(Sess->caps & captab[i].val)
129 fmtprint(f, "%s ", captab[i].name);
130 fmtprint(f, "\n");
131
132 fmtprint(f, "security: ");
133 for(i = 0; i < nelem(sectab); i++)
134 if(Sess->secmode & sectab[i].val)
135 fmtprint(f, "%s ", sectab[i].name);
136 fmtprint(f, "\n");
137
138 if(Sess->nbt)
139 fmtprint(f, "transport: cifs over netbios\n");
140 else
141 fmtprint(f, "transport: cifs\n");
142 return 0;
143 }
144
145 int
sessioninfo(Fmt * f)146 sessioninfo(Fmt *f)
147 {
148 int got, i;
149 Sessinfo *si;
150
151 si = nil;
152 if((got = RAPsessionenum(Sess, &Ipc, &si)) == -1){
153 fmtprint(f, "RAPsessionenum: %r\n");
154 return 0;
155 }
156
157 for(i = 0; i < got; i++){
158 fmtprint(f, "%-24q %-24q ", si[i].user, si[i].wrkstn);
159 fmtprint(f, "%12s ", period(si[i].sesstime));
160 fmtprint(f, "%12s\n", period(si[i].idletime));
161 free(si[i].wrkstn);
162 free(si[i].user);
163 }
164 free(si);
165 return 0;
166 }
167
168 /*
169 * We request the domain referral for "" which gives the
170 * list of all the trusted domains in the clients forest, and
171 * other trusted forests.
172 *
173 * We then sumbit each of these names in turn which gives the
174 * names of the domain controllers for that domain.
175 *
176 * We get a DNS domain name for each domain controller as well as a
177 * netbios name. I THINK I am correct in saying that a name
178 * containing a dot ('.') must be a DNS name, as the NetBios
179 * name munging cannot encode one. Thus names which contain no
180 * dots must be netbios names.
181 *
182 */
183 static void
dfsredir(Fmt * f,char * path,int depth)184 dfsredir(Fmt *f, char *path, int depth)
185 {
186 Refer *re, retab[128];
187 int n, used, flags;
188
189 n = T2getdfsreferral(Sess, &Ipc, path, &flags, &used, retab, nelem(retab));
190 if(n == -1)
191 return;
192 for(re = retab; re < retab+n; re++){
193 if(strcmp(path, re->path) != 0)
194 dfsredir(f, re->path, depth+1);
195 else
196 fmtprint(f, "%-32q %q\n", re->path, re->addr);
197
198 free(re->addr);
199 free(re->path);
200 }
201 }
202
203 int
dfsrootinfo(Fmt * f)204 dfsrootinfo(Fmt *f)
205 {
206 dfsredir(f, "", 0);
207 return 0;
208 }
209
210
211 int
userinfo(Fmt * f)212 userinfo(Fmt *f)
213 {
214 int got, i;
215 Namelist *nl;
216 Userinfo ui;
217
218 nl = nil;
219 if((got = RAPuserenum2(Sess, &Ipc, &nl)) == -1)
220 if((got = RAPuserenum(Sess, &Ipc, &nl)) == -1){
221 fmtprint(f, "RAPuserenum: %r\n");
222 return 0;
223 }
224
225 for(i = 0; i < got; i++){
226 fmtprint(f, "%-24q ", nl[i].name);
227
228 if(RAPuserinfo(Sess, &Ipc, nl[i].name, &ui) != -1){
229 fmtprint(f, "%-48q %q", ui.fullname, ui.comment);
230 free(ui.user);
231 free(ui.comment);
232 free(ui.fullname);
233 free(ui.user_comment);
234 }
235 free(nl[i].name);
236 fmtprint(f, "\n");
237 }
238 free(nl);
239 return 0;
240 }
241
242 int
groupinfo(Fmt * f)243 groupinfo(Fmt *f)
244 {
245 int got1, got2, i, j;
246 Namelist *grps, *usrs;
247
248 grps = nil;
249 if((got1 = RAPgroupenum(Sess, &Ipc, &grps)) == -1){
250 fmtprint(f, "RAPgroupenum: %r\n");
251 return 0;
252 }
253
254 for(i = 0; i < got1; i++){
255 fmtprint(f, "%q ", grps[i].name);
256 usrs = nil;
257 if((got2 = RAPgroupusers(Sess, &Ipc, grps[i].name, &usrs)) != -1){
258 for(j = 0; j < got2; j++){
259 fmtprint(f, "%q ", usrs[j].name);
260 free(usrs[j].name);
261 }
262 free(usrs);
263 }
264 free(grps[i].name);
265 fmtprint(f, "\n");
266 }
267 free(grps);
268 return 0;
269 }
270
271 static int
nodelist(Fmt * f,int type)272 nodelist(Fmt *f, int type)
273 {
274 int more, got, i, j;
275 Serverinfo *si;
276 static char *types[] = {
277 [0] "workstation",
278 [1] "server",
279 [2] "SQL server",
280 [3] "DC",
281 [4] "backup DC",
282 [5] "time source",
283 [6] "Apple server",
284 [7] "Novell server",
285 [8] "domain member",
286 [9] "printer server",
287 [10] "dial-up server",
288 [11] "Unix",
289 [12] "NT",
290 [13] "WFW",
291 [14] "MFPN (?)",
292 [15] "NT server",
293 [16] "potential browser",
294 [17] "backup browser",
295 [18] "LMB",
296 [19] "DMB",
297 [20] "OSF Unix",
298 [21] "VMS",
299 [22] "Win95",
300 [23] "DFS",
301 [24] "NT cluster",
302 [25] "Terminal server",
303 [26] "[26]",
304 [27] "[27]",
305 [28] "IBM DSS",
306 };
307
308 si = nil;
309 if((got = RAPServerenum2(Sess, &Ipc, Sess->auth->windom, type, &more,
310 &si)) == -1){
311 fmtprint(f, "RAPServerenum2: %r\n");
312 return 0;
313 }
314 if(more)
315 if((got = RAPServerenum3(Sess, &Ipc, Sess->auth->windom, type,
316 got-1, si)) == -1){
317 fmtprint(f, "RAPServerenum3: %r\n");
318 return 0;
319 }
320
321 for(i = 0; i < got; i++){
322 fmtprint(f, "%-16q %-16q ", si[i].name, si[i].comment);
323 if(type != LIST_DOMAINS_ONLY){
324 fmtprint(f, "v%d.%d ", si[i].major, si[i].minor);
325 for(j = 0; j < nelem(types); j++)
326 if(si[i].type & (1 << j) && types[j])
327 fmtprint(f, "%s,", types[j]);
328 }
329 fmtprint(f, "\n");
330 free(si[i].name);
331 free(si[i].comment);
332 }
333 free(si);
334 return 0;
335 }
336
337 int
domaininfo(Fmt * f)338 domaininfo(Fmt *f)
339 {
340 return nodelist(f, LIST_DOMAINS_ONLY);
341 }
342
343 int
workstationinfo(Fmt * f)344 workstationinfo(Fmt *f)
345 {
346 return nodelist(f, ALL_LEARNT_IN_DOMAIN);
347 }
348
349 static char *
period(long sec)350 period(long sec)
351 {
352 int days, hrs, min;
353 static char when[32];
354
355 days = sec / (60L * 60L * 24L);
356 sec -= days * (60L * 60L * 24L);
357 hrs = sec / (60L * 60L);
358 sec -= hrs * (60L * 60L);
359 min = sec / 60L;
360 sec -= min * 60L;
361 if(days)
362 snprint(when, sizeof(when), "%d %d:%d:%ld ", days, hrs, min, sec);
363 else
364 snprint(when, sizeof(when), "%d:%d:%ld ", hrs, min, sec);
365 return when;
366 }
367