1 #include "headers.h"
2
3 SmbProcessResult
smbcomrename(SmbSession * s,SmbHeader * h,uchar *,SmbBuffer * b)4 smbcomrename(SmbSession *s, SmbHeader *h, uchar *, SmbBuffer *b)
5 {
6 int rv;
7 char *old, *new;
8 char *oldpath = nil;
9 char *newpath = nil;
10 char *olddir, *newdir;
11 char *oldname, *newname;
12 uchar oldfmt, newfmt;
13 SmbTree *t;
14 Dir d;
15 SmbProcessResult pr;
16
17 if (h->wordcount != 1)
18 return SmbProcessResultFormat;
19 if (!smbbuffergetb(b, &oldfmt) || oldfmt != 0x04 || !smbbuffergetstring(b, h, SMB_STRING_PATH, &old)
20 || !smbbuffergetb(b, &newfmt) || newfmt != 0x04 || !smbbuffergetstring(b, h, SMB_STRING_PATH, &new))
21 return SmbProcessResultFormat;
22
23 t = smbidmapfind(s->tidmap, h->tid);
24 if (t == nil) {
25 smbseterror(s, ERRSRV, ERRinvtid);
26 return SmbProcessResultError;
27 }
28 smbstringprint(&oldpath, "%s%s", t->serv->path, old);
29 smbstringprint(&newpath, "%s%s", t->serv->path, new);
30
31 smblogprint(h->command, "smbcomrename: %s to %s\n", oldpath, newpath);
32 smbpathsplit(oldpath, &olddir, &oldname);
33 smbpathsplit(newpath, &newdir, &newname);
34 if (strcmp(olddir, newdir) != 0) {
35 smblogprint(h->command, "smbcomrename: directories differ\n");
36 goto noaccess;
37 }
38 memset(&d, 0xff, sizeof(d));
39 d.uid = d.gid = d.muid = nil;
40 d.name = newname;
41 rv = dirwstat(oldpath, &d);
42 if (rv < 0) {
43 smblogprint(h->command, "smbcomrename failed: %r\n");
44 noaccess:
45 smbseterror(s, ERRDOS, ERRnoaccess);
46 pr = SmbProcessResultError;
47 }
48 else
49 pr = smbbufferputack(s->response, h, &s->peerinfo);
50 free(oldpath);
51 free(olddir);
52 free(oldname);
53 free(newpath);
54 free(newdir);
55 free(newname);
56 return pr;
57 }
58