xref: /plan9/sys/src/cmd/cifs/fs.c (revision 912e5f5442636b48aaa52937edbb904e279d1987)
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