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