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