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 = 64;
1143
1144
1145
1146 int info_level = 1;
1147
1148 char *p;
1149 int i;
1150 int first, total_count;
1151 struct smb_dirent *current_entry;
1152
1153 char *resp_data;
1154 char *resp_param;
1155 int resp_data_len = 0;
1156 int resp_param_len=0;
1157
1158 int attribute = aSYSTEM | aHIDDEN | aDIR;
1159 int result;
1160
1161 int ff_resume_key = 0;
1162 int ff_searchcount=0;
1163 int ff_eos=0;
1164 int ff_lastname=0;
1165 int ff_dir_handle=0;
1166 int loop_count = 0;
1167
1168 int dirlen = strlen(SMB_FINFO(dir)->path);
1169 char mask[dirlen + 5];
1170
1171 strcpy(mask, SMB_FINFO(dir)->path);
1172 strcat(mask, "\\*");
1173
1174 DPRINTK("SMB call lreaddir %d @ %d\n", cache_size, fpos);
1175 DPRINTK(" mask = %s\n", mask);
1176
1177 resp_param = NULL;
1178 resp_data = NULL;
1179
1180 smb_lock_server(server);
1181
1182 retry:
1183
1184 first = 1;
1185 total_count = 0;
1186 current_entry = entry;
1187
1188 while (ff_eos == 0)
1189 {
1190 int masklen = strlen(mask);
1191 unsigned char *outbuf = server->packet;
1192
1193 loop_count += 1;
1194 if (loop_count > 200)
1195 {
1196 printk("smb_proc_readdir_long: "
1197 "Looping in FIND_NEXT??\n");
1198 break;
1199 }
1200
1201 smb_setup_header(server, SMBtrans2, 15,
1202 5 + 12 + masklen + 1);
1203
1204 WSET(outbuf,smb_tpscnt,12 + masklen +1);
1205 WSET(outbuf,smb_tdscnt,0);
1206 WSET(outbuf,smb_mprcnt,10);
1207 WSET(outbuf,smb_mdrcnt,TRANS2_MAX_TRANSFER);
1208 WSET(outbuf,smb_msrcnt,0);
1209 WSET(outbuf,smb_flags,0);
1210 DSET(outbuf,smb_timeout,0);
1211 WSET(outbuf,smb_pscnt,WVAL(outbuf,smb_tpscnt));
1212 WSET(outbuf,smb_psoff,((SMB_BUF(outbuf)+3) - outbuf)-4);
1213 WSET(outbuf,smb_dscnt,0);
1214 WSET(outbuf,smb_dsoff,0);
1215 WSET(outbuf,smb_suwcnt,1);
1216 WSET(outbuf,smb_setup0,
1217 first == 1 ? TRANSACT2_FINDFIRST : TRANSACT2_FINDNEXT);
1218
1219 p = SMB_BUF(outbuf);
1220 *p++=0;
1221 *p++='D'; *p++ = ' ';
1222
1223 if (first != 0)
1224 {
1225 WSET(p,0,attribute);
1226 WSET(p,2,max_matches);
1227 WSET(p,4,8+4+2);
1228
1229 WSET(p,6,info_level);
1230 DSET(p,8,0);
1231 p += 12;
1232 strncpy(p, mask, masklen);
1233 p += masklen;
1234 *p++ = 0; *p++ = 0;
1235 }
1236 else
1237 {
1238 DPRINTK("hand=0x%X resume=%d ff_lastname=%d mask=%s\n",
1239 ff_dir_handle,ff_resume_key,ff_lastname,mask);
1240 WSET(p,0,ff_dir_handle);
1241 WSET(p,2,max_matches);
1242 WSET(p,4,info_level);
1243 DSET(p,6,ff_resume_key);
1244 WSET(p,10,8+4+2);
1245
1246 p += 12;
1247 strncpy(p, mask, masklen);
1248 p += masklen;
1249 *p++ = 0; *p++ = 0;
1250 }
1251
1252 result = smb_trans2_request(server,
1253 &resp_data_len,&resp_param_len,
1254 &resp_data,&resp_param);
1255
1256 if (result < 0) {
1257 if (smb_retry(server)) {
1258 goto retry;
1259 }
1260 DPRINTK("smb_proc_readdir_long: "
1261 "got error from trans2_request\n");
1262 break;
1263 }
1264
1265 if (server->rcls != 0)
1266 {
1267 result = -EIO;
1268 break;
1269 }
1270
1271
1272 p = resp_param;
1273 if (first != 0)
1274 {
1275 ff_dir_handle = WVAL(p,0);
1276 ff_searchcount = WVAL(p,2);
1277 ff_eos = WVAL(p,4);
1278 ff_lastname = WVAL(p,8);
1279 }
1280 else
1281 {
1282 ff_searchcount = WVAL(p,0);
1283 ff_eos = WVAL(p,2);
1284 ff_lastname = WVAL(p,6);
1285 }
1286
1287 if (ff_searchcount == 0)
1288 break;
1289
1290
1291 p = resp_data;
1292
1293
1294 if (ff_lastname > 0)
1295 {
1296 switch(info_level)
1297 {
1298 case 260:
1299 ff_resume_key =0;
1300 strcpy(mask,p+ff_lastname+94);
1301 break;
1302 case 1:
1303 strcpy(mask,p + ff_lastname + 1);
1304 ff_resume_key = 0;
1305 break;
1306 }
1307 }
1308 else
1309 strcpy(mask,"");
1310
1311
1312
1313 for (i = 0; i < ff_searchcount; i ++) {
1314 if (total_count < fpos) {
1315 p = smb_decode_long_dirent(p, NULL,
1316 info_level);
1317 DPRINTK("smb_proc_readdir: skipped entry.\n");
1318 DDPRINTK(" total_count = %d\n"
1319 " i = %d, fpos = %d\n",
1320 total_count, i, fpos);
1321 }
1322 else if (total_count >= fpos + cache_size) {
1323 goto finished;
1324 }
1325 else {
1326 p = smb_decode_long_dirent(p, current_entry,
1327 info_level);
1328 current_entry->f_pos = total_count;
1329 DDPRINTK("smb_proc_readdir: entry->f_pos = "
1330 "%lu\n", entry->f_pos);
1331 current_entry += 1;
1332 }
1333 total_count += 1;
1334 }
1335
1336 if (resp_data != NULL) {
1337 smb_kfree_s(resp_data, 0);
1338 resp_data = NULL;
1339 }
1340 if (resp_param != NULL) {
1341 smb_kfree_s(resp_param, 0);
1342 resp_param = NULL;
1343 }
1344
1345 DPRINTK("received %d entries (eos=%d resume=%d)\n",
1346 ff_searchcount,ff_eos,ff_resume_key);
1347
1348 first = 0;
1349 }
1350
1351 finished:
1352 if (resp_data != NULL) {
1353 smb_kfree_s(resp_data, 0);
1354 resp_data = NULL;
1355 }
1356 if (resp_param != NULL) {
1357 smb_kfree_s(resp_param, 0);
1358 resp_param = NULL;
1359 }
1360
1361 smb_unlock_server(server);
1362
1363 return total_count - fpos;
1364 }
1365
1366 int
1367 smb_proc_readdir(struct smb_server *server, struct inode *dir, int fpos,
1368 int cache_size, struct smb_dirent *entry)
1369 {
1370 if (server->protocol >= PROTOCOL_LANMAN2)
1371 return smb_proc_readdir_long(server, dir, fpos, cache_size,
1372 entry);
1373 else
1374 return smb_proc_readdir_short(server, dir, fpos, cache_size,
1375 entry);
1376 }
1377
1378 static int
1379 smb_proc_getattr_core(struct smb_server *server, const char *path, int len,
1380 struct smb_dirent *entry)
1381 {
1382 int result;
1383 char *p;
1384 char *buf = server->packet;
1385
1386 smb_lock_server(server);
1387
1388 DDPRINTK("smb_proc_getattr: %s\n", path);
1389
1390 retry:
1391 p = smb_setup_header(server, SMBgetatr, 0, 2 + len);
1392 smb_encode_ascii(p, path, len);
1393
1394 if ((result = smb_request_ok(server, SMBgetatr, 10, 0)) < 0) {
1395 if (smb_retry(server)) {
1396 goto retry;
1397 }
1398 smb_unlock_server(server);
1399 return result;
1400 }
1401
1402 entry->attr = WVAL(buf, smb_vwv0);
1403 entry->ctime = entry->atime =
1404 entry->mtime = local2utc(DVAL(buf, smb_vwv1));
1405
1406 entry->size = DVAL(buf, smb_vwv3);
1407 smb_unlock_server(server);
1408 return 0;
1409 }
1410
1411
1412
1413 static int
1414 smb_proc_getattrE(struct smb_server *server, struct smb_dirent *entry)
1415 {
1416 char* buf = server->packet;
1417 int result;
1418
1419 smb_setup_header_exclusive(server, SMBgetattrE, 1, 0);
1420 WSET(buf, smb_vwv0, entry->fileid);
1421
1422 if ((result = smb_request_ok(server, SMBgetattrE, 11, 0)) != 0) {
1423 smb_unlock_server(server);
1424 return result;
1425 }
1426
1427 entry->ctime = date_dos2unix(WVAL(buf, smb_vwv1), WVAL(buf, smb_vwv0));
1428 entry->atime = date_dos2unix(WVAL(buf, smb_vwv3), WVAL(buf, smb_vwv2));
1429 entry->mtime = date_dos2unix(WVAL(buf, smb_vwv5), WVAL(buf, smb_vwv4));
1430 entry->size = DVAL(buf, smb_vwv6);
1431 entry->attr = WVAL(buf, smb_vwv10);
1432
1433 smb_unlock_server(server);
1434 return 0;
1435 }
1436
1437 int
1438 smb_proc_getattr(struct smb_server *server, const char *path, int len,
1439 struct smb_dirent *entry)
1440 {
1441 if (server->protocol >= PROTOCOL_LANMAN1) {
1442
1443 int result = 0;
1444 struct smb_dirent temp_entry;
1445
1446 if ((result=smb_proc_open(server,path,len,
1447 &temp_entry)) < 0) {
1448
1449
1450 return smb_proc_getattr_core(server,path,len,entry);
1451 }
1452
1453 if ((result=smb_proc_getattrE(server, &temp_entry)) >= 0) {
1454 entry->attr = temp_entry.attr;
1455 entry->atime = temp_entry.atime;
1456 entry->mtime = temp_entry.mtime;
1457 entry->ctime = temp_entry.ctime;
1458 entry->size = temp_entry.size;
1459 }
1460
1461 smb_proc_close(server, &temp_entry);
1462 return result;
1463
1464 } else {
1465 return smb_proc_getattr_core(server, path, len, entry);
1466 }
1467 }
1468
1469
1470
1471
1472 static int
1473 smb_proc_setattr_core(struct smb_server *server,
1474 const char *path, int len,
1475 struct smb_dirent *new_finfo)
1476 {
1477 char *p;
1478 char *buf = server->packet;
1479 int result;
1480
1481 smb_lock_server(server);
1482
1483 retry:
1484 p = smb_setup_header(server, SMBsetatr, 8, 4 + len);
1485 WSET(buf, smb_vwv0, new_finfo->attr);
1486 DSET(buf, smb_vwv1, utc2local(new_finfo->mtime));
1487 p = smb_encode_ascii(p, path, len);
1488 p = smb_encode_ascii(p, "", 0);
1489
1490 if ((result = smb_request_ok(server, SMBsetatr, 0, 0)) < 0) {
1491 if (smb_retry(server)) {
1492 goto retry;
1493 }
1494 }
1495 smb_unlock_server(server);
1496 return result;
1497 }
1498
1499
1500
1501 static int
1502 smb_proc_setattrE(struct smb_server *server, word fid,
1503 struct smb_dirent *new_entry)
1504 {
1505 char *buf = server->packet;
1506 word date, time;
1507
1508 smb_setup_header_exclusive(server, SMBsetattrE, 7, 0);
1509
1510 WSET(buf, smb_vwv0, fid);
1511
1512 date_unix2dos(new_entry->ctime, &time, &date);
1513 WSET(buf, smb_vwv1, date);
1514 WSET(buf, smb_vwv2, time);
1515
1516 date_unix2dos(new_entry->atime, &time, &date);
1517 WSET(buf, smb_vwv3, date);
1518 WSET(buf, smb_vwv4, time);
1519
1520 date_unix2dos(new_entry->mtime, &time, &date);
1521 WSET(buf, smb_vwv5, date);
1522 WSET(buf, smb_vwv6, time);
1523
1524 return smb_request_ok_unlock(server, SMBsetattrE, 0, 0);
1525 }
1526
1527
1528
1529 int
1530 smb_proc_setattr(struct smb_server *server, struct inode *inode,
1531 struct smb_dirent *new_finfo)
1532 {
1533 struct smb_dirent *finfo = SMB_FINFO(inode);
1534 int result;
1535
1536 if (server->protocol >= PROTOCOL_LANMAN1) {
1537 if ((result = smb_make_open(inode, O_RDWR)) < 0)
1538 return result;
1539 return smb_proc_setattrE(server, finfo->fileid, new_finfo);
1540 } else {
1541 return smb_proc_setattr_core(server, finfo->path, finfo->len,
1542 new_finfo);
1543 }
1544 }
1545
1546 int
1547 smb_proc_dskattr(struct super_block *super, struct smb_dskattr *attr)
1548 {
1549 int error;
1550 char *p;
1551 struct smb_server *server = &(SMB_SBP(super)->s_server);
1552
1553 smb_lock_server(server);
1554
1555 retry:
1556 smb_setup_header(server, SMBdskattr, 0, 0);
1557
1558 if ((error = smb_request_ok(server, SMBdskattr, 5, 0)) < 0) {
1559 if (smb_retry(server)) {
1560 goto retry;
1561 }
1562 smb_unlock_server(server);
1563 return error;
1564 }
1565
1566 p = SMB_VWV(server->packet);
1567 p = smb_decode_word(p, &attr->total);
1568 p = smb_decode_word(p, &attr->allocblocks);
1569 p = smb_decode_word(p, &attr->blocksize);
1570 p = smb_decode_word(p, &attr->free);
1571 smb_unlock_server(server);
1572 return 0;
1573 }
1574
1575
1576
1577
1578
1579
1580
1581 struct smb_prots {
1582 enum smb_protocol prot;
1583 const char *name;
1584 };
1585
1586
1587
1588
1589
1590
1591 int
1592 smb_proc_reconnect(struct smb_server *server)
1593 {
1594 struct smb_prots prots[] =
1595 { { PROTOCOL_CORE, "PC NETWORK PROGRAM 1.0"},
1596 { PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
1597 #ifdef LANMAN1
1598 { PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
1599 { PROTOCOL_LANMAN1,"LANMAN1.0"},
1600 #endif
1601 #ifdef LANMAN2
1602 { PROTOCOL_LANMAN2,"LM1.2X002"},
1603 #endif
1604 #ifdef NT1
1605 { PROTOCOL_NT1,"NT LM 0.12"},
1606 { PROTOCOL_NT1,"NT LANMAN 1.0"},
1607 #endif
1608 {-1, NULL} };
1609 char dev[] = "A:";
1610 int i, plength;
1611 int max_xmit = 1024;
1612 int given_max_xmit = server->m.max_xmit;
1613 int result;
1614 byte *p;
1615
1616 if ((result = smb_connect(server)) < 0) {
1617 DPRINTK("smb_proc_reconnect: could not smb_connect\n");
1618 goto fail;
1619 }
1620
1621
1622 server->state = CONN_VALID;
1623
1624 if (server->packet != NULL) {
1625 smb_kfree_s(server->packet, server->max_xmit);
1626 }
1627
1628 server->packet = smb_kmalloc(max_xmit, GFP_KERNEL);
1629
1630 if (server->packet == NULL) {
1631 printk("smb_proc_connect: No memory! Bailing out.\n");
1632 result = -ENOMEM;
1633 goto fail;
1634 }
1635
1636 server->max_xmit = max_xmit;
1637
1638
1639
1640
1641 p = server->packet + 4;
1642
1643 p = smb_name_mangle(p, server->m.server_name);
1644 p = smb_name_mangle(p, server->m.client_name);
1645
1646 smb_encode_smb_length(server->packet,
1647 (void *)p - (void *)(server->packet));
1648
1649 server->packet[0] = 0x81;
1650
1651 if (smb_catch_keepalive(server) < 0) {
1652 printk("smb_proc_connect: could not catch_keepalives\n");
1653 }
1654
1655 if ((result = smb_request(server)) < 0) {
1656 printk("smb_proc_connect: Failed to send SESSION REQUEST.\n");
1657 smb_dont_catch_keepalive(server);
1658 goto fail;
1659 }
1660
1661 if (server->packet[0] != 0x82) {
1662 printk("smb_proc_connect: Did not recieve positive response "
1663 "(err = %x)\n",
1664 server->packet[0]);
1665 smb_dont_catch_keepalive(server);
1666 #if DEBUG_SMB > 0
1667 smb_dump_packet(server->packet);
1668 #endif
1669 result = -EIO;
1670 goto fail;
1671 }
1672
1673 DPRINTK("smb_proc_connect: Passed SESSION REQUEST.\n");
1674
1675
1676 memset(server->packet, 0, SMB_HEADER_LEN);
1677
1678 plength = 0;
1679 for (i = 0; prots[i].name != NULL; i++) {
1680 plength += strlen(prots[i].name) + 2;
1681 }
1682
1683 smb_setup_header(server, SMBnegprot, 0, plength);
1684
1685 p = SMB_BUF(server->packet);
1686
1687 for (i = 0; prots[i].name != NULL; i++) {
1688 p = smb_encode_dialect(p,prots[i].name, strlen(prots[i].name));
1689 }
1690
1691 if ((result = smb_request_ok(server, SMBnegprot, 1, -1)) < 0) {
1692 printk("smb_proc_connect: Failure requesting SMBnegprot\n");
1693 smb_dont_catch_keepalive(server);
1694 goto fail;
1695 } else {
1696 DDPRINTK("smb_proc_connect: Request SMBnegprot..");
1697 }
1698
1699 DDPRINTK("Verified!\n");
1700
1701 p = SMB_VWV(server->packet);
1702 p = smb_decode_word(p, (word *)&i);
1703 server->protocol = prots[i].prot;
1704
1705 DPRINTK("smb_proc_connect: Server wants %s protocol.\n",
1706 prots[i].name);
1707
1708 if (server->protocol > PROTOCOL_LANMAN1) {
1709
1710 word passlen = strlen(server->m.password);
1711 word userlen = strlen(server->m.username);
1712
1713 DPRINTK("smb_proc_connect: password = %s\n",
1714 server->m.password);
1715 DPRINTK("smb_proc_connect: usernam = %s\n",
1716 server->m.username);
1717 DPRINTK("smb_proc_connect: blkmode = %d\n",
1718 WVAL(server->packet, smb_vwv5));
1719
1720 if (server->protocol >= PROTOCOL_NT1) {
1721 server->maxxmt = DVAL(server->packet,smb_vwv3+1);
1722 server->maxmux = WVAL(server->packet, smb_vwv1+1);
1723 server->maxvcs = WVAL(server->packet, smb_vwv2+1);
1724 server->blkmode= DVAL(server->packet, smb_vwv9+1);
1725 server->sesskey= DVAL(server->packet, smb_vwv7+1);
1726 } else {
1727 server->maxxmt = WVAL(server->packet, smb_vwv2);
1728 server->maxmux = WVAL(server->packet, smb_vwv3);
1729 server->maxvcs = WVAL(server->packet, smb_vwv4);
1730 server->blkmode= WVAL(server->packet, smb_vwv5);
1731 server->sesskey= DVAL(server->packet, smb_vwv6);
1732 }
1733
1734
1735 if (server->protocol >= PROTOCOL_NT1) {
1736 char *workgroup = "WORKGROUP";
1737 char *OS_id = "Unix";
1738 char *client_id = "ksmbfs";
1739
1740 smb_setup_header(server, SMBsesssetupX, 13,
1741 5 + userlen + passlen +
1742 strlen(workgroup) + strlen(OS_id) +
1743 strlen(client_id));
1744
1745 WSET(server->packet, smb_vwv0, 0x00ff);
1746 WSET(server->packet, smb_vwv1, 0);
1747 WSET(server->packet, smb_vwv2, given_max_xmit);
1748 WSET(server->packet, smb_vwv3, 2);
1749 WSET(server->packet, smb_vwv4, server->pid);
1750 DSET(server->packet, smb_vwv5, server->sesskey);
1751 WSET(server->packet, smb_vwv7, passlen + 1);
1752 WSET(server->packet, smb_vwv8, 0);
1753 WSET(server->packet, smb_vwv9, 0);
1754
1755 p = SMB_BUF(server->packet);
1756 strcpy(p, server->m.password);
1757 p += passlen + 1;
1758 strcpy(p, server->m.username);
1759 p += userlen + 1;
1760 strcpy(p, workgroup);
1761 p += strlen(p) + 1;
1762 strcpy(p, OS_id);
1763 p += strlen(p) + 1;
1764 strcpy(p, client_id);
1765 } else {
1766 smb_setup_header(server, SMBsesssetupX, 10,
1767 2 + userlen + passlen);
1768
1769 WSET(server->packet, smb_vwv0, 0x00ff);
1770 WSET(server->packet, smb_vwv1, 0);
1771 WSET(server->packet, smb_vwv2, given_max_xmit);
1772 WSET(server->packet, smb_vwv3, 2);
1773 WSET(server->packet, smb_vwv4, server->pid);
1774 DSET(server->packet, smb_vwv5, server->sesskey);
1775 WSET(server->packet, smb_vwv7, passlen + 1);
1776 WSET(server->packet, smb_vwv8, 0);
1777 WSET(server->packet, smb_vwv9, 0);
1778
1779 p = SMB_BUF(server->packet);
1780 strcpy(p, server->m.password);
1781 p += passlen + 1;
1782 strcpy(p, server->m.username);
1783 }
1784
1785 if ((result = smb_request_ok(server,SMBsesssetupX,3,0)) < 0) {
1786 DPRINTK("smb_proc_connect: SMBsessetupX failed\n");
1787 smb_dont_catch_keepalive(server);
1788 goto fail;
1789 }
1790 smb_decode_word(server->packet+32, &(server->server_uid));
1791 }
1792 else
1793
1794 {
1795 server->maxxmt = 0;
1796 server->maxmux = 0;
1797 server->maxvcs = 0;
1798 server->blkmode = 0;
1799 server->sesskey = 0;
1800 }
1801
1802
1803
1804 smb_setup_header(server, SMBtcon, 0,
1805 6 + strlen(server->m.service) +
1806 strlen(server->m.password) + strlen(dev));
1807 p = SMB_BUF(server->packet);
1808 p = smb_encode_ascii(p, server->m.service, strlen(server->m.service));
1809 p = smb_encode_ascii(p,server->m.password, strlen(server->m.password));
1810 p = smb_encode_ascii(p, dev, strlen(dev));
1811
1812 if ((result = smb_request_ok(server, SMBtcon, 2, 0)) < 0) {
1813 DPRINTK("smb_proc_connect: SMBtcon not verified.\n");
1814 smb_dont_catch_keepalive(server);
1815 goto fail;
1816 }
1817
1818 DDPRINTK("OK! Managed to set up SMBtcon!\n");
1819
1820 p = SMB_VWV(server->packet);
1821 p = smb_decode_word(p, &server->max_xmit);
1822
1823 if (server->max_xmit > given_max_xmit)
1824 server->max_xmit = given_max_xmit;
1825
1826 p = smb_decode_word(p, &server->tid);
1827
1828
1829
1830 server->max_xmit += 4;
1831
1832 DPRINTK("max_xmit = %d, tid = %d\n", server->max_xmit, server->tid);
1833
1834
1835 smb_kfree_s(server->packet, max_xmit);
1836
1837 server->packet = smb_kmalloc(server->max_xmit, GFP_KERNEL);
1838 if (server->packet == NULL) {
1839 printk("smb_proc_connect: No memory left in end of "
1840 "connection phase :-(\n");
1841 smb_dont_catch_keepalive(server);
1842 goto fail;
1843 }
1844
1845 DPRINTK("smb_proc_connect: Normal exit\n");
1846 return 0;
1847
1848 fail:
1849 server->state = CONN_INVALID;
1850 return result;
1851 }
1852
1853
1854
1855 int
1856 smb_proc_connect(struct smb_server *server)
1857 {
1858 int result;
1859 smb_lock_server(server);
1860 result = smb_proc_reconnect(server);
1861 if ((result < 0) && (server->packet != NULL)) {
1862 smb_kfree_s(server->packet, server->max_xmit);
1863 server->packet = NULL;
1864 }
1865 smb_unlock_server(server);
1866 return result;
1867 }
1868
1869 int
1870 smb_proc_disconnect(struct smb_server *server)
1871 {
1872 smb_setup_header_exclusive(server, SMBtdis, 0, 0);
1873 return smb_request_ok_unlock(server, SMBtdis, 0, 0);
1874 }
1875
1876
1877
1878
1879 #if DEBUG_SMB > 0
1880
1881 typedef struct {
1882 char *name;
1883 int code;
1884 char *message;
1885 } err_code_struct;
1886
1887
1888 err_code_struct dos_msgs[] = {
1889 { "ERRbadfunc",1,"Invalid function."},
1890 { "ERRbadfile",2,"File not found."},
1891 { "ERRbadpath",3,"Directory invalid."},
1892 { "ERRnofids",4,"No file descriptors available"},
1893 { "ERRnoaccess",5,"Access denied."},
1894 { "ERRbadfid",6,"Invalid file handle."},
1895 { "ERRbadmcb",7,"Memory control blocks destroyed."},
1896 { "ERRnomem",8,"Insufficient server memory to perform the requested function."},
1897 { "ERRbadmem",9,"Invalid memory block address."},
1898 { "ERRbadenv",10,"Invalid environment."},
1899 { "ERRbadformat",11,"Invalid format."},
1900 { "ERRbadaccess",12,"Invalid open mode."},
1901 { "ERRbaddata",13,"Invalid data."},
1902 { "ERR",14,"reserved."},
1903 { "ERRbaddrive",15,"Invalid drive specified."},
1904 { "ERRremcd",16,"A Delete Directory request attempted to remove the server's current directory."},
1905 { "ERRdiffdevice",17,"Not same device."},
1906 { "ERRnofiles",18,"A File Search command can find no more files matching the specified criteria."},
1907 { "ERRbadshare",32,"The sharing mode specified for an Open conflicts with existing FIDs on the file."},
1908 { "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."},
1909 { "ERRfilexists",80,"The file named in a Create Directory, Make New File or Link request already exists."},
1910 { "ERRbadpipe",230,"Pipe invalid."},
1911 { "ERRpipebusy",231,"All instances of the requested pipe are busy."},
1912 { "ERRpipeclosing",232,"Pipe close in progress."},
1913 { "ERRnotconnected",233,"No process on other end of pipe."},
1914 { "ERRmoredata",234,"There is more data to be returned."},
1915 { NULL,-1,NULL}};
1916
1917
1918 err_code_struct server_msgs[] = {
1919 { "ERRerror",1,"Non-specific error code."},
1920 { "ERRbadpw",2,"Bad password - name/password pair in a Tree Connect or Session Setup are invalid."},
1921 { "ERRbadtype",3,"reserved."},
1922 { "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."},
1923 { "ERRinvnid",5,"The tree ID (TID) specified in a command was invalid."},
1924 { "ERRinvnetname",6,"Invalid network name in tree connect."},
1925 { "ERRinvdevice",7,"Invalid device - printer request made to non-printer connection or non-printer request made to printer connection."},
1926 { "ERRqfull",49,"Print queue full (files) -- returned by open print file."},
1927 { "ERRqtoobig",50,"Print queue full -- no space."},
1928 { "ERRqeof",51,"EOF on print queue dump."},
1929 { "ERRinvpfid",52,"Invalid print file FID."},
1930 { "ERRsmbcmd",64,"The server did not recognize the command received."},
1931 { "ERRsrverror",65,"The server encountered an internal error, e.g., system file unavailable."},
1932 { "ERRfilespecs",67,"The file handle (FID) and pathname parameters contained an invalid combination of values."},
1933 { "ERRreserved",68,"reserved."},
1934 { "ERRbadpermits",69,"The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute."},
1935 { "ERRreserved",70,"reserved."},
1936 { "ERRsetattrmode",71,"The attribute mode in the Set File Attribute request is invalid."},
1937 { "ERRpaused",81,"Server is paused."},
1938 { "ERRmsgoff",82,"Not receiving messages."},
1939 { "ERRnoroom",83,"No room to buffer message."},
1940 { "ERRrmuns",87,"Too many remote user names."},
1941 { "ERRtimeout",88,"Operation timed out."},
1942 { "ERRnoresource",89,"No resources currently available for request."},
1943 { "ERRtoomanyuids",90,"Too many UIDs active on this session."},
1944 { "ERRbaduid",91,"The UID is not known as a valid ID on this session."},
1945 { "ERRusempx",250,"Temp unable to support Raw, use MPX mode."},
1946 { "ERRusestd",251,"Temp unable to support Raw, use standard read/write."},
1947 { "ERRcontmpx",252,"Continue in MPX mode."},
1948 { "ERRreserved",253,"reserved."},
1949 { "ERRreserved",254,"reserved."},
1950 { "ERRnosupport",0xFFFF,"Function not supported."},
1951 { NULL,-1,NULL}};
1952
1953
1954 err_code_struct hard_msgs[] = {
1955 { "ERRnowrite",19,"Attempt to write on write-protected diskette."},
1956 { "ERRbadunit",20,"Unknown unit."},
1957 { "ERRnotready",21,"Drive not ready."},
1958 { "ERRbadcmd",22,"Unknown command."},
1959 { "ERRdata",23,"Data error (CRC)."},
1960 { "ERRbadreq",24,"Bad request structure length."},
1961 { "ERRseek",25 ,"Seek error."},
1962 { "ERRbadmedia",26,"Unknown media type."},
1963 { "ERRbadsector",27,"Sector not found."},
1964 { "ERRnopaper",28,"Printer out of paper."},
1965 { "ERRwrite",29,"Write fault."},
1966 { "ERRread",30,"Read fault."},
1967 { "ERRgeneral",31,"General failure."},
1968 { "ERRbadshare",32,"A open conflicts with an existing open."},
1969 { "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."},
1970 { "ERRwrongdisk",34,"The wrong disk was found in a drive."},
1971 { "ERRFCBUnavail",35,"No FCBs are available to process request."},
1972 { "ERRsharebufexc",36,"A sharing buffer has been exceeded."},
1973 { NULL,-1,NULL}
1974 };
1975
1976
1977 struct {
1978 int code;
1979 char *class;
1980 err_code_struct *err_msgs;
1981 } err_classes[] = {
1982 { 0,"SUCCESS",NULL},
1983 { 0x01,"ERRDOS",dos_msgs},
1984 { 0x02,"ERRSRV",server_msgs},
1985 { 0x03,"ERRHRD",hard_msgs},
1986 { 0x04,"ERRXOS",NULL},
1987 { 0xE1,"ERRRMX1",NULL},
1988 { 0xE2,"ERRRMX2",NULL},
1989 { 0xE3,"ERRRMX3",NULL},
1990 { 0xFF,"ERRCMD",NULL},
1991 { -1,NULL,NULL}
1992 };
1993
1994 void
1995 smb_printerr(int class, int num)
1996 {
1997 int i,j;
1998 err_code_struct *err;
1999
2000 for (i=0; err_classes[i].class; i++) {
2001 if (err_classes[i].code != class)
2002 continue;
2003 if (!err_classes[i].err_msgs) {
2004 printk("%s - %d", err_classes[i].class, num);
2005 return;
2006 }
2007
2008 err = err_classes[i].err_msgs;
2009 for (j=0; err[j].name; j++) {
2010 if (num != err[j].code)
2011 continue;
2012 printk("%s - %s (%s)",
2013 err_classes[i].class, err[j].name,
2014 err[j].message);
2015 return;
2016 }
2017 }
2018
2019 printk("Unknown error - (%d,%d)", class, num);
2020 return;
2021 }
2022
2023 #endif
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040