1 #include "headers.h" 2 3 static void 4 smblogprintattr(int cmd, ushort attr) 5 { 6 if (attr & SMB_ATTR_READ_ONLY) 7 smblogprint(cmd, " readonly"); 8 if (attr & SMB_ATTR_HIDDEN) 9 smblogprint(cmd, " hidden"); 10 if (attr & SMB_ATTR_SYSTEM) 11 smblogprint(cmd, " system"); 12 if (attr & SMB_ATTR_DIRECTORY) 13 smblogprint(cmd, " directory"); 14 if (attr & SMB_ATTR_ARCHIVE) 15 smblogprint(cmd, " archive"); 16 } 17 18 static SmbFile * 19 openfile(SmbSession *s, SmbTree *t, char *path, ushort mode, ushort attr, ushort ofun, ulong createoptions, uvlong createsize, 20 ushort *fidp, Dir **dp, ushort *actionp) 21 { 22 int p9mode; 23 int share; 24 Dir *d = nil; 25 int fd = -1; 26 ushort action; 27 SmbFile *f = nil; 28 SmbSharedFile *sf = nil; 29 char *fullpath = nil; 30 int diropen = 0; 31 32 //smblogprint(-1, "%s A %r", path); 33 p9mode = (mode >> SMB_OPEN_MODE_ACCESS_SHIFT) & SMB_OPEN_MODE_ACCESS_MASK; 34 share = (mode >> SMB_OPEN_MODE_SHARE_SHIFT) & SMB_OPEN_MODE_SHARE_MASK; 35 if (share == SMB_OPEN_MODE_SHARE_COMPATIBILITY) { 36 badshare: 37 //smblogprint(-1, "%s SMB_OPEN_MODE_SHARE_COMPATIBILITY", path); 38 smbseterror(s, ERRDOS, ERRbadshare); 39 goto done; 40 } 41 smbstringprint(&fullpath, "%s%s", t->serv->path, path); 42 d = dirstat(fullpath); 43 if (d) { 44 /* file exists */ 45 int ofunexist; 46 if (d->mode & DMDIR) { 47 if (createoptions & SMB_CO_FILE) { 48 smbseterror(s, ERRDOS, ERRnoaccess); 49 goto done; 50 } 51 } 52 else if (createoptions & SMB_CO_DIRECTORY) { 53 smbseterror(s, ERRDOS, ERRnoaccess); 54 goto done; 55 } 56 57 sf = smbsharedfileget(d, p9mode, &share); 58 if (sf == nil) 59 goto badshare; 60 action = 1; 61 ofunexist = (ofun >> SMB_OFUN_EXIST_SHIFT) & SMB_OFUN_EXIST_MASK; 62 if (ofunexist == SMB_OFUN_EXIST_FAIL) { 63 smbseterror(s, ERRDOS, ERRfilexists); 64 goto done; 65 } 66 else if (ofunexist == SMB_OFUN_EXIST_TRUNCATE) { 67 if ((d->mode & DMDIR) || (p9mode != OWRITE && p9mode != ORDWR)) { 68 smbseterror(s, ERRDOS, ERRbadaccess); 69 goto done; 70 } 71 p9mode |= OTRUNC; 72 action = 3; 73 } 74 else if (ofunexist != SMB_OFUN_EXIST_OPEN) { 75 smbseterror(s, ERRDOS, ERRbadaccess); 76 goto done; 77 } 78 if (d->mode & DMDIR) 79 diropen = 1; 80 else 81 fd = open(fullpath, p9mode); 82 } 83 else { 84 /* file does not exist */ 85 ulong p9attr; 86 action = 3; 87 if ((ofun & SMB_OFUN_NOEXIST_CREATE) == 0) { 88 smbseterror(s, ERRDOS, ERRbadfile); 89 goto done; 90 } 91 if (createsize != 0) { 92 smbseterror(s, ERRDOS, ERRunsup); 93 goto done; 94 } 95 //smblogprint(-1, "creating: attr 0x%.4ux co 0x%.8lux\n", attr, createoptions); 96 if (createoptions & SMB_CO_FILE) { 97 attr &= SMB_ATTR_DIRECTORY; 98 if (attr == 0) 99 attr = SMB_ATTR_NORMAL; 100 } 101 else if (createoptions & SMB_CO_DIRECTORY) { 102 attr &= ~SMB_ATTR_NORMAL; 103 attr |= SMB_ATTR_DIRECTORY; 104 p9mode = OREAD; 105 } 106 //smblogprint(-1, "creating: before conversion attr 0x%.4ux\n", attr); 107 p9attr = smbdosattr2plan9mode(attr); 108 //smblogprint(-1, "creating: after conversion p9attr 0%.uo\n", p9attr); 109 fd = create(fullpath, p9mode, p9attr); 110 if (fd >= 0) { 111 d = dirfstat(fd); 112 sf = smbsharedfileget(d, p9mode, &share); 113 if (sf == nil) { 114 close(fd); 115 remove(path); 116 goto badshare; 117 } 118 } 119 } 120 //smblogprint(-1, "%s D %r", fullpath); 121 if (!diropen && fd < 0) { 122 smbseterror(s, ERRSRV, ERRaccess); 123 goto done; 124 } 125 f = smbemalloc(sizeof(SmbFile)); 126 if (diropen) { 127 f->ioallowed = 0; 128 f->fd = -1; 129 } 130 else { 131 f->ioallowed = 1; 132 f->fd = fd; 133 } 134 f->name = smbestrdup(path); 135 f->sf = sf; 136 sf = nil; 137 f->share = share; 138 f->p9mode = p9mode; 139 f->t = t; 140 if (s->fidmap == nil) 141 s->fidmap = smbidmapnew(); 142 *fidp = smbidmapadd(s->fidmap, f); 143 //smblogprint(h->command, "REPLY:\n t->id=0x%ux fid=%d path=%s\n", t->id, *fidp, path); 144 smblogprintif(smbglobals.log.fids, "openfile: 0x%.4ux/0x%.4ux %s\n", t->id, *fidp, path); 145 if (actionp) 146 *actionp = action; 147 if (dp) { 148 *dp = d; 149 d = nil; 150 } 151 done: 152 if (sf) 153 smbsharedfileput(nil, sf, share); 154 free(d); 155 free(fullpath); 156 return f; 157 } 158 159 SmbProcessResult 160 smbcomopenandx(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b) 161 { 162 uchar andxcommand; 163 ushort andxoffset, flags, mode, sattr, attr; 164 ulong createtime; 165 ushort ofun; 166 ulong createsize, timeout; 167 char *path = nil; 168 ulong andxoffsetfixupoffset; 169 SmbProcessResult pr; 170 ushort action; 171 Dir *d = nil; 172 SmbFile *f; 173 SmbTree *t; 174 ushort fid; 175 176 if (!smbcheckwordcount("comopenandx", h, 15)) 177 return SmbProcessResultFormat; 178 179 andxcommand = *pdata++; 180 pdata++; 181 andxoffset = smbnhgets(pdata); pdata += 2; 182 flags = smbnhgets(pdata); pdata += 2; 183 mode = smbnhgets(pdata); pdata += 2; 184 sattr = smbnhgets(pdata); pdata += 2; 185 attr = smbnhgets(pdata); pdata += 2; 186 createtime = smbnhgetl(pdata); pdata += 4; 187 ofun = smbnhgets(pdata); pdata += 2; 188 createsize = smbnhgetl(pdata); pdata += 4; 189 timeout = smbnhgetl(pdata); pdata += 4; 190 pdata += 4; 191 USED(pdata); 192 if (!smbbuffergetstring(b, h, SMB_STRING_PATH, &path)) { 193 pr = SmbProcessResultFormat; 194 goto done; 195 } 196 197 smbloglock(); 198 smblogprint(h->command, "flags 0x%.4ux", flags); 199 if (flags & SMB_OPEN_FLAGS_ADDITIONAL) 200 smblogprint(h->command, " additional"); 201 if (flags & SMB_OPEN_FLAGS_OPLOCK) 202 smblogprint(h->command, " oplock"); 203 if (flags & SMB_OPEN_FLAGS_OPBATCH) 204 smblogprint(h->command, " opbatch"); 205 smblogprint(h->command, "\n"); 206 smblogprint(h->command, "mode 0x%.4ux", mode); 207 switch ((mode >> SMB_OPEN_MODE_ACCESS_SHIFT) & SMB_OPEN_MODE_ACCESS_MASK) { 208 case OREAD: 209 smblogprint(h->command, " OREAD"); 210 break; 211 case OWRITE: 212 smblogprint(h->command, " OWRITE"); 213 break; 214 case ORDWR: 215 smblogprint(h->command, " ORDWR"); 216 break; 217 case OEXEC: 218 smblogprint(h->command, " OEXEC"); 219 break; 220 } 221 switch ((mode >> SMB_OPEN_MODE_SHARE_SHIFT) & SMB_OPEN_MODE_SHARE_MASK) { 222 case SMB_OPEN_MODE_SHARE_COMPATIBILITY: 223 smblogprint(h->command, " compatinility"); 224 break; 225 case SMB_OPEN_MODE_SHARE_EXCLUSIVE: 226 smblogprint(h->command, " exclusive"); 227 break; 228 case SMB_OPEN_MODE_SHARE_DENY_WRITE: 229 smblogprint(h->command, " deny write"); 230 break; 231 case SMB_OPEN_MODE_SHARE_DENY_READOREXEC: 232 smblogprint(h->command, " deny readorxec"); 233 break; 234 case SMB_OPEN_MODE_SHARE_DENY_NONE: 235 smblogprint(h->command, " deny none"); 236 break; 237 } 238 if (mode & SMB_OPEN_MODE_WRITE_THROUGH) 239 smblogprint(h->command, " write through"); 240 smblogprint(h->command, "\n"); 241 smblogprint(h->command, "sattr 0x%.4ux", sattr); 242 smblogprintattr(h->command, sattr); 243 smblogprint(h->command, "\n"); 244 smblogprint(h->command, "attr 0x%.4ux", attr); 245 smblogprintattr(h->command, attr); 246 smblogprint(h->command, "\n"); 247 smblogprint(h->command, "createtime 0x%.8lux\n", createtime); 248 smblogprint(h->command, "ofun 0x%.4ux", ofun); 249 if (ofun & SMB_OFUN_NOEXIST_CREATE) 250 smblogprint(h->command, " noexistscreate"); 251 else 252 smblogprint(h->command, " noexistfail"); 253 switch ((ofun >> SMB_OFUN_EXIST_SHIFT) & SMB_OFUN_EXIST_MASK) { 254 case SMB_OFUN_EXIST_FAIL: 255 smblogprint(h->command, " existfail"); 256 break; 257 case SMB_OFUN_EXIST_OPEN: 258 smblogprint(h->command, " existopen"); 259 break; 260 case SMB_OFUN_EXIST_TRUNCATE: 261 smblogprint(h->command, " existtruncate"); 262 break; 263 } 264 smblogprint(h->command, "\n"); 265 smblogprint(h->command, "createsize 0x%.8lux\n", createsize); 266 smblogprint(h->command, "timeout 0x%.8lux\n", timeout); 267 smblogprint(h->command, "path %s\n", path); 268 smblogunlock(); 269 270 t = smbidmapfind(s->tidmap, h->tid); 271 if (t == nil) { 272 smbseterror(s, ERRSRV, ERRinvtid); 273 goto errordone; 274 } 275 276 f = openfile(s, t, path, mode, attr, ofun, 0, createsize, &fid, &d, &action); 277 if (f == nil) { 278 pr = SmbProcessResultError; 279 goto done; 280 } 281 h->wordcount = 15; 282 if (!smbbufferputandxheader(s->response, h, &s->peerinfo, andxcommand, &andxoffsetfixupoffset) 283 || !smbbufferputs(s->response, fid) 284 || !smbbufferputs(s->response, smbplan9mode2dosattr(d->mode)) 285 || !smbbufferputl(s->response, smbplan9time2utime(d->mtime, s->tzoff)) 286 || !smbbufferputl(s->response, smbplan9length2size32(d->length)) 287 || !smbbufferputs(s->response, smbplan9mode2dosattr(d->mode)) // probbaly bogus 288 || !smbbufferputs(s->response, 0) // all files are files 289 || !smbbufferputs(s->response, 0) // pipe state 290 || !smbbufferputs(s->response, action) 291 || !smbbufferputl(s->response, 0) // fileID 292 || !smbbufferputs(s->response, 0) 293 || !smbbufferputs(s->response, 0)) { // bytecount 0 294 smbfileclose(s, f); 295 pr = SmbProcessResultMisc; 296 goto done; 297 } 298 if (andxcommand != SMB_COM_NO_ANDX_COMMAND) 299 pr = smbchaincommand(s, h, andxoffsetfixupoffset, andxcommand, andxoffset, b); 300 else 301 pr = SmbProcessResultReply; 302 goto done; 303 errordone: 304 pr = SmbProcessResultError; 305 done: 306 free(path); 307 free(d); 308 return pr; 309 } 310 311 SmbProcessResult 312 smbcomopen(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b) 313 { 314 uchar fmt; 315 char *path; 316 ushort mode, attr; 317 SmbTree *t; 318 ushort fid; 319 Dir *d = nil; 320 SmbFile *f; 321 SmbProcessResult pr; 322 323 if (!smbcheckwordcount("comopen", h, 2)) 324 return SmbProcessResultFormat; 325 mode = smbnhgets(pdata); 326 attr = smbnhgets(pdata + 2); 327 if (!smbbuffergetb(b, &fmt) 328 || fmt != 4 329 || !smbbuffergetstring(b, h, SMB_STRING_PATH, &path)) { 330 pr = SmbProcessResultFormat; 331 goto done; 332 } 333 t = smbidmapfind(s->tidmap, h->tid); 334 if (t == nil) { 335 smbseterror(s, ERRSRV, ERRinvtid); 336 error: 337 pr = SmbProcessResultError; 338 goto done; 339 } 340 f = openfile(s, t, path, mode, attr, 341 SMB_OFUN_EXIST_OPEN << SMB_OFUN_EXIST_SHIFT, 342 0, 0, &fid, &d, nil); 343 if (f == nil) 344 goto error; 345 h->wordcount = 7; 346 if (!smbbufferputheader(s->response, h, &s->peerinfo) 347 || !smbbufferputs(s->response, fid) 348 || !smbbufferputs(s->response, smbplan9mode2dosattr(d->mode)) 349 || !smbbufferputl(s->response, smbplan9time2utime(d->mtime, s->tzoff)) 350 || !smbbufferputl(s->response, smbplan9length2size32(d->length)) 351 || !smbbufferputs(s->response, 2) // lies - this should be the actual access allowed 352 || !smbbufferputs(s->response, 0)) 353 pr = SmbProcessResultMisc; 354 else 355 pr = SmbProcessResultReply; 356 done: 357 free(path); 358 free(d); 359 return pr; 360 } 361 362 363 /* 364 smb_com SMBcreate smb_com SMBcreate 365 smb_wct 3 smb_wct 1 366 smb_vwv[0] attribute smb_vwv[0] file handle 367 smb_vwv[1] time low smb_bcc 0 368 smb_vwv[2] time high 369 smb_bcc min = 2 370 smb_buf[] ASCII -- 04 371 file pathname 372 */ 373 374 SmbProcessResult 375 smbcomcreate(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b) 376 { 377 int ofun, attr, mode; 378 long createtime; 379 char *path; 380 uchar fmt; 381 SmbFile *f; 382 SmbTree *t; 383 ushort fid; 384 SmbProcessResult pr; 385 386 path = nil; 387 if (!smbcheckwordcount("comcreate", h, 3)) 388 return SmbProcessResultFormat; 389 390 smblogprint(h->command, "tid=%d\n", h->tid); 391 attr = smbnhgets(pdata); pdata += 2; 392 createtime = smbnhgetl(pdata); 393 if (!smbbuffergetb(b, &fmt) || fmt != 0x04 || 394 !smbbuffergetstring(b, h, SMB_STRING_PATH, &path)){ 395 pr = SmbProcessResultError; 396 goto done; 397 } 398 399 smbloglock(); 400 smblogprint(h->command, "path %s\n", path); 401 smblogprint(h->command, "attr 0x%.4ux", attr); 402 smblogprintattr(h->command, attr); 403 smblogprint(h->command, "\n"); 404 smblogprint(h->command, "createtime 0x%.8lux\n", createtime); 405 smblogunlock(); 406 407 t = smbidmapfind(s->tidmap, h->tid); 408 if (t == nil) { 409 pr = SmbProcessResultError; 410 goto done; 411 } 412 413 mode = (ORDWR<<SMB_OPEN_MODE_ACCESS_SHIFT) | // SFS: FIXME: should be OWRITE? 414 (SMB_OPEN_MODE_SHARE_EXCLUSIVE<<SMB_OPEN_MODE_SHARE_SHIFT); 415 ofun = SMB_OFUN_NOEXIST_CREATE|(SMB_OFUN_EXIST_FAIL<<SMB_OFUN_EXIST_SHIFT); 416 f = openfile(s, t, path, mode, attr, ofun, SMB_CO_FILE, 0, &fid, nil, nil); 417 if (f == nil) { 418 pr = SmbProcessResultError; 419 goto done; 420 } 421 422 h->wordcount = 1; // SFS: FIXME: unsure of this constant, maybe should be 3 423 if (!smbbufferputheader(s->response, h, &s->peerinfo) 424 || !smbbufferputs(s->response, fid) 425 || !smbbufferputs(s->response, 0)){ // bytecount 0 426 pr = SmbProcessResultMisc; 427 goto done; 428 } 429 pr = SmbProcessResultReply; 430 goto done; 431 432 done: 433 free(path); 434 return pr; 435 } 436 437 438 typedef struct SmbSblut { 439 char *s; 440 ulong mask; 441 } SmbSblut; 442 443 static SmbSblut dasblut[] = { 444 { "SMB_DA_SPECIFIC_READ_DATA", SMB_DA_SPECIFIC_READ_DATA }, 445 { "SMB_DA_SPECIFIC_WRITE_DATA", SMB_DA_SPECIFIC_WRITE_DATA }, 446 { "SMB_DA_SPECIFIC_APPEND_DATA", SMB_DA_SPECIFIC_APPEND_DATA }, 447 { "SMB_DA_SPECIFIC_READ_EA", SMB_DA_SPECIFIC_READ_EA }, 448 { "SMB_DA_SPECIFIC_WRITE_EA", SMB_DA_SPECIFIC_WRITE_EA }, 449 { "SMB_DA_SPECIFIC_EXECUTE", SMB_DA_SPECIFIC_EXECUTE }, 450 { "SMB_DA_SPECIFIC_DELETE_CHILD", SMB_DA_SPECIFIC_DELETE_CHILD }, 451 { "SMB_DA_SPECIFIC_READ_ATTRIBUTES", SMB_DA_SPECIFIC_READ_ATTRIBUTES }, 452 { "SMB_DA_SPECIFIC_WRITE_ATTRIBUTES", SMB_DA_SPECIFIC_WRITE_ATTRIBUTES }, 453 { "SMB_DA_STANDARD_DELETE_ACCESS", SMB_DA_STANDARD_DELETE_ACCESS }, 454 { "SMB_DA_STANDARD_READ_CONTROL_ACCESS", SMB_DA_STANDARD_READ_CONTROL_ACCESS }, 455 { "SMB_DA_STANDARD_WRITE_DAC_ACCESS", SMB_DA_STANDARD_WRITE_DAC_ACCESS }, 456 { "SMB_DA_STANDARD_WRITE_OWNER_ACCESS", SMB_DA_STANDARD_WRITE_OWNER_ACCESS }, 457 { "SMB_DA_STANDARD_SYNCHRONIZE_ACCESS", SMB_DA_STANDARD_SYNCHRONIZE_ACCESS }, 458 { "SMB_DA_GENERIC_ALL_ACCESS", SMB_DA_GENERIC_ALL_ACCESS }, 459 { "SMB_DA_GENERIC_EXECUTE_ACCESS", SMB_DA_GENERIC_EXECUTE_ACCESS }, 460 { "SMB_DA_GENERIC_WRITE_ACCESS", SMB_DA_GENERIC_WRITE_ACCESS }, 461 { "SMB_DA_GENERIC_READ_ACCESS", SMB_DA_GENERIC_READ_ACCESS }, 462 { 0 } 463 }; 464 465 static SmbSblut efasblut[] = { 466 { "SMB_ATTR_READ_ONLY", SMB_ATTR_READ_ONLY }, 467 { "SMB_ATTR_HIDDEN", SMB_ATTR_HIDDEN }, 468 { "SMB_ATTR_SYSTEM", SMB_ATTR_SYSTEM }, 469 { "SMB_ATTR_DIRECTORY", SMB_ATTR_DIRECTORY }, 470 { "SMB_ATTR_ARCHIVE", SMB_ATTR_ARCHIVE }, 471 { "SMB_ATTR_NORMAL", SMB_ATTR_NORMAL }, 472 { "SMB_ATTR_COMPRESSED", SMB_ATTR_COMPRESSED }, 473 { "SMB_ATTR_TEMPORARY", SMB_ATTR_TEMPORARY }, 474 { "SMB_ATTR_WRITETHROUGH", SMB_ATTR_WRITETHROUGH }, 475 { "SMB_ATTR_NO_BUFFERING", SMB_ATTR_NO_BUFFERING }, 476 { "SMB_ATTR_RANDOM_ACCESS", SMB_ATTR_RANDOM_ACCESS }, 477 { 0 } 478 }; 479 480 static SmbSblut sasblut[] = { 481 { "SMB_SA_SHARE_READ", SMB_SA_SHARE_READ }, 482 { "SMB_SA_SHARE_WRITE", SMB_SA_SHARE_WRITE }, 483 { "SMB_SA_SHARE_DELETE", SMB_SA_SHARE_DELETE }, 484 { "SMB_SA_NO_SHARE", SMB_SA_NO_SHARE }, 485 { 0 } 486 }; 487 488 static SmbSblut cosblut[] = { 489 { "SMB_CO_DIRECTORY", SMB_CO_DIRECTORY }, 490 { "SMB_CO_WRITETHROUGH", SMB_CO_WRITETHROUGH }, 491 { "SMB_CO_SEQUENTIAL_ONLY", SMB_CO_SEQUENTIAL_ONLY }, 492 { "SMB_CO_FILE", SMB_CO_FILE }, 493 { "SMB_CO_NO_EA_KNOWLEDGE", SMB_CO_NO_EA_KNOWLEDGE }, 494 { "SMB_CO_EIGHT_DOT_THREE_ONLY", SMB_CO_EIGHT_DOT_THREE_ONLY }, 495 { "SMB_CO_RANDOM_ACCESS", SMB_CO_RANDOM_ACCESS }, 496 { "SMB_CO_DELETE_ON_CLOSE", SMB_CO_DELETE_ON_CLOSE }, 497 { 0 } 498 }; 499 500 static SmbSlut cdslut[] = { 501 { "SMB_CD_SUPERCEDE", SMB_CD_SUPERCEDE }, 502 { "SMB_CD_OPEN", SMB_CD_OPEN }, 503 { "SMB_CD_CREATE", SMB_CD_CREATE }, 504 { "SMB_CD_OPEN_IF", SMB_CD_OPEN_IF }, 505 { "SMB_CD_OVERWRITE", SMB_CD_OVERWRITE }, 506 { "SMB_CD_OVERWRITE_IF", SMB_CD_OVERWRITE_IF }, 507 { 0 } 508 }; 509 510 static void 511 smbsblutlogprint(uchar cmd, SmbSblut *sblut, ulong mask) 512 { 513 while (sblut->s) { 514 if (mask && (sblut->mask & mask) || (mask == 0 && sblut->mask == 0)) 515 smblogprint(cmd, " %s", sblut->s); 516 sblut++; 517 } 518 } 519 520 SmbProcessResult 521 smbcomntcreateandx(SmbSession *s, SmbHeader *h, uchar *pdata, SmbBuffer *b) 522 { 523 uchar andxcommand; 524 ushort andxoffset; 525 char *path = nil; 526 SmbProcessResult pr; 527 ulong namelength; 528 ulong flags; 529 ulong rootdirectoryfid, desiredaccess; 530 uvlong allocationsize; 531 ulong extfileattributes, shareaccess, createdisposition, createoptions, impersonationlevel; 532 uchar securityflags; 533 int p9mode; 534 int sharemode; 535 ushort mode; 536 SmbTree *t; 537 ushort ofun; 538 SmbFile *f; 539 ushort fid; 540 Dir *d = nil; 541 ushort action; 542 uvlong mtime; 543 ulong andxoffsetfixup; 544 545 if (!smbcheckwordcount("comntcreateandx", h, 24)) 546 return SmbProcessResultFormat; 547 548 andxcommand = *pdata++; 549 pdata++; 550 andxoffset = smbnhgets(pdata); pdata += 2; 551 pdata++; 552 namelength = smbnhgets(pdata); pdata += 2; 553 flags = smbnhgetl(pdata); pdata += 4; 554 rootdirectoryfid = smbnhgetl(pdata); pdata += 4; 555 desiredaccess = smbnhgetl(pdata); pdata += 4; 556 allocationsize = smbnhgetv(pdata); pdata += 8; 557 extfileattributes = smbnhgetl(pdata); pdata += 4; 558 shareaccess = smbnhgetl(pdata); pdata += 4; 559 createdisposition = smbnhgetl(pdata); pdata += 4; 560 createoptions = smbnhgetl(pdata); pdata += 4; 561 impersonationlevel = smbnhgetl(pdata); pdata += 4; 562 securityflags = *pdata++; 563 USED(pdata); 564 565 if (!smbbuffergetstring(b, h, SMB_STRING_PATH, &path)) { 566 pr = SmbProcessResultFormat; 567 goto done; 568 } 569 570 smblogprint(h->command, "namelength %d\n", namelength); 571 smblogprint(h->command, "flags 0x%.8lux\n", flags); 572 smblogprint(h->command, "rootdirectoryfid %lud\n", rootdirectoryfid); 573 smblogprint(h->command, "desiredaccess 0x%.8lux", desiredaccess); 574 smbsblutlogprint(h->command, dasblut, desiredaccess); 575 smblogprint(h->command, "\n"); 576 smblogprint(h->command, "allocationsize %llud\n", allocationsize); 577 smblogprint(h->command, "extfileattributes 0x%.8lux", extfileattributes); 578 smbsblutlogprint(h->command, efasblut, extfileattributes); 579 smblogprint(h->command, "\n"); 580 smblogprint(h->command, "shareaccess 0x%.8lux", shareaccess); 581 smbsblutlogprint(h->command, sasblut, shareaccess); 582 smblogprint(h->command, "\n"); 583 smblogprint(h->command, "createdisposition 0x%.8lux %s\n", 584 createdisposition, smbrevslut(cdslut, createdisposition)); 585 smblogprint(h->command, "createoptions 0x%.8lux", createoptions); 586 smbsblutlogprint(h->command, cosblut, createoptions); 587 smblogprint(h->command, "\n"); 588 smblogprint(h->command, "impersonationlevel 0x%.8lux\n", impersonationlevel); 589 smblogprint(h->command, "securityflags 0x%.2ux\n", securityflags); 590 smblogprint(h->command, "path %s\n", path); 591 592 if (rootdirectoryfid != 0) { 593 smblogprint(-1, "smbcomntcreateandx: fid relative not implemented\n"); 594 goto unimp; 595 } 596 597 if (desiredaccess & SMB_DA_GENERIC_MASK) 598 switch (desiredaccess & SMB_DA_GENERIC_MASK){ 599 case SMB_DA_GENERIC_READ_ACCESS: 600 p9mode = OREAD; 601 break; 602 case SMB_DA_GENERIC_WRITE_ACCESS: 603 p9mode = OWRITE; 604 break; 605 case SMB_DA_GENERIC_ALL_ACCESS: 606 p9mode = ORDWR; 607 break; 608 case SMB_DA_GENERIC_EXECUTE_ACCESS: 609 p9mode = OEXEC; 610 break; 611 default: 612 p9mode = OREAD; 613 break; 614 } 615 else 616 if (desiredaccess & SMB_DA_SPECIFIC_READ_DATA) 617 if (desiredaccess & (SMB_DA_SPECIFIC_WRITE_DATA | SMB_DA_SPECIFIC_APPEND_DATA)) 618 p9mode = ORDWR; 619 else 620 p9mode = OREAD; 621 else if (desiredaccess & (SMB_DA_SPECIFIC_WRITE_DATA | SMB_DA_SPECIFIC_APPEND_DATA)) 622 p9mode = ORDWR; 623 else 624 p9mode = OREAD; 625 626 if (shareaccess == SMB_SA_NO_SHARE) 627 sharemode = SMB_OPEN_MODE_SHARE_EXCLUSIVE; 628 else if (shareaccess & (SMB_SA_SHARE_READ | SMB_SA_SHARE_WRITE) == 629 (SMB_SA_SHARE_READ | SMB_SA_SHARE_WRITE)) 630 sharemode = SMB_OPEN_MODE_SHARE_DENY_NONE; 631 else if (shareaccess & SMB_SA_SHARE_READ) 632 sharemode = SMB_OPEN_MODE_SHARE_DENY_WRITE; 633 else if (shareaccess & SMB_SA_SHARE_WRITE) 634 sharemode = SMB_OPEN_MODE_SHARE_DENY_READOREXEC; 635 else 636 sharemode = SMB_OPEN_MODE_SHARE_DENY_NONE; 637 638 mode = (sharemode << SMB_OPEN_MODE_SHARE_SHIFT) | (p9mode << SMB_OPEN_MODE_ACCESS_SHIFT); 639 640 switch (createdisposition) { 641 default: 642 smblogprint(-1, "smbcomntcreateandx: createdisposition 0x%.8lux not implemented\n", createdisposition); 643 goto unimp; 644 case SMB_CD_OPEN: 645 ofun = SMB_OFUN_EXIST_OPEN; 646 break; 647 case SMB_CD_CREATE: 648 ofun = SMB_OFUN_EXIST_FAIL | SMB_OFUN_NOEXIST_CREATE; 649 break; 650 case SMB_CD_OPEN_IF: 651 ofun = SMB_OFUN_EXIST_OPEN | SMB_OFUN_NOEXIST_CREATE; 652 break; 653 case SMB_CD_OVERWRITE: 654 ofun = SMB_OFUN_EXIST_TRUNCATE; 655 break; 656 case SMB_CD_OVERWRITE_IF: 657 ofun = SMB_OFUN_EXIST_TRUNCATE | SMB_OFUN_NOEXIST_CREATE; 658 break; 659 } 660 661 t = smbidmapfind(s->tidmap, h->tid); 662 if (t == nil) { 663 smbseterror(s, ERRSRV, ERRinvtid); 664 pr = SmbProcessResultError; 665 goto done; 666 } 667 668 f = openfile(s, t, path, mode, extfileattributes, ofun, createoptions, allocationsize, &fid, &d, &action); 669 670 if (f == nil) { 671 pr = SmbProcessResultError; 672 goto done; 673 } 674 675 h->wordcount = 42; 676 mtime = smbplan9time2time(d->mtime); 677 if (!smbbufferputandxheader(s->response, h, &s->peerinfo, andxcommand, &andxoffsetfixup) 678 || !smbbufferputb(s->response, 0) // oplocks? pah 679 || !smbbufferputs(s->response, fid) 680 || !smbbufferputl(s->response, action) 681 || !smbbufferputv(s->response, mtime) 682 || !smbbufferputv(s->response, smbplan9time2time(d->atime)) 683 || !smbbufferputv(s->response, mtime) 684 || !smbbufferputv(s->response, mtime) 685 || !smbbufferputl(s->response, smbplan9mode2dosattr(d->mode)) 686 || !smbbufferputv(s->response, smbl2roundupvlong(d->length, smbglobals.l2allocationsize)) 687 || !smbbufferputv(s->response, d->length) 688 || !smbbufferputbytes(s->response, nil, 4) 689 || !smbbufferputb(s->response, (d->qid.type & QTDIR) != 0) 690 || !smbbufferputbytes(s->response, nil, 8) 691 || !smbbufferputs(s->response, 0)) { 692 pr = SmbProcessResultMisc; 693 goto done; 694 } 695 696 if (andxcommand != SMB_COM_NO_ANDX_COMMAND) 697 pr = smbchaincommand(s, h, andxoffsetfixup, andxcommand, andxoffset, b); 698 else 699 pr = SmbProcessResultReply; 700 701 goto done; 702 703 unimp: 704 pr = SmbProcessResultUnimp; 705 706 done: 707 free(path); 708 free(d); 709 710 return pr; 711 } 712 713