]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/ip/cifsd/rap.c
socksd: setnetmtpt
[plan9front.git] / sys / src / cmd / ip / cifsd / rap.c
1 #include <u.h>
2 #include <libc.h>
3 #include <auth.h>
4 #include "dat.h"
5 #include "fns.h"
6
7 static void
8 padname(uchar *buf, int len, char *name)
9 {
10         int n;
11         n = strlen(name);
12         if(n >= len)
13                 n = len-1;
14         memset(buf, 0, len);
15         memmove(buf, name, n);
16 }
17
18 static int
19 packshareinfo(Trans *t, int level, char *name, int *pstatus)
20 {
21         Share *share;
22         uchar buf[13];
23
24         if((share = mapshare(name)) == nil){
25                 if(pstatus)
26                         *pstatus = 0x906;       /* NERR_NetNameNotFound */
27                 return 0;
28         }
29         padname(buf, sizeof(buf), share->name);
30         switch(level){
31         case 0:
32                 return pack(t->out.data.b, t->out.data.p, t->out.data.e, "[]",
33                         buf, buf+sizeof(buf));
34         case 1:
35                 return pack(t->out.data.b, t->out.data.p, t->out.data.e, "[]_w@1l{f}",
36                         buf, buf+sizeof(buf), share->stype, smbstrpack8, share->remark);
37         case 2:
38                 return pack(t->out.data.b, t->out.data.p, t->out.data.e, "[]_w@1l__ww@2l__________{f}{f}",
39                         buf, buf+sizeof(buf), share->stype, 100, 1, smbstrpack8, share->remark,
40                         smbnamepack8, share->root);
41         default:
42                 return -1;
43         }
44 }
45
46 void
47 transrap(Trans *t)
48 {
49         char *pd, *dd, *name;
50         int n, code, status, level, rbs;
51         uchar *ip, *ipe, *op, *opb, *ope;
52         uchar buf[16];
53
54         code = 0;
55         name = nil;
56         pd = dd = nil;
57         ip = ipe = t->in.param.e;
58         if(!unpack(t->in.param.b, t->in.param.p, t->in.param.e, "wff[]", &code, 
59                 smbstrunpack8, &pd, smbstrunpack8, &dd, &ip, nil)){
60                 t->respond(t, STATUS_NOT_SUPPORTED);
61                 goto out;
62         }
63
64         ope = t->out.param.e;
65         opb = op = t->out.param.b+2+2;
66
67         n = status = level = 0;
68         switch(code){
69         case 0x0000:    /* NetShareEnum */
70                 op += pack(opb, op, ope, "ww", 0, 0);
71                 if(!unpack(ip, ip, ipe, "ww", &level, &rbs))
72                         break;
73                 if((n = packshareinfo(t, level, "local", nil)) > 0){
74                         t->out.data.p += n;
75                         pack(opb, opb, ope, "ww", 1, 1);
76                 }
77                 break;
78
79         case 0x0001:    /* NetShareGetInfo */
80                 op += pack(opb, op, ope, "w", 0);
81                 if(!unpack(ip, ip, ipe, "fww", smbstrunpack8, &name, &level, &rbs))
82                         break;
83                 if((n = packshareinfo(t, level, name, &status)) > 0){
84 outlen:
85                         t->out.data.p += n;
86                         pack(opb, opb, ope, "w", n);
87                 }
88                 break;
89
90         case 0x000d:    /* NetServerGetInfo */
91                 op += pack(opb, op, ope, "w", 0);
92                 if(!unpack(ip, ip, ipe, "ww", &level, &rbs))
93                         break;
94                 padname(buf, sizeof(buf), "");
95                 switch(level){
96                 case 0:
97                         if((n = pack(t->out.data.b, t->out.data.p, t->out.data.e, "[]", 
98                                 buf, buf+sizeof(buf))) > 0)
99                                 goto outlen;
100                         break;
101                 case 1:
102                         if((n = pack(t->out.data.b, t->out.data.p, t->out.data.e, "[]bbl@1l{f}", 
103                                 buf, buf+sizeof(buf), 0x05, 0x00, 2, smbstrpack8, osname)) > 0)
104                                 goto outlen;
105                 default:
106                         n = -1;
107                 }
108                 break;
109
110         case 0x003f:    /* NetWrkstaGetInfo */
111                 op += pack(opb, op, ope, "w", 0);
112                 if(!unpack(ip, ip, ipe, "ww", &level, &rbs))
113                         break;
114                 if(level != 10){
115                         n = -1;
116                         break;
117                 }
118                 if((n = pack(t->out.data.b, t->out.data.p, t->out.data.e, 
119                         "@0l____@1lbb________{f}{f}", 0x05, 0x00, 
120                         smbstrpack8, sysname(), smbstrpack8, domain)) > 0)
121                         goto outlen;
122                 break;
123
124         default:
125                 logit("[%.4x] unknown rap command pd=%s dd=%s", code, pd, dd);
126         }
127         if(n < 0){
128                 logit("[%.4x] unknown rap level [%.4x]", code, level);
129                 status = 0x7C;
130         }
131         if((n = pack(t->out.param.b, t->out.param.p, t->out.param.e, "w__[]", status, opb, op)) == 0){
132                 t->respond(t, STATUS_INVALID_SMB);
133                 goto out;
134         }
135         t->out.param.p += n;
136         t->respond(t, 0);
137
138 out:
139         free(name);
140         free(pd);
141         free(dd);
142         return;
143 }