1 #include "headers.h" 2 3 SmbProcessResult 4 smbtrans2setfileinformation(SmbSession *s, SmbHeader *h) 5 { 6 SmbTree *t; 7 ushort infolevel; 8 SmbBuffer *b; 9 SmbProcessResult pr; 10 ushort fid; 11 SmbFile *f; 12 vlong newsize; 13 uvlong atime, mtime; 14 ulong attr; 15 ulong mode; 16 17 t = smbidmapfind(s->tidmap, h->tid); 18 if (t == nil) { 19 smbseterror(s, ERRSRV, ERRinvtid); 20 pr = SmbProcessResultError; 21 goto done; 22 } 23 b = smbbufferinit(s->transaction.in.parameters, s->transaction.in.parameters, s->transaction.in.tpcount); 24 if (!smbbuffergets(b, &fid) || !smbbuffergets(b, &infolevel)) { 25 misc: 26 pr = SmbProcessResultMisc; 27 goto done; 28 } 29 30 f = smbidmapfind(s->fidmap, fid); 31 if (f == nil) { 32 smbseterror(s, ERRDOS, ERRbadfid); 33 pr = SmbProcessResultError; 34 goto done; 35 } 36 37 switch (infolevel) { 38 case SMB_SET_FILE_ALLOCATION_INFO: 39 case SMB_SET_FILE_END_OF_FILE_INFO: 40 if (s->transaction.in.tdcount < 8) 41 goto misc; 42 newsize = smbnhgetv(s->transaction.in.data); 43 pr = smbtruncatefile(s, f, newsize); 44 if (pr == SmbProcessResultReply && !smbbufferputs(s->transaction.out.parameters, 0)) 45 goto misc; 46 break; 47 48 case SMB_SET_FILE_BASIC_INFO: 49 if (s->transaction.in.tdcount < 4 * 8 + 4) 50 goto misc; 51 atime = smbnhgetv(s->transaction.in.data + 8); 52 mtime = smbnhgetv(s->transaction.in.data + 24); 53 attr = smbnhgetv(s->transaction.in.data + 32); 54 if (attr) { 55 Dir *od = dirfstat(f->fd); 56 if (od == nil) 57 goto noaccess; 58 mode = smbdosattr2plan9wstatmode(od->mode, attr); 59 free(od); 60 } 61 else 62 mode = 0xffffffff; 63 if (atime || mtime || mode != 0xffffffff) { 64 Dir d; 65 memset(&d, 0xff, sizeof(d)); 66 d.name = d.uid = d.gid = d.muid = nil; 67 if (atime) 68 d.atime = smbtime2plan9time(atime); 69 if (mtime) 70 d.mtime = smbtime2plan9time(mtime); 71 d.mode = mode; 72 if (dirfwstat(f->fd, &d) < 0) { 73 noaccess: 74 smbseterror(s, ERRDOS, ERRnoaccess); 75 pr = SmbProcessResultError; 76 goto done; 77 } 78 } 79 if (!smbbufferputs(s->transaction.out.parameters, 0)) 80 goto misc; 81 pr = SmbProcessResultReply; 82 break; 83 84 case SMB_SET_FILE_DISPOSITION_INFO: 85 if (s->transaction.in.tdcount < 1) 86 goto misc; 87 f->sf->deleteonclose = *s->transaction.in.data; 88 if (!smbbufferputs(s->transaction.out.parameters, 0)) 89 goto misc; 90 pr = SmbProcessResultReply; 91 break; 92 93 default: 94 smblogprint(-1, "smbtrans2setfileinformation: infolevel 0x%.4ux not implemented\n", infolevel); 95 smbseterror(s, ERRDOS, ERRunknownlevel); 96 pr = SmbProcessResultError; 97 break; 98 } 99 done: 100 smbbufferfree(&b); 101 return pr; 102 } 103 104 SmbProcessResult 105 smbtrans2setpathinformation(SmbSession *s, SmbHeader *h) 106 { 107 char *fullpath, *path; 108 SmbTree *t; 109 ushort infolevel; 110 SmbBuffer *b; 111 SmbProcessResult pr; 112 ushort atime, adate, mtime, mdate; 113 ulong attr; 114 ulong mode; 115 ulong size; 116 // uvlong length; 117 118 t = smbidmapfind(s->tidmap, h->tid); 119 if (t == nil) { 120 smbseterror(s, ERRSRV, ERRinvtid); 121 pr = SmbProcessResultError; 122 goto done; 123 } 124 b = smbbufferinit(s->transaction.in.parameters, s->transaction.in.parameters, s->transaction.in.tpcount); 125 path = nil; 126 if (!smbbuffergets(b, &infolevel) || !smbbuffergetbytes(b, nil, 4) 127 || !smbbuffergetstring(b, h, SMB_STRING_PATH, &path)) { 128 misc: 129 pr = SmbProcessResultMisc; 130 goto done; 131 } 132 133 fullpath = nil; 134 smbstringprint(&fullpath, "%s%s", t->serv->path, path); 135 136 translogprint(s->transaction.in.setup[0], "path %s\n", path); 137 translogprint(s->transaction.in.setup[0], "infolevel 0x%.4ux\n", infolevel); 138 translogprint(s->transaction.in.setup[0], "fullpath %s\n", fullpath); 139 140 switch (infolevel) { 141 case SMB_INFO_STANDARD: 142 if (s->transaction.in.tdcount < 6 * 4 + 2 * 2) 143 goto misc; 144 adate = smbnhgets(s->transaction.in.data + 6); 145 atime = smbnhgets(s->transaction.in.data + 4); 146 mdate = smbnhgets(s->transaction.in.data + 10); 147 mtime = smbnhgets(s->transaction.in.data + 8); 148 size = smbnhgetl(s->transaction.in.data + 12); 149 attr = smbnhgets(s->transaction.in.data + 20); 150 if (attr) { 151 Dir *od = dirstat(fullpath); 152 if (od == nil) 153 goto noaccess; 154 mode = smbdosattr2plan9wstatmode(od->mode, attr); 155 free(od); 156 } 157 else 158 mode = 0xffffffff; 159 translogprint(s->transaction.in.setup[0], "mode 0%od\n", mode); 160 161 // if (size) 162 // length = size; 163 // else 164 // length = ~0LL; 165 166 translogprint(s->transaction.in.setup[0], "size %lld\n", size); 167 translogprint(s->transaction.in.setup[0], "adate %d atime %d", adate, atime); 168 translogprint(s->transaction.in.setup[0], "mdate %d mtime %d\n", mdate, mtime); 169 170 if (size || adate || atime || mdate || mtime || mode != 0xffffffff) { 171 Dir d; 172 memset(&d, 0xff, sizeof(d)); 173 d.name = d.uid = d.gid = d.muid = nil; 174 if (adate || atime) 175 d.atime = smbdatetime2plan9time(adate, atime, s->tzoff); 176 if (mdate || mtime) 177 d.mtime = smbdatetime2plan9time(mdate, mtime, s->tzoff); 178 d.mode = mode; 179 d.length = size; 180 if (dirwstat(fullpath, &d) < 0) { 181 noaccess: 182 smbseterror(s, ERRDOS, ERRnoaccess); 183 pr = SmbProcessResultError; 184 goto done; 185 } 186 } 187 if (!smbbufferputs(s->transaction.out.parameters, 0)) 188 goto misc; 189 pr = SmbProcessResultReply; 190 break; 191 192 default: 193 smblogprint(-1, "smbtrans2setpathinformation: infolevel 0x%.4ux not implemented\n", infolevel); 194 smbseterror(s, ERRDOS, ERRunknownlevel); 195 pr = SmbProcessResultError; 196 break; 197 } 198 done: 199 smbbufferfree(&b); 200 return pr; 201 } 202