This source file includes following definitions.
- smb_encode_word
- smb_decode_word
- smb_encode_smb_length
- smb_encode_dialect
- smb_encode_ascii
- smb_encode_vblock
- smb_decode_data
- smb_name_mangle
- utc2local
- local2utc
- date_dos2unix
- date_unix2dos
- smb_len
- smb_bcc
- smb_valid_packet
- smb_verify
- smb_errno
- print_char
- smb_dump_packet
- smb_lock_server
- smb_unlock_server
- smb_request_ok
- smb_retry
- smb_request_ok_unlock
- smb_setup_header
- smb_setup_header_exclusive
- smb_proc_open
- smb_proc_close
- smb_proc_read
- smb_proc_read_raw
- smb_proc_write
- smb_proc_write_raw
- smb_proc_do_create
- smb_proc_create
- smb_proc_mknew
- smb_proc_mv
- smb_proc_mkdir
- smb_proc_rmdir
- smb_proc_unlink
- smb_proc_trunc
- smb_decode_dirent
- smb_proc_readdir_short
- smb_decode_long_dirent
- smb_proc_readdir_long
- smb_proc_readdir
- smb_proc_getattr_core
- smb_proc_getattrE
- smb_proc_getattr
- smb_proc_setattr_core
- smb_proc_setattrE
- smb_proc_setattr
- smb_proc_dskattr
- smb_proc_reconnect
- smb_proc_connect
- smb_proc_disconnect
- smb_printerr
1
2
3
4
5
6
7
8 #include <linux/module.h>
9
10 #include <linux/fs.h>
11 #include <linux/smbno.h>
12 #include <linux/smb_fs.h>
13 #include <linux/types.h>
14 #include <linux/errno.h>
15 #include <linux/malloc.h>
16 #include <linux/stat.h>
17 #include <linux/fcntl.h>
18 #include <asm/segment.h>
19 #include <asm/string.h>
20
21 #define ARCH i386
22 #define SMB_VWV(packet) ((packet) + SMB_HEADER_LEN)
23 #define SMB_CMD(packet) ((packet)[8])
24 #define SMB_WCT(packet) ((packet)[SMB_HEADER_LEN - 1])
25 #define SMB_BCC(packet) smb_bcc(packet)
26 #define SMB_BUF(packet) ((packet) + SMB_HEADER_LEN + SMB_WCT(packet) * 2 + 2)
27
28 #define SMB_DIRINFO_SIZE 43
29 #define SMB_STATUS_SIZE 21
30
31 #define HI_WORD(l) ((word)(l >> 16))
32 #define LO_WORD(l) ((word)(l % 0xFFFF))
33
34 void smb_printerr(int class, int num);
35 static int smb_request_ok(struct smb_server *s, int command, int wct, int bcc);
36
37
38
39
40
41
42
43 static byte *
44 smb_encode_word(byte *p, word data)
45 {
46 #if (ARCH == i386)
47 *((word *)p) = data;
48 #else
49 p[0] = data & 0x00ffU;
50 p[1] = (data & 0xff00U) >> 8;
51 #error "Non-Intel"
52 #endif
53 return &p[2];
54 }
55
56 static byte *
57 smb_decode_word(byte *p, word *data)
58 {
59 #if (ARCH == i386)
60 *data = *(word *)p;
61 #else
62 *data = (word) p[0] | p[1] << 8;
63 #endif
64 return &p[2];
65 }
66
67 byte *
68 smb_encode_smb_length(byte *p, dword len)
69 {
70 p[0] = p[1] = 0;
71 p[2] = (len & 0xFF00) >> 8;
72 p[3] = (len & 0xFF);
73 if (len > 0xFFFF)
74 p[1] |= 0x01;
75 return &p[4];
76 }
77
78 static byte *
79 smb_encode_dialect(byte *p, const byte *name, int len)
80 {
81 *p ++ = 2;
82 strcpy(p, name);
83 return p + len + 1;
84 }
85
86 static byte *
87 smb_encode_ascii(byte *p, const byte *name, int len)
88 {
89 *p ++ = 4;
90 strcpy(p, name);
91 return p + len + 1;
92 }
93
94 static byte *
95 smb_encode_vblock(byte *p, const byte *data, word len, int fs)
96 {
97 *p ++ = 5;
98 p = smb_encode_word(p, len);
99 if (fs)
100 memcpy_fromfs(p, data, len);
101 else
102 memcpy(p, data, len);
103 return p + len;
104 }
105
106 static byte *
107 smb_decode_data(byte *p, byte *data, word *data_len, int fs)
108 {
109 word len;
110
111 if (!(*p == 1 || *p == 5)) {
112 printk("smb_decode_data: Warning! Data block not starting "
113 "with 1 or 5\n");
114 }
115
116 len = WVAL(p, 1);
117 p += 3;
118
119 if (fs)
120 memcpy_tofs(data, p, len);
121 else
122 memcpy(data, p, len);
123
124 *data_len = len;
125
126 return p + len;
127 }
128
129 static byte *
130 smb_name_mangle(byte *p, const byte *name)
131 {
132 int len, pad = 0;
133
134 len = strlen(name);
135
136 if (len < 16)
137 pad = 16 - len;
138
139 *p ++ = 2 * (len + pad);
140
141 while (*name) {
142 *p ++ = (*name >> 4) + 'A';
143 *p ++ = (*name & 0x0F) + 'A';
144 name ++;
145 }
146 while (pad --) {
147 *p ++ = 'C';
148 *p ++ = 'A';
149 }
150 *p++ = '\0';
151
152 return p;
153 }
154
155
156
157
158
159 static int day_n[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 };
160
161
162
163 extern struct timezone sys_tz;
164
165 static int
166 utc2local(int time)
167 {
168 return time - sys_tz.tz_minuteswest*60;
169 }
170
171 static int
172 local2utc(int time)
173 {
174 return time + sys_tz.tz_minuteswest*60;
175 }
176
177
178
179 static int
180 date_dos2unix(unsigned short time,unsigned short date)
181 {
182 int month,year,secs;
183
184 month = ((date >> 5) & 15)-1;
185 year = date >> 9;
186 secs = (time & 31)*2+60*((time >> 5) & 63)+(time >> 11)*3600+86400*
187 ((date & 31)-1+day_n[month]+(year/4)+year*365-((year & 3) == 0 &&
188 month < 2 ? 1 : 0)+3653);
189
190 return local2utc(secs);
191 }
192
193
194
195
196 static void
197 date_unix2dos(int unix_date,unsigned short *time, unsigned short *date)
198 {
199 int day,year,nl_day,month;
200
201 unix_date = utc2local(unix_date);
202 *time = (unix_date % 60)/2+(((unix_date/60) % 60) << 5)+
203 (((unix_date/3600) % 24) << 11);
204 day = unix_date/86400-3652;
205 year = day/365;
206 if ((year+3)/4+365*year > day) year--;
207 day -= (year+3)/4+365*year;
208 if (day == 59 && !(year & 3)) {
209 nl_day = day;
210 month = 2;
211 }
212 else {
213 nl_day = (year & 3) || day <= 59 ? day : day-1;
214 for (month = 0; month < 12; month++)
215 if (day_n[month] > nl_day) break;
216 }
217 *date = nl_day-day_n[month-1]+1+(month << 5)+(year << 9);
218 }
219
220
221
222
223
224
225
226
227
228 dword
229 smb_len(byte *packet)
230 {
231 return ((packet[1] & 0x1) << 16L) | (packet[2] << 8L) | (packet[3]);
232 }
233
234 static word
235 smb_bcc(byte *packet)
236 {
237 int pos = SMB_HEADER_LEN + SMB_WCT(packet) * sizeof(word);
238 #if (ARCH == i386)
239 return *((word *)((byte *)packet + pos));
240 #else
241 return packet[pos] | packet[pos+1] << 8;
242 #endif
243 }
244
245
246
247
248 static int
249 smb_valid_packet(byte *packet)
250 {
251 DDPRINTK("len: %ld, wct: %d, bcc: %d\n",
252 smb_len(packet), SMB_WCT(packet), SMB_BCC(packet));
253 return ( packet[4] == 0xff
254 && packet[5] == 'S'
255 && packet[6] == 'M'
256 && packet[7] == 'B'
257 && (smb_len(packet) + 4 == SMB_HEADER_LEN
258 + SMB_WCT(packet) * 2 + SMB_BCC(packet)));
259 }
260
261
262
263
264 static int
265 smb_verify(byte *packet, int command, int wct, int bcc)
266 {
267 return (SMB_CMD(packet) == command &&
268 SMB_WCT(packet) >= wct &&
269 (bcc == -1 || SMB_BCC(packet) == bcc)) ? 0 : -EIO;
270 }
271
272 static int
273 smb_errno(int errcls, int error)
274 {
275
276 #if DEBUG_SMB > 1
277 if (errcls) {
278 printk("smb_errno: ");
279 smb_printerr(errcls, error);
280 printk("\n");
281 }
282 #endif
283
284 if (errcls == ERRDOS)
285 switch (error) {
286 case ERRbadfunc: return EINVAL;
287 case ERRbadfile: return ENOENT;
288 case ERRbadpath: return ENOENT;
289 case ERRnofids: return EMFILE;
290 case ERRnoaccess: return EACCES;
291 case ERRbadfid: return EBADF;
292 case ERRbadmcb: return EREMOTEIO;
293 case ERRnomem: return ENOMEM;
294 case ERRbadmem: return EFAULT;
295 case ERRbadenv: return EREMOTEIO;
296 case ERRbadformat: return EREMOTEIO;
297 case ERRbadaccess: return EACCES;
298 case ERRbaddata: return E2BIG;
299 case ERRbaddrive: return ENXIO;
300 case ERRremcd: return EREMOTEIO;
301 case ERRdiffdevice: return EXDEV;
302 case ERRnofiles: return 0;
303 case ERRbadshare: return ETXTBSY;
304 case ERRlock: return EDEADLOCK;
305 case ERRfilexists: return EEXIST;
306 case 87: return 0;
307
308
309 case 183: return EEXIST;
310 default: return EIO;
311 }
312 else if (errcls == ERRSRV)
313 switch (error) {
314 case ERRerror: return ENFILE;
315 case ERRbadpw: return EINVAL;
316 case ERRbadtype: return EIO;
317 case ERRaccess: return EACCES;
318 default: return EIO;
319 }
320 else if (errcls == ERRHRD)
321 switch (error) {
322 case ERRnowrite: return EROFS;
323 case ERRbadunit: return ENODEV;
324 case ERRnotready: return EUCLEAN;
325 case ERRbadcmd: return EIO;
326 case ERRdata: return EIO;
327 case ERRbadreq: return ERANGE;
328 case ERRbadshare: return ETXTBSY;
329 case ERRlock: return EDEADLOCK;
330 default: return EIO;
331 }
332 else if (errcls == ERRCMD)
333 return EIO;
334 return 0;
335 }
336
337 #if DEBUG_SMB > 0
338 static char
339 print_char(char c)
340 {
341 if ((c < ' ') || (c > '~'))
342 return '.';
343 return c;
344 }
345
346 static void
347 smb_dump_packet(byte *packet) {
348 int i, j, len;
349 int errcls, error;
350
351 errcls = (int)packet[9];
352 error = (int)(int)(packet[11]|packet[12]<<8);
353
354 printk("smb_len = %d valid = %d \n",
355 len = smb_len(packet), smb_valid_packet(packet));
356 printk("smb_cmd = %d smb_wct = %d smb_bcc = %d\n",
357 packet[8], SMB_WCT(packet), SMB_BCC(packet));
358 printk("smb_rcls = %d smb_err = %d\n", errcls, error);
359
360 if (errcls) {
361 smb_printerr(errcls, error);
362 printk("\n");
363 }
364
365 if (len > 100)
366 len = 100;
367
368 for (i = 0; i < len; i += 10) {
369 printk("%03d:", i);
370 for (j = i; j < i+10; j++)
371 if (j < len)
372 printk("%02x ", packet[j]);
373 else
374 printk(" ");
375 printk(": ");
376 for (j = i; j < i+10; j++)
377 if (j < len)
378 printk("%c", print_char(packet[j]));
379 printk("\n");
380 }
381 }
382 #endif
383
384 static void
385 smb_lock_server(struct smb_server *server)
386 {
387 while (server->lock)
388 sleep_on(&server->wait);
389 server->lock = 1;
390 }
391
392 static void
393 smb_unlock_server(struct smb_server *server)
394 {
395 if (server->lock != 1) {
396 printk("smb_unlock_server: was not locked!\n");
397 }
398
399 server->lock = 0;
400 wake_up(&server->wait);
401 }
402
403
404
405
406
407
408 static int
409 smb_request_ok(struct smb_server *s, int command, int wct, int bcc)
410 {
411 int result = 0;
412 s->rcls = 0;
413 s->err = 0;
414
415 if (smb_request(s) < 0) {
416 DPRINTK("smb_request failed\n");
417 result = -EIO;
418 }
419 else if (smb_valid_packet(s->packet) != 0) {
420 DPRINTK("not a valid packet!\n");
421 result = -EIO;
422 }
423 else if (s->rcls != 0) {
424 result = -smb_errno(s->rcls, s->err);
425 }
426 else if (smb_verify(s->packet, command, wct, bcc) != 0) {
427 DPRINTK("smb_verify failed\n");
428 result = -EIO;
429 }
430
431 return result;
432 }
433
434
435
436
437
438
439
440 static int
441 smb_retry(struct smb_server *server)
442 {
443 if (server->state != CONN_INVALID) {
444 return 0;
445 }
446
447 if (smb_release(server) < 0) {
448 DPRINTK("smb_retry: smb_release failed\n");
449 server->state = CONN_RETRIED;
450 return 0;
451 }
452 if(smb_proc_reconnect(server) < 0) {
453 DPRINTK("smb_proc_reconnect failed\n");
454 server->state = CONN_RETRIED;
455 return 0;
456 }
457
458 server->state = CONN_VALID;
459 return 1;
460 }
461
462 static int
463 smb_request_ok_unlock(struct smb_server *s, int command, int wct, int bcc)
464 {
465 int result = smb_request_ok(s, command, wct, bcc);
466
467 smb_unlock_server(s);
468
469 return result;
470 }
471
472
473
474
475 static byte *
476 smb_setup_header(struct smb_server *server, byte command, word wct, word bcc)
477 {
478 dword xmit_len = SMB_HEADER_LEN + wct * sizeof(word) + bcc + 2;
479 byte *p = server->packet;
480 byte *buf = server->packet;
481
482 p = smb_encode_smb_length(p, xmit_len);
483
484 BSET(p,0,0xff);
485 BSET(p,1,'S');
486 BSET(p,2,'M');
487 BSET(p,3,'B');
488 BSET(p,4,command);
489
490 p += 5;
491 memset(p, '\0', 19);
492 p += 19;
493 p += 8;
494
495 WSET(buf, smb_tid, server->tid);
496 WSET(buf, smb_pid, server->pid);
497 WSET(buf, smb_uid, server->server_uid);
498 WSET(buf, smb_mid, server->mid);
499
500 if (server->protocol > PROTOCOL_CORE) {
501 BSET(buf, smb_flg, 0x8);
502 WSET(buf, smb_flg2, 0x3);
503 }
504
505 *p++ = wct;
506 p += 2*wct;
507 WSET(p, 0, bcc);
508 return p+2;
509 }
510
511
512
513
514
515 static byte *
516 smb_setup_header_exclusive(struct smb_server *server,
517 byte command, word wct, word bcc)
518 {
519 smb_lock_server(server);
520 return smb_setup_header(server, command, wct, bcc);
521 }
522
523
524
525
526
527
528
529
530 int
531 smb_proc_open(struct smb_server *server, const char *pathname, int len,
532 struct smb_dirent *entry)
533 {
534 int error;
535 char* p;
536 char* buf = server->packet;
537 const word o_attr = aSYSTEM | aHIDDEN | aDIR;
538
539 DPRINTK("smb_proc_open: path=%s\n", pathname);
540
541 smb_lock_server(server);
542
543 retry:
544 p = smb_setup_header(server, SMBopen, 2, 2 + len);
545 WSET(buf, smb_vwv0, 0x42);
546 WSET(buf, smb_vwv1, o_attr);
547 smb_encode_ascii(p, pathname, len);
548
549 if ((error = smb_request_ok(server, SMBopen, 7, 0)) != 0) {
550
551 if (smb_retry(server)) {
552 goto retry;
553 }
554
555 if (error != -EACCES) {
556 smb_unlock_server(server);
557 return error;
558 }
559
560 p = smb_setup_header(server, SMBopen, 2, 2 + len);
561 WSET(buf, smb_vwv0, 0x40);
562 WSET(buf, smb_vwv1, o_attr);
563 smb_encode_ascii(p, pathname, len);
564
565 if ((error = smb_request_ok(server, SMBopen, 7, 0)) != 0) {
566 if (smb_retry(server)) {
567 goto retry;
568 }
569 smb_unlock_server(server);
570 return error;
571 }
572 }
573
574
575
576 entry->fileid = WVAL(buf, smb_vwv0);
577 entry->attr = WVAL(buf, smb_vwv1);
578 entry->ctime = entry->atime =
579 entry->mtime = local2utc(DVAL(buf, smb_vwv2));
580 entry->size = DVAL(buf, smb_vwv4);
581 entry->access = WVAL(buf, smb_vwv6);
582
583 smb_unlock_server(server);
584
585 entry->access &= 3;
586 DPRINTK("smb_proc_open: entry->access = %d\n", entry->access);
587 return 0;
588 }
589
590
591
592 int
593 smb_proc_close(struct smb_server *server, struct smb_dirent *finfo)
594 {
595 char *buf = server->packet;
596
597 smb_setup_header_exclusive(server, SMBclose, 3, 0);
598 WSET(buf, smb_vwv0, finfo->fileid);
599 DSET(buf, smb_vwv1, utc2local(finfo->mtime));
600
601 return smb_request_ok_unlock(server, SMBclose, 0, 0);
602 }
603
604
605
606
607
608
609
610 int
611 smb_proc_read(struct smb_server *server, struct smb_dirent *finfo,
612 off_t offset, long count, char *data, int fs)
613 {
614 word returned_count, data_len;
615 char *buf = server->packet;
616 int error;
617
618 smb_setup_header_exclusive(server, SMBread, 5, 0);
619
620 WSET(buf, smb_vwv0, finfo->fileid);
621 WSET(buf, smb_vwv1, count);
622 DSET(buf, smb_vwv2, offset);
623 WSET(buf, smb_vwv4, 0);
624
625 if ((error = smb_request_ok(server, SMBread, 5, -1)) < 0) {
626 smb_unlock_server(server);
627 return error;
628 }
629
630 returned_count = WVAL(buf, smb_vwv0);
631
632 smb_decode_data(SMB_BUF(server->packet), data, &data_len, fs);
633
634 smb_unlock_server(server);
635
636 if (returned_count != data_len) {
637 printk("smb_proc_read: Warning, returned_count != data_len\n");
638 printk("smb_proc_read: ret_c=%d, data_len=%d\n",
639 returned_count, data_len);
640 }
641
642 return data_len;
643 }
644
645
646
647
648 int
649 smb_proc_read_raw(struct smb_server *server, struct smb_dirent *finfo,
650 off_t offset, long count, char *data)
651 {
652 char *buf = server->packet;
653 int result;
654
655 if ((count <= 0) || (count > 65535)) {
656 return -EINVAL;
657 }
658
659 smb_setup_header_exclusive(server, SMBreadbraw, 8, 0);
660
661 WSET(buf, smb_vwv0, finfo->fileid);
662 DSET(buf, smb_vwv1, offset);
663 WSET(buf, smb_vwv3, count);
664 WSET(buf, smb_vwv4, 0);
665 DSET(buf, smb_vwv5, 0);
666
667 result = smb_request_read_raw(server, data, count);
668 smb_unlock_server(server);
669 return result;
670 }
671
672 int
673 smb_proc_write(struct smb_server *server, struct smb_dirent *finfo,
674 off_t offset, int count, const char *data)
675 {
676 int res = 0;
677 char *buf = server->packet;
678 byte *p;
679
680 p = smb_setup_header_exclusive(server, SMBwrite, 5, count + 3);
681 WSET(buf, smb_vwv0, finfo->fileid);
682 WSET(buf, smb_vwv1, count);
683 DSET(buf, smb_vwv2, offset);
684 WSET(buf, smb_vwv4, 0);
685
686 *p++ = 1;
687 WSET(p, 0, count);
688 memcpy_fromfs(p+2, data, count);
689
690 if ((res = smb_request_ok(server, SMBwrite, 1, 0)) >= 0) {
691 res = WVAL(buf, smb_vwv0);
692 }
693
694 smb_unlock_server(server);
695
696 return res;
697 }
698
699
700 int
701 smb_proc_write_raw(struct smb_server *server, struct smb_dirent *finfo,
702 off_t offset, long count, const char *data)
703 {
704 char *buf = server->packet;
705 int result;
706
707 if ((count <= 0) || (count > 65535)) {
708 return -EINVAL;
709 }
710
711 smb_setup_header_exclusive(server, SMBwritebraw, 11, 0);
712
713 WSET(buf, smb_vwv0, finfo->fileid);
714 WSET(buf, smb_vwv1, count);
715 WSET(buf, smb_vwv2, 0);
716 DSET(buf, smb_vwv3, offset);
717 DSET(buf, smb_vwv5, 0);
718 WSET(buf, smb_vwv7, 1);
719 DSET(buf, smb_vwv8, 0);
720 WSET(buf, smb_vwv10, 0);
721 WSET(buf, smb_vwv11, 0);
722
723 result = smb_request_ok(server, SMBwritebraw, 1, 0);
724
725 DPRINTK("smb_proc_write_raw: first request returned %d\n", result);
726
727 if (result < 0) {
728 smb_unlock_server(server);
729 return result;
730 }
731
732 result = smb_request_write_raw(server, data, count);
733
734 DPRINTK("smb_proc_write_raw: raw request returned %d\n", result);
735
736 if (result > 0) {
737
738 if (smb_valid_packet(server->packet) != 0) {
739 DPRINTK("not a valid packet!\n");
740 result = -EIO;
741 } else if (server->rcls != 0) {
742 result = -smb_errno(server->rcls, server->err);
743 } else if (smb_verify(server->packet, SMBwritec,1,0) != 0) {
744 DPRINTK("smb_verify failed\n");
745 result = -EIO;
746 }
747 }
748
749 smb_unlock_server(server);
750 return result;
751 }
752
753
754
755
756 static int
757 smb_proc_do_create(struct smb_server *server, const char *path, int len,
758 struct smb_dirent *entry, word command)
759 {
760 int error;
761 char *p;
762 char *buf = server->packet;
763
764 smb_lock_server(server);
765 retry:
766 p = smb_setup_header(server, command, 3, len + 2);
767 WSET(buf, smb_vwv0, entry->attr);
768 DSET(buf, smb_vwv1, utc2local(entry->ctime));
769 smb_encode_ascii(p, path, len);
770
771 if ((error = smb_request_ok(server, command, 1, 0)) < 0) {
772 if (smb_retry(server)) {
773 goto retry;
774 }
775 smb_unlock_server(server);
776 return error;
777 }
778
779 entry->opened = 1;
780 entry->fileid = WVAL(buf, smb_vwv0);
781 smb_unlock_server(server);
782
783 smb_proc_close(server, entry);
784
785 return 0;
786 }
787
788 int
789 smb_proc_create(struct smb_server *server, const char *path, int len,
790 struct smb_dirent *entry)
791 {
792 return smb_proc_do_create(server, path, len, entry, SMBcreate);
793 }
794
795 int
796 smb_proc_mknew(struct smb_server *server, const char *path, int len,
797 struct smb_dirent *entry)
798 {
799 return smb_proc_do_create(server, path, len, entry, SMBmknew);
800 }
801
802 int
803 smb_proc_mv(struct smb_server *server,
804 const char *opath, const int olen,
805 const char *npath, const int nlen)
806 {
807 char *p;
808 char *buf = server->packet;
809 int result;
810
811 smb_lock_server(server);
812
813 retry:
814 p = smb_setup_header(server, SMBmv, 1, olen + nlen + 4);
815 WSET(buf, smb_vwv0, 0);
816 p = smb_encode_ascii(p, opath, olen);
817 smb_encode_ascii(p, npath, olen);
818
819 if ((result = smb_request_ok(server, SMBmv, 0, 0)) < 0) {
820 if (smb_retry(server)) {
821 goto retry;
822 }
823 }
824 smb_unlock_server(server);
825 return result;
826 }
827
828 int
829 smb_proc_mkdir(struct smb_server *server, const char *path, const int len)
830 {
831 char *p;
832 int result;
833
834 smb_lock_server(server);
835
836 retry:
837 p = smb_setup_header(server, SMBmkdir, 0, 2 + len);
838 smb_encode_ascii(p, path, len);
839
840 if ((result = smb_request_ok(server, SMBmkdir, 0, 0)) < 0) {
841 if (smb_retry(server)) {
842 goto retry;
843 }
844 }
845 smb_unlock_server(server);
846 return result;
847 }
848
849 int
850 smb_proc_rmdir(struct smb_server *server, const char *path, const int len)
851 {
852 char *p;
853 int result;
854
855 smb_lock_server(server);
856
857 retry:
858 p = smb_setup_header(server, SMBrmdir, 0, 2 + len);
859 smb_encode_ascii(p, path, len);
860
861 if ((result = smb_request_ok(server, SMBrmdir, 0, 0)) < 0) {
862 if (smb_retry(server)) {
863 goto retry;
864 }
865 }
866 smb_unlock_server(server);
867 return result;
868 }
869
870 int
871 smb_proc_unlink(struct smb_server *server, const char *path, const int len)
872 {
873 char *p;
874 char *buf = server->packet;
875 int result;
876
877 smb_lock_server(server);
878
879 retry:
880 p = smb_setup_header(server, SMBunlink, 1, 2 + len);
881 WSET(buf, smb_vwv0, 0);
882 smb_encode_ascii(p, path, len);
883
884 if ((result = smb_request_ok(server, SMBunlink, 0, 0)) < 0) {
885 if (smb_retry(server)) {
886 goto retry;
887 }
888 }
889 smb_unlock_server(server);
890 return result;
891 }
892
893 int
894 smb_proc_trunc(struct smb_server *server, word fid, dword length)
895 {
896 char *p;
897 char *buf = server->packet;
898 int result;
899
900 smb_lock_server(server);
901
902 retry:
903 p = smb_setup_header(server, SMBwrite, 5, 3);
904 WSET(buf, smb_vwv0, fid);
905 WSET(buf, smb_vwv1, 0);
906 DSET(buf, smb_vwv2, length);
907 WSET(buf, smb_vwv4, 0);
908 smb_encode_ascii(p, "", 0);
909
910 if ((result = smb_request_ok(server, SMBwrite, 1, 0)) < 0) {
911 if (smb_retry(server)) {
912 goto retry;
913 }
914 }
915 smb_unlock_server(server);
916 return result;
917 }
918
919 static char *
920 smb_decode_dirent(char *p, struct smb_dirent *entry)
921 {
922 p += SMB_STATUS_SIZE;
923 entry->attr = BVAL(p, 0);
924 entry->mtime = entry->atime = entry->ctime =
925 date_dos2unix(WVAL(p, 1), WVAL(p, 3));
926 entry->size = DVAL(p, 5);
927 memcpy(entry->path, p+9, 13);
928 DDPRINTK("smb_decode_dirent: path = %s\n", entry->path);
929 return p + 22;
930 }
931
932
933
934
935
936 static int
937 smb_proc_readdir_short(struct smb_server *server, struct inode *dir, int fpos,
938 int cache_size, struct smb_dirent *entry)
939 {
940 char *p;
941 char *buf;
942 int error;
943 int result;
944 int i;
945 int first, total_count;
946 struct smb_dirent *current_entry;
947 word bcc;
948 word count;
949 char status[SMB_STATUS_SIZE];
950 int entries_asked = (server->max_xmit - 100) / SMB_DIRINFO_SIZE;
951 int dirlen = strlen(SMB_FINFO(dir)->path);
952 char mask[dirlen + 5];
953
954 strcpy(mask, SMB_FINFO(dir)->path);
955 strcat(mask, "\\*.*");
956
957 DPRINTK("SMB call readdir %d @ %d\n", cache_size, fpos);
958 DPRINTK(" mask = %s\n", mask);
959
960 buf = server->packet;
961
962 smb_lock_server(server);
963
964 retry:
965 first = 1;
966 total_count = 0;
967 current_entry = entry;
968
969 while (1) {
970 if (first == 1) {
971 p = smb_setup_header(server, SMBsearch, 2,
972 5 + strlen(mask));
973 WSET(buf, smb_vwv0, entries_asked);
974 WSET(buf, smb_vwv1, aDIR);
975 p = smb_encode_ascii(p, mask, strlen(mask));
976 *p ++ = 5;
977 p = smb_encode_word(p, 0);
978 } else {
979 p = smb_setup_header(server, SMBsearch, 2,
980 5 + SMB_STATUS_SIZE);
981 WSET(buf, smb_vwv0, entries_asked);
982 WSET(buf, smb_vwv1, aDIR);
983 p = smb_encode_ascii(p, "", 0);
984 p = smb_encode_vblock(p, status, SMB_STATUS_SIZE, 0);
985 }
986
987 if ((error = smb_request_ok(server, SMBsearch, 1, -1)) < 0) {
988 if ( (server->rcls == ERRDOS)
989 && (server->err == ERRnofiles)) {
990 result = total_count - fpos;
991 goto unlock_return;
992 }
993 else
994 {
995 if (smb_retry(server)) {
996 goto retry;
997 }
998 result = error;
999 goto unlock_return;
1000 }
1001 }
1002
1003 p = SMB_VWV(server->packet);
1004 p = smb_decode_word(p, &count);
1005 p = smb_decode_word(p, &bcc);
1006
1007 first = 0;
1008
1009 if (count <= 0) {
1010 result = total_count - fpos;
1011 goto unlock_return;
1012 }
1013 if (bcc != count * SMB_DIRINFO_SIZE + 3) {
1014 result = -EIO;
1015 goto unlock_return;
1016 }
1017
1018 p += 3;
1019
1020
1021 memcpy(status,
1022 SMB_BUF(server->packet) + 3 +
1023 (count - 1) * SMB_DIRINFO_SIZE,
1024 SMB_STATUS_SIZE);
1025
1026
1027
1028 for (i = 0; i < count; i ++) {
1029 if (total_count < fpos) {
1030 p += SMB_DIRINFO_SIZE;
1031 DDPRINTK("smb_proc_readdir: skipped entry.\n");
1032 DDPRINTK(" total_count = %d\n"
1033 " i = %d, fpos = %d\n",
1034 total_count, i, fpos);
1035 }
1036 else if (total_count >= fpos + cache_size) {
1037 result = total_count - fpos;
1038 goto unlock_return;
1039 }
1040 else {
1041 p = smb_decode_dirent(p, current_entry);
1042 current_entry->f_pos = total_count;
1043 DDPRINTK("smb_proc_readdir: entry->f_pos = "
1044 "%lu\n", entry->f_pos);
1045 current_entry += 1;
1046 }
1047 total_count += 1;
1048 }
1049 }
1050 unlock_return:
1051 smb_unlock_server(server);
1052 return result;
1053 }
1054
1055
1056
1057
1058
1059
1060 static char *
1061 smb_decode_long_dirent(char *p, struct smb_dirent *finfo, int level)
1062 {
1063 char *result;
1064
1065 if (finfo) {
1066
1067
1068 finfo->ctime = finfo->mtime = finfo->atime = 0;
1069 }
1070
1071 switch (level)
1072 {
1073 case 1:
1074 if (finfo)
1075 {
1076 DPRINTK("received entry\n");
1077 strcpy(finfo->path,p+27);
1078 finfo->len = strlen(finfo->path);
1079 finfo->size = DVAL(p,16);
1080 finfo->attr = BVAL(p,24);
1081
1082 finfo->ctime = date_dos2unix(WVAL(p, 6), WVAL(p, 4));
1083 finfo->atime = date_dos2unix(WVAL(p, 10), WVAL(p, 8));
1084 finfo->mtime = date_dos2unix(WVAL(p, 14), WVAL(p, 12));
1085 }
1086 result = p + 28 + BVAL(p,26);
1087 break;
1088
1089 case 2:
1090 if (finfo)
1091 {
1092 strcpy(finfo->path,p+31);
1093 finfo->len = strlen(finfo->path);
1094 finfo->size = DVAL(p,16);
1095 finfo->attr = BVAL(p,24);
1096 #if 0
1097 finfo->atime = make_unix_date2(p+8);
1098 finfo->mtime = make_unix_date2(p+12);
1099 #endif
1100 }
1101 result = p + 32 + BVAL(p,30);
1102 break;
1103
1104 case 260:
1105 result = p + WVAL(p,0);
1106 if (finfo)
1107 {
1108 int namelen;
1109 p += 4;
1110 p += 4;
1111
1112 p += 8;
1113
1114 p += 8;
1115 p += 8;
1116
1117 p += 8;
1118 finfo->size = DVAL(p,0);
1119 p += 8;
1120 p += 8;
1121 finfo->attr = BVAL(p,0);
1122 p += 4;
1123 namelen = min(DVAL(p,0), SMB_MAXNAMELEN);
1124 p += 4;
1125 p += 4;
1126 p += 2;
1127 p += 24;
1128 strncpy(finfo->path,p,namelen);
1129 finfo->len = namelen;
1130 }
1131 break;
1132
1133 default:
1134 DPRINTK("Unknown long filename format %d\n",level);
1135 result = p + WVAL(p,0);
1136 }
1137 return result;
1138 }
1139
1140 int
1141 smb_proc_readdir_long(struct smb_server *server, struct inode *dir, int fpos,
1142 int cache_size, struct smb_dirent *entry)
1143 {
1144 int max_matches = 512;
1145
1146
1147 int info_level = 1;
1148
1149 char *p;
1150 int i;
1151 int first, total_count;
1152 struct smb_dirent *current_entry;
1153
1154 char *resp_data;
1155 char *resp_param;
1156 int resp_data_len = 0;
1157 int resp_param_len=0;
1158
1159 int attribute = aSYSTEM | aHIDDEN | aDIR;
1160 int result;
1161
1162 int ff_resume_key = 0;
1163 int ff_searchcount=0;
1164 int ff_eos=0;
1165 int ff_lastname=0;
1166 int ff_dir_handle=0;
1167 int loop_count = 0;
1168
1169 int dirlen = strlen(SMB_FINFO(dir)->path);
1170 char mask[dirlen + 5];
1171
1172 strcpy(mask, SMB_FINFO(dir)->path);
1173 strcat(mask, "\\*");
1174
1175 DPRINTK("SMB call lreaddir %d @ %d\n", cache_size, fpos);
1176 DPRINTK(" mask = %s\n", mask);
1177
1178 resp_param = NULL;
1179 resp_data = NULL;
1180
1181 smb_lock_server(server);
1182
1183 retry:
1184
1185 first = 1;
1186 total_count = 0;
1187 current_entry = entry;
1188
1189 while (ff_eos == 0)
1190 {
1191 int masklen = strlen(mask);
1192 unsigned char *outbuf = server->packet;
1193
1194 loop_count += 1;
1195 if (loop_count > 200)
1196 {
1197 printk("smb_proc_readdir_long: "
1198 "Looping in FIND_NEXT??\n");
1199 break;
1200 }
1201
1202 smb_setup_header(server, SMBtrans2, 15,
1203 5 + 12 + masklen + 1);
1204
1205 WSET(outbuf,smb_tpscnt,12 + masklen +1);
1206 WSET(outbuf,smb_tdscnt,0);
1207 WSET(outbuf,smb_mprcnt,10);
1208 WSET(outbuf,smb_mdrcnt,TRANS2_MAX_TRANSFER);
1209 WSET(outbuf,smb_msrcnt,0);
1210 WSET(outbuf,smb_flags,0);
1211 DSET(outbuf,smb_timeout,0);
1212 WSET(outbuf,smb_pscnt,WVAL(outbuf,smb_tpscnt));
1213 WSET(outbuf,smb_psoff,((SMB_BUF(outbuf)+3) - outbuf)-4);
1214 WSET(outbuf,smb_dscnt,0);
1215 WSET(outbuf,smb_dsoff,0);
1216 WSET(outbuf,smb_suwcnt,1);
1217 WSET(outbuf,smb_setup0,
1218 first == 1 ? TRANSACT2_FINDFIRST : TRANSACT2_FINDNEXT);
1219
1220 p = SMB_BUF(outbuf);
1221 *p++=0;
1222 *p++='D'; *p++ = ' ';
1223
1224 if (first != 0)
1225 {
1226 WSET(p,0,attribute);
1227 WSET(p,2,max_matches);
1228 WSET(p,4,8+4+2);
1229
1230 WSET(p,6,info_level);
1231 DSET(p,8,0);
1232 p += 12;
1233 strncpy(p, mask, masklen);
1234 p += masklen;
1235 *p++ = 0; *p++ = 0;
1236 }
1237 else
1238 {
1239 DPRINTK("hand=0x%X resume=%d ff_lastname=%d mask=%s\n",
1240 ff_dir_handle,ff_resume_key,ff_lastname,mask);
1241 WSET(p,0,ff_dir_handle);
1242 WSET(p,2,max_matches);
1243 WSET(p,4,info_level);
1244 DSET(p,6,ff_resume_key);
1245 WSET(p,10,8+4+2);
1246
1247 p += 12;
1248 strncpy(p, mask, masklen);
1249 p += masklen;
1250 *p++ = 0; *p++ = 0;
1251 }
1252
1253 result = smb_trans2_request(server,
1254 &resp_data_len,&resp_param_len,
1255 &resp_data,&resp_param);
1256
1257 if (result < 0) {
1258 if (smb_retry(server)) {
1259 goto retry;
1260 }
1261 DPRINTK("smb_proc_readdir_long: "
1262 "got error from trans2_request\n");
1263 break;
1264 }
1265
1266 if (server->rcls != 0)
1267 {
1268 result = -EIO;
1269 break;
1270 }
1271
1272
1273 p = resp_param;
1274 if (first != 0)
1275 {
1276 ff_dir_handle = WVAL(p,0);
1277 ff_searchcount = WVAL(p,2);
1278 ff_eos = WVAL(p,4);
1279 ff_lastname = WVAL(p,8);
1280 }
1281 else
1282 {
1283 ff_searchcount = WVAL(p,0);
1284 ff_eos = WVAL(p,2);
1285 ff_lastname = WVAL(p,6);
1286 }
1287
1288 if (ff_searchcount == 0)
1289 break;
1290
1291
1292 p = resp_data;
1293
1294
1295 if (ff_lastname > 0)
1296 {
1297 switch(info_level)
1298 {
1299 case 260:
1300 ff_resume_key =0;
1301 strcpy(mask,p+ff_lastname+94);
1302 break;
1303 case 1:
1304 strcpy(mask,p + ff_lastname + 1);
1305 ff_resume_key = 0;
1306 break;
1307 }
1308 }
1309 else
1310 strcpy(mask,"");
1311
1312
1313
1314 for (i = 0; i < ff_searchcount; i ++) {
1315 if (total_count < fpos) {
1316 p = smb_decode_long_dirent(p, NULL,
1317 info_level);
1318 DPRINTK("smb_proc_readdir: skipped entry.\n");
1319 DDPRINTK(" total_count = %d\n"
1320 " i = %d, fpos = %d\n",
1321 total_count, i, fpos);
1322 }
1323 else if (total_count >= fpos + cache_size) {
1324 goto finished;
1325 }
1326 else {
1327 p = smb_decode_long_dirent(p, current_entry,
1328 info_level);
1329 current_entry->f_pos = total_count;
1330 DDPRINTK("smb_proc_readdir: entry->f_pos = "
1331 "%lu\n", entry->f_pos);
1332 current_entry += 1;
1333 }
1334 total_count += 1;
1335 }
1336
1337 if (resp_data != NULL) {
1338 smb_kfree_s(resp_data, 0);
1339 resp_data = NULL;
1340 }
1341 if (resp_param != NULL) {
1342 smb_kfree_s(resp_param, 0);
1343 resp_param = NULL;
1344 }
1345
1346 DPRINTK("received %d entries (eos=%d resume=%d)\n",
1347 ff_searchcount,ff_eos,ff_resume_key);
1348
1349 first = 0;
1350 }
1351
1352 finished:
1353 if (resp_data != NULL) {
1354 smb_kfree_s(resp_data, 0);
1355 resp_data = NULL;
1356 }
1357 if (resp_param != NULL) {
1358 smb_kfree_s(resp_param, 0);
1359 resp_param = NULL;
1360 }
1361
1362 smb_unlock_server(server);
1363
1364 return total_count - fpos;
1365 }
1366
1367 int
1368 smb_proc_readdir(struct smb_server *server, struct inode *dir, int fpos,
1369 int cache_size, struct smb_dirent *entry)
1370 {
1371 if (server->protocol >= PROTOCOL_LANMAN2)
1372 return smb_proc_readdir_long(server, dir, fpos, cache_size,
1373 entry);
1374 else
1375 return smb_proc_readdir_short(server, dir, fpos, cache_size,
1376 entry);
1377 }
1378
1379 static int
1380 smb_proc_getattr_core(struct smb_server *server, const char *path, int len,
1381 struct smb_dirent *entry)
1382 {
1383 int result;
1384 char *p;
1385 char *buf = server->packet;
1386
1387 smb_lock_server(server);
1388
1389 DDPRINTK("smb_proc_getattr: %s\n", path);
1390
1391 retry:
1392 p = smb_setup_header(server, SMBgetatr, 0, 2 + len);
1393 smb_encode_ascii(p, path, len);
1394
1395 if ((result = smb_request_ok(server, SMBgetatr, 10, 0)) < 0) {
1396 if (smb_retry(server)) {
1397 goto retry;
1398 }
1399 smb_unlock_server(server);
1400 return result;
1401 }
1402
1403 entry->attr = WVAL(buf, smb_vwv0);
1404 entry->ctime = entry->atime =
1405 entry->mtime = local2utc(DVAL(buf, smb_vwv1));
1406
1407 entry->size = DVAL(buf, smb_vwv3);
1408 smb_unlock_server(server);
1409 return 0;
1410 }
1411
1412
1413
1414 static int
1415 smb_proc_getattrE(struct smb_server *server, struct smb_dirent *entry)
1416 {
1417 char* buf = server->packet;
1418 int result;
1419
1420 smb_setup_header_exclusive(server, SMBgetattrE, 1, 0);
1421 WSET(buf, smb_vwv0, entry->fileid);
1422
1423 if ((result = smb_request_ok(server, SMBgetattrE, 11, 0)) != 0) {
1424 smb_unlock_server(server);
1425 return result;
1426 }
1427
1428 entry->ctime = date_dos2unix(WVAL(buf, smb_vwv1), WVAL(buf, smb_vwv0));
1429 entry->atime = date_dos2unix(WVAL(buf, smb_vwv3), WVAL(buf, smb_vwv2));
1430 entry->mtime = date_dos2unix(WVAL(buf, smb_vwv5), WVAL(buf, smb_vwv4));
1431 entry->size = DVAL(buf, smb_vwv6);
1432 entry->attr = WVAL(buf, smb_vwv10);
1433
1434 smb_unlock_server(server);
1435 return 0;
1436 }
1437
1438 int
1439 smb_proc_getattr(struct smb_server *server, const char *path, int len,
1440 struct smb_dirent *entry)
1441 {
1442 if (server->protocol >= PROTOCOL_LANMAN1) {
1443
1444 int result = 0;
1445 struct smb_dirent temp_entry;
1446
1447 if ((result=smb_proc_open(server,path,len,
1448 &temp_entry)) < 0) {
1449
1450
1451 return smb_proc_getattr_core(server,path,len,entry);
1452 }
1453
1454 if ((result=smb_proc_getattrE(server, &temp_entry)) >= 0) {
1455 entry->attr = temp_entry.attr;
1456 entry->atime = temp_entry.atime;
1457 entry->mtime = temp_entry.mtime;
1458 entry->ctime = temp_entry.ctime;
1459 entry->size = temp_entry.size;
1460 }
1461
1462 smb_proc_close(server, &temp_entry);
1463 return result;
1464
1465 } else {
1466 return smb_proc_getattr_core(server, path, len, entry);
1467 }
1468 }
1469
1470
1471
1472
1473 static int
1474 smb_proc_setattr_core(struct smb_server *server,
1475 const char *path, int len,
1476 struct smb_dirent *new_finfo)
1477 {
1478 char *p;
1479 char *buf = server->packet;
1480 int result;
1481
1482 smb_lock_server(server);
1483
1484 retry:
1485 p = smb_setup_header(server, SMBsetatr, 8, 4 + len);
1486 WSET(buf, smb_vwv0, new_finfo->attr);
1487 DSET(buf, smb_vwv1, utc2local(new_finfo->mtime));
1488 p = smb_encode_ascii(p, path, len);
1489 p = smb_encode_ascii(p, "", 0);
1490
1491 if ((result = smb_request_ok(server, SMBsetatr, 0, 0)) < 0) {
1492 if (smb_retry(server)) {
1493 goto retry;
1494 }
1495 }
1496 smb_unlock_server(server);
1497 return result;
1498 }
1499
1500
1501
1502 static int
1503 smb_proc_setattrE(struct smb_server *server, word fid,
1504 struct smb_dirent *new_entry)
1505 {
1506 char *buf = server->packet;
1507 word date, time;
1508
1509 smb_setup_header_exclusive(server, SMBsetattrE, 7, 0);
1510
1511 WSET(buf, smb_vwv0, fid);
1512
1513 date_unix2dos(new_entry->ctime, &time, &date);
1514 WSET(buf, smb_vwv1, date);
1515 WSET(buf, smb_vwv2, time);
1516
1517 date_unix2dos(new_entry->atime, &time, &date);
1518 WSET(buf, smb_vwv3, date);
1519 WSET(buf, smb_vwv4, time);
1520
1521 date_unix2dos(new_entry->mtime, &time, &date);
1522 WSET(buf, smb_vwv5, date);
1523 WSET(buf, smb_vwv6, time);
1524
1525 return smb_request_ok_unlock(server, SMBsetattrE, 0, 0);
1526 }
1527
1528
1529
1530 int
1531 smb_proc_setattr(struct smb_server *server, struct inode *inode,
1532 struct smb_dirent *new_finfo)
1533 {
1534 struct smb_dirent *finfo = SMB_FINFO(inode);
1535 int result;
1536
1537 if (server->protocol >= PROTOCOL_LANMAN1) {
1538 if ((result = smb_make_open(inode, O_RDWR)) < 0)
1539 return result;
1540 return smb_proc_setattrE(server, finfo->fileid, new_finfo);
1541 } else {
1542 return smb_proc_setattr_core(server, finfo->path, finfo->len,
1543 new_finfo);
1544 }
1545 }
1546
1547 int
1548 smb_proc_dskattr(struct super_block *super, struct smb_dskattr *attr)
1549 {
1550 int error;
1551 char *p;
1552 struct smb_server *server = &(SMB_SBP(super)->s_server);
1553
1554 smb_lock_server(server);
1555
1556 retry:
1557 smb_setup_header(server, SMBdskattr, 0, 0);
1558
1559 if ((error = smb_request_ok(server, SMBdskattr, 5, 0)) < 0) {
1560 if (smb_retry(server)) {
1561 goto retry;
1562 }
1563 smb_unlock_server(server);
1564 return error;
1565 }
1566
1567 p = SMB_VWV(server->packet);
1568 p = smb_decode_word(p, &attr->total);
1569 p = smb_decode_word(p, &attr->allocblocks);
1570 p = smb_decode_word(p, &attr->blocksize);
1571 p = smb_decode_word(p, &attr->free);
1572 smb_unlock_server(server);
1573 return 0;
1574 }
1575
1576
1577
1578
1579
1580
1581
1582 struct smb_prots {
1583 enum smb_protocol prot;
1584 const char *name;
1585 };
1586
1587
1588
1589
1590
1591
1592 int
1593 smb_proc_reconnect(struct smb_server *server)
1594 {
1595 struct smb_prots prots[] =
1596 { { PROTOCOL_CORE, "PC NETWORK PROGRAM 1.0"},
1597 { PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
1598 #ifdef LANMAN1
1599 { PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
1600 { PROTOCOL_LANMAN1,"LANMAN1.0"},
1601 #endif
1602 #ifdef LANMAN2
1603 { PROTOCOL_LANMAN2,"LM1.2X002"},
1604 #endif
1605 {-1, NULL} };
1606 char dev[] = "A:";
1607 int i, plength;
1608 int max_xmit = 1024;
1609 int given_max_xmit = server->m.max_xmit;
1610 int result;
1611 byte *p;
1612
1613 if ((result = smb_connect(server)) < 0) {
1614 DPRINTK("smb_proc_reconnect: could not smb_connect\n");
1615 goto fail;
1616 }
1617
1618
1619 server->state = CONN_VALID;
1620
1621 if (server->packet != NULL) {
1622 smb_kfree_s(server->packet, server->max_xmit);
1623 }
1624
1625 server->packet = smb_kmalloc(max_xmit, GFP_KERNEL);
1626
1627 if (server->packet == NULL) {
1628 printk("smb_proc_connect: No memory! Bailing out.\n");
1629 result = -ENOMEM;
1630 goto fail;
1631 }
1632
1633 server->max_xmit = max_xmit;
1634
1635
1636
1637
1638 p = server->packet + 4;
1639
1640 p = smb_name_mangle(p, server->m.server_name);
1641 p = smb_name_mangle(p, server->m.client_name);
1642
1643 smb_encode_smb_length(server->packet,
1644 (void *)p - (void *)(server->packet));
1645
1646 server->packet[0] = 0x81;
1647
1648 if (smb_catch_keepalive(server) < 0) {
1649 printk("smb_proc_connect: could not catch_keepalives\n");
1650 }
1651
1652 if ((result = smb_request(server)) < 0) {
1653 printk("smb_proc_connect: Failed to send SESSION REQUEST.\n");
1654 smb_dont_catch_keepalive(server);
1655 goto fail;
1656 }
1657
1658 if (server->packet[0] != 0x82) {
1659 printk("smb_proc_connect: Did not recieve positive response "
1660 "(err = %x)\n",
1661 server->packet[0]);
1662 smb_dont_catch_keepalive(server);
1663 #if DEBUG_SMB > 0
1664 smb_dump_packet(server->packet);
1665 #endif
1666 result = -EIO;
1667 goto fail;
1668 }
1669
1670 DPRINTK("smb_proc_connect: Passed SESSION REQUEST.\n");
1671
1672
1673 memset(server->packet, 0, SMB_HEADER_LEN);
1674
1675 plength = 0;
1676 for (i = 0; prots[i].name != NULL; i++) {
1677 plength += strlen(prots[i].name) + 2;
1678 }
1679
1680 smb_setup_header(server, SMBnegprot, 0, plength);
1681
1682 p = SMB_BUF(server->packet);
1683
1684 for (i = 0; prots[i].name != NULL; i++) {
1685 p = smb_encode_dialect(p,prots[i].name, strlen(prots[i].name));
1686 }
1687
1688 if ((result = smb_request_ok(server, SMBnegprot, 1, -1)) < 0) {
1689 printk("smb_proc_connect: Failure requesting SMBnegprot\n");
1690 smb_dont_catch_keepalive(server);
1691 goto fail;
1692 } else {
1693 DDPRINTK("smb_proc_connect: Request SMBnegprot..");
1694 }
1695
1696 DDPRINTK("Verified!\n");
1697
1698 p = SMB_VWV(server->packet);
1699 p = smb_decode_word(p, (word *)&i);
1700 server->protocol = prots[i].prot;
1701
1702 DPRINTK("smb_proc_connect: Server wants %s protocol.\n",
1703 prots[i].name);
1704
1705 if (server->protocol > PROTOCOL_LANMAN1) {
1706
1707 word passlen = strlen(server->m.password);
1708 word userlen = strlen(server->m.username);
1709
1710 DPRINTK("smb_proc_connect: password = %s\n",
1711 server->m.password);
1712 DPRINTK("smb_proc_connect: usernam = %s\n",
1713 server->m.username);
1714 DPRINTK("smb_proc_connect: blkmode = %d\n",
1715 WVAL(server->packet, smb_vwv5));
1716
1717 server->maxxmt = WVAL(server->packet, smb_vwv2);
1718 server->maxmux = WVAL(server->packet, smb_vwv3);
1719 server->maxvcs = WVAL(server->packet, smb_vwv4);
1720 server->blkmode= WVAL(server->packet, smb_vwv5);
1721 server->sesskey= DVAL(server->packet, smb_vwv6);
1722
1723 smb_setup_header(server, SMBsesssetupX, 10,
1724 2 + userlen + passlen);
1725
1726 WSET(server->packet, smb_vwv0, 0x00ff);
1727 WSET(server->packet, smb_vwv1, 0);
1728 WSET(server->packet, smb_vwv2, given_max_xmit);
1729 WSET(server->packet, smb_vwv3, 2);
1730 WSET(server->packet, smb_vwv4, server->pid);
1731 DSET(server->packet, smb_vwv5, server->sesskey);
1732 WSET(server->packet, smb_vwv7, passlen + 1);
1733 WSET(server->packet, smb_vwv8, 0);
1734 WSET(server->packet, smb_vwv9, 0);
1735
1736 p = SMB_BUF(server->packet);
1737 strcpy(p, server->m.password);
1738 p += passlen + 1;
1739 strcpy(p, server->m.username);
1740
1741 if ((result = smb_request_ok(server,SMBsesssetupX,3,0)) < 0) {
1742 DPRINTK("smb_proc_connect: SMBsessetupX failed\n");
1743 smb_dont_catch_keepalive(server);
1744 goto fail;
1745 }
1746 smb_decode_word(server->packet+32, &(server->server_uid));
1747 }
1748 else
1749
1750 {
1751 server->maxxmt = 0;
1752 server->maxmux = 0;
1753 server->maxvcs = 0;
1754 server->blkmode = 0;
1755 server->sesskey = 0;
1756 }
1757
1758
1759
1760 smb_setup_header(server, SMBtcon, 0,
1761 6 + strlen(server->m.service) +
1762 strlen(server->m.password) + strlen(dev));
1763 p = SMB_BUF(server->packet);
1764 p = smb_encode_ascii(p, server->m.service, strlen(server->m.service));
1765 p = smb_encode_ascii(p,server->m.password, strlen(server->m.password));
1766 p = smb_encode_ascii(p, dev, strlen(dev));
1767
1768 if ((result = smb_request_ok(server, SMBtcon, 2, 0)) < 0) {
1769 DPRINTK("smb_proc_connect: SMBtcon not verified.\n");
1770 smb_dont_catch_keepalive(server);
1771 goto fail;
1772 }
1773
1774 DDPRINTK("OK! Managed to set up SMBtcon!\n");
1775
1776 p = SMB_VWV(server->packet);
1777 p = smb_decode_word(p, &server->max_xmit);
1778
1779 if (server->max_xmit > given_max_xmit)
1780 server->max_xmit = given_max_xmit;
1781
1782 p = smb_decode_word(p, &server->tid);
1783
1784
1785
1786 server->max_xmit += 4;
1787
1788 DPRINTK("max_xmit = %d, tid = %d\n", server->max_xmit, server->tid);
1789
1790
1791 smb_kfree_s(server->packet, max_xmit);
1792
1793 server->packet = smb_kmalloc(server->max_xmit, GFP_KERNEL);
1794 if (server->packet == NULL) {
1795 printk("smb_proc_connect: No memory left in end of "
1796 "connection phase :-(\n");
1797 smb_dont_catch_keepalive(server);
1798 goto fail;
1799 }
1800
1801 DPRINTK("smb_proc_connect: Normal exit\n");
1802 return 0;
1803
1804 fail:
1805 server->state = CONN_INVALID;
1806 return result;
1807 }
1808
1809
1810
1811 int
1812 smb_proc_connect(struct smb_server *server)
1813 {
1814 int result;
1815 smb_lock_server(server);
1816 result = smb_proc_reconnect(server);
1817 if ((result < 0) && (server->packet != NULL)) {
1818 smb_kfree_s(server->packet, server->max_xmit);
1819 server->packet = NULL;
1820 }
1821 smb_unlock_server(server);
1822 return result;
1823 }
1824
1825 int
1826 smb_proc_disconnect(struct smb_server *server)
1827 {
1828 smb_setup_header_exclusive(server, SMBtdis, 0, 0);
1829 return smb_request_ok_unlock(server, SMBtdis, 0, 0);
1830 }
1831
1832
1833
1834
1835 #if DEBUG_SMB > 0
1836
1837 typedef struct {
1838 char *name;
1839 int code;
1840 char *message;
1841 } err_code_struct;
1842
1843
1844 err_code_struct dos_msgs[] = {
1845 { "ERRbadfunc",1,"Invalid function."},
1846 { "ERRbadfile",2,"File not found."},
1847 { "ERRbadpath",3,"Directory invalid."},
1848 { "ERRnofids",4,"No file descriptors available"},
1849 { "ERRnoaccess",5,"Access denied."},
1850 { "ERRbadfid",6,"Invalid file handle."},
1851 { "ERRbadmcb",7,"Memory control blocks destroyed."},
1852 { "ERRnomem",8,"Insufficient server memory to perform the requested function."},
1853 { "ERRbadmem",9,"Invalid memory block address."},
1854 { "ERRbadenv",10,"Invalid environment."},
1855 { "ERRbadformat",11,"Invalid format."},
1856 { "ERRbadaccess",12,"Invalid open mode."},
1857 { "ERRbaddata",13,"Invalid data."},
1858 { "ERR",14,"reserved."},
1859 { "ERRbaddrive",15,"Invalid drive specified."},
1860 { "ERRremcd",16,"A Delete Directory request attempted to remove the server's current directory."},
1861 { "ERRdiffdevice",17,"Not same device."},
1862 { "ERRnofiles",18,"A File Search command can find no more files matching the specified criteria."},
1863 { "ERRbadshare",32,"The sharing mode specified for an Open conflicts with existing FIDs on the file."},
1864 { "ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."},
1865 { "ERRfilexists",80,"The file named in a Create Directory, Make New File or Link request already exists."},
1866 { "ERRbadpipe",230,"Pipe invalid."},
1867 { "ERRpipebusy",231,"All instances of the requested pipe are busy."},
1868 { "ERRpipeclosing",232,"Pipe close in progress."},
1869 { "ERRnotconnected",233,"No process on other end of pipe."},
1870 { "ERRmoredata",234,"There is more data to be returned."},
1871 { NULL,-1,NULL}};
1872
1873
1874 err_code_struct server_msgs[] = {
1875 { "ERRerror",1,"Non-specific error code."},
1876 { "ERRbadpw",2,"Bad password - name/password pair in a Tree Connect or Session Setup are invalid."},
1877 { "ERRbadtype",3,"reserved."},
1878 { "ERRaccess",4,"The requester does not have the necessary access rights within the specified context for the requested function. The context is defined by the TID or the UID."},
1879 { "ERRinvnid",5,"The tree ID (TID) specified in a command was invalid."},
1880 { "ERRinvnetname",6,"Invalid network name in tree connect."},
1881 { "ERRinvdevice",7,"Invalid device - printer request made to non-printer connection or non-printer request made to printer connection."},
1882 { "ERRqfull",49,"Print queue full (files) -- returned by open print file."},
1883 { "ERRqtoobig",50,"Print queue full -- no space."},
1884 { "ERRqeof",51,"EOF on print queue dump."},
1885 { "ERRinvpfid",52,"Invalid print file FID."},
1886 { "ERRsmbcmd",64,"The server did not recognize the command received."},
1887 { "ERRsrverror",65,"The server encountered an internal error, e.g., system file unavailable."},
1888 { "ERRfilespecs",67,"The file handle (FID) and pathname parameters contained an invalid combination of values."},
1889 { "ERRreserved",68,"reserved."},
1890 { "ERRbadpermits",69,"The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute."},
1891 { "ERRreserved",70,"reserved."},
1892 { "ERRsetattrmode",71,"The attribute mode in the Set File Attribute request is invalid."},
1893 { "ERRpaused",81,"Server is paused."},
1894 { "ERRmsgoff",82,"Not receiving messages."},
1895 { "ERRnoroom",83,"No room to buffer message."},
1896 { "ERRrmuns",87,"Too many remote user names."},
1897 { "ERRtimeout",88,"Operation timed out."},
1898 { "ERRnoresource",89,"No resources currently available for request."},
1899 { "ERRtoomanyuids",90,"Too many UIDs active on this session."},
1900 { "ERRbaduid",91,"The UID is not known as a valid ID on this session."},
1901 { "ERRusempx",250,"Temp unable to support Raw, use MPX mode."},
1902 { "ERRusestd",251,"Temp unable to support Raw, use standard read/write."},
1903 { "ERRcontmpx",252,"Continue in MPX mode."},
1904 { "ERRreserved",253,"reserved."},
1905 { "ERRreserved",254,"reserved."},
1906 { "ERRnosupport",0xFFFF,"Function not supported."},
1907 { NULL,-1,NULL}};
1908
1909
1910 err_code_struct hard_msgs[] = {
1911 { "ERRnowrite",19,"Attempt to write on write-protected diskette."},
1912 { "ERRbadunit",20,"Unknown unit."},
1913 { "ERRnotready",21,"Drive not ready."},
1914 { "ERRbadcmd",22,"Unknown command."},
1915 { "ERRdata",23,"Data error (CRC)."},
1916 { "ERRbadreq",24,"Bad request structure length."},
1917 { "ERRseek",25 ,"Seek error."},
1918 { "ERRbadmedia",26,"Unknown media type."},
1919 { "ERRbadsector",27,"Sector not found."},
1920 { "ERRnopaper",28,"Printer out of paper."},
1921 { "ERRwrite",29,"Write fault."},
1922 { "ERRread",30,"Read fault."},
1923 { "ERRgeneral",31,"General failure."},
1924 { "ERRbadshare",32,"A open conflicts with an existing open."},
1925 { "ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."},
1926 { "ERRwrongdisk",34,"The wrong disk was found in a drive."},
1927 { "ERRFCBUnavail",35,"No FCBs are available to process request."},
1928 { "ERRsharebufexc",36,"A sharing buffer has been exceeded."},
1929 { NULL,-1,NULL}
1930 };
1931
1932
1933 struct {
1934 int code;
1935 char *class;
1936 err_code_struct *err_msgs;
1937 } err_classes[] = {
1938 { 0,"SUCCESS",NULL},
1939 { 0x01,"ERRDOS",dos_msgs},
1940 { 0x02,"ERRSRV",server_msgs},
1941 { 0x03,"ERRHRD",hard_msgs},
1942 { 0x04,"ERRXOS",NULL},
1943 { 0xE1,"ERRRMX1",NULL},
1944 { 0xE2,"ERRRMX2",NULL},
1945 { 0xE3,"ERRRMX3",NULL},
1946 { 0xFF,"ERRCMD",NULL},
1947 { -1,NULL,NULL}
1948 };
1949
1950 void
1951 smb_printerr(int class, int num)
1952 {
1953 int i,j;
1954 err_code_struct *err;
1955
1956 for (i=0; err_classes[i].class; i++) {
1957 if (err_classes[i].code != class)
1958 continue;
1959 if (!err_classes[i].err_msgs) {
1960 printk("%s - %d", err_classes[i].class, num);
1961 return;
1962 }
1963
1964 err = err_classes[i].err_msgs;
1965 for (j=0; err[j].name; j++) {
1966 if (num != err[j].code)
1967 continue;
1968 printk("%s - %s (%s)",
1969 err_classes[i].class, err[j].name,
1970 err[j].message);
1971 return;
1972 }
1973 }
1974
1975 printk("Unknown error - (%d,%d)", class, num);
1976 return;
1977 }
1978
1979 #endif
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996