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