Print this page
Build provider 3rd arg from smb_request_t
hacking...
NEX-1643 dtrace provider for smbsrv
Also illumos 1841:
 DTrace smb provider was mis-implemented, doesn't exist.
Add back handlers for read/write raw, so that
 legacy dtrace consumers can find the probes.
Kill extra arg in smb_negotiate
Fix missing "done" probe with smb_notify
Add example consumer: smb-trace.d
fix soi_pid


  44  * server encountered a resource issue.
  45  */
  46 smb_sdrc_t
  47 smb_pre_write(smb_request_t *sr)
  48 {
  49         smb_rw_param_t *param;
  50         uint32_t off;
  51         uint16_t count;
  52         int rc;
  53 
  54         param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
  55         sr->arg.rw = param;
  56         param->rw_magic = SMB_RW_MAGIC;
  57 
  58         rc = smbsr_decode_vwv(sr, "wwl", &sr->smb_fid, &count, &off);
  59 
  60         param->rw_count = (uint32_t)count;
  61         param->rw_offset = (uint64_t)off;
  62         param->rw_vdb.vdb_uio.uio_loffset = (offset_t)param->rw_offset;
  63 
  64         DTRACE_SMB_2(op__Write__start, smb_request_t *, sr,
  65             smb_rw_param_t *, param);
  66 
  67         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
  68 }
  69 
  70 void
  71 smb_post_write(smb_request_t *sr)
  72 {
  73         DTRACE_SMB_2(op__Write__done, smb_request_t *, sr,
  74             smb_rw_param_t *, sr->arg.rw);
  75 
  76         kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
  77 }
  78 
  79 smb_sdrc_t
  80 smb_com_write(smb_request_t *sr)
  81 {
  82         smb_rw_param_t *param = sr->arg.rw;
  83         int rc;
  84 
  85         smbsr_lookup_file(sr);
  86         if (sr->fid_ofile == NULL) {
  87                 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
  88                 return (SDRC_ERROR);
  89         }
  90 
  91         sr->user_cr = smb_ofile_getcred(sr->fid_ofile);
  92 
  93         if (param->rw_count == 0) {
  94                 rc = smb_write_truncate(sr, param);


 134         smb_rw_param_t *param;
 135         uint32_t off;
 136         uint16_t count;
 137         int rc;
 138 
 139         param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
 140         sr->arg.rw = param;
 141         param->rw_magic = SMB_RW_MAGIC;
 142 
 143         if (sr->smb_wct == 12) {
 144                 rc = smbsr_decode_vwv(sr, "wwll12.", &sr->smb_fid,
 145                     &count, &off, &param->rw_last_write);
 146         } else {
 147                 rc = smbsr_decode_vwv(sr, "wwll", &sr->smb_fid,
 148                     &count, &off, &param->rw_last_write);
 149         }
 150 
 151         param->rw_count = (uint32_t)count;
 152         param->rw_offset = (uint64_t)off;
 153 
 154         DTRACE_SMB_2(op__WriteAndClose__start, smb_request_t *, sr,
 155             smb_rw_param_t *, param);
 156 
 157         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 158 }
 159 
 160 void
 161 smb_post_write_and_close(smb_request_t *sr)
 162 {
 163         DTRACE_SMB_2(op__WriteAndClose__done, smb_request_t *, sr,
 164             smb_rw_param_t *, sr->arg.rw);
 165 
 166         kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
 167 }
 168 
 169 smb_sdrc_t
 170 smb_com_write_and_close(smb_request_t *sr)
 171 {
 172         smb_rw_param_t *param = sr->arg.rw;
 173         uint16_t count;
 174         int rc = 0;
 175 
 176         smbsr_lookup_file(sr);
 177         if (sr->fid_ofile == NULL) {
 178                 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
 179                 return (SDRC_ERROR);
 180         }
 181 
 182         sr->user_cr = smb_ofile_getcred(sr->fid_ofile);
 183 
 184         if (param->rw_count == 0) {


 232  * server encountered a resource issue.
 233  */
 234 smb_sdrc_t
 235 smb_pre_write_and_unlock(smb_request_t *sr)
 236 {
 237         smb_rw_param_t *param;
 238         uint32_t off;
 239         uint16_t count;
 240         uint16_t remcnt;
 241         int rc;
 242 
 243         param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
 244         sr->arg.rw = param;
 245         param->rw_magic = SMB_RW_MAGIC;
 246 
 247         rc = smbsr_decode_vwv(sr, "wwlw", &sr->smb_fid, &count, &off, &remcnt);
 248 
 249         param->rw_count = (uint32_t)count;
 250         param->rw_offset = (uint64_t)off;
 251 
 252         DTRACE_SMB_2(op__WriteAndUnlock__start, smb_request_t *, sr,
 253             smb_rw_param_t *, param);
 254 
 255         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 256 }
 257 
 258 void
 259 smb_post_write_and_unlock(smb_request_t *sr)
 260 {
 261         DTRACE_SMB_2(op__WriteAndUnlock__done, smb_request_t *, sr,
 262             smb_rw_param_t *, sr->arg.rw);
 263 
 264         kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
 265 }
 266 
 267 smb_sdrc_t
 268 smb_com_write_and_unlock(smb_request_t *sr)
 269 {
 270         smb_rw_param_t *param = sr->arg.rw;
 271         uint32_t lk_pid;
 272         uint32_t status;
 273         int rc = 0;
 274 
 275         if (STYPE_ISDSK(sr->tid_tree->t_res_type) == 0) {
 276                 smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
 277                 return (SDRC_ERROR);
 278         }
 279 
 280         smbsr_lookup_file(sr);
 281         if (sr->fid_ofile == NULL) {
 282                 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);


 308         }
 309 
 310 
 311         /* Note: SMB1 locking uses 16-bit PIDs. */
 312         lk_pid = sr->smb_pid & 0xFFFF;
 313 
 314         status = smb_unlock_range(sr, param->rw_offset,
 315             (uint64_t)param->rw_count, lk_pid);
 316         if (status != NT_STATUS_SUCCESS) {
 317                 smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
 318                     ERRDOS, ERROR_NOT_LOCKED);
 319                 return (SDRC_ERROR);
 320         }
 321 
 322         rc = smbsr_encode_result(sr, 1, 0, "bww", 1,
 323             (uint16_t)param->rw_count, 0);
 324         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 325 }
 326 
 327 /*




























































 328  * Write bytes to a file (SMB Core).  This request was extended in
 329  * LM 0.12 to support 64-bit offsets, indicated by sending a wct of
 330  * 14, instead of 12, and including additional offset information.
 331  *
 332  * A ByteCount of 0 does not truncate the file - use SMB_COM_WRITE
 333  * to truncate a file.  A zero length merely transfers zero bytes.
 334  *
 335  * If bit 0 of WriteMode is set, Fid must refer to a disk file and
 336  * the data must be on stable storage before responding.
 337  *
 338  * MS-SMB 3.3.5.8 update to LM 0.12 4.2.5:
 339  * If CAP_LARGE_WRITEX is set, the byte count may be larger than the
 340  * negotiated buffer size and the server is expected to write the
 341  * number of bytes specified.
 342  */
 343 smb_sdrc_t
 344 smb_pre_write_andx(smb_request_t *sr)
 345 {
 346         smb_rw_param_t *param;
 347         uint32_t off_low;


 370 
 371                 if (param->rw_dsoff >= 59)
 372                         param->rw_dsoff -= 59;
 373                 param->rw_offset = (uint64_t)off_low;
 374                 /* off_high not present */
 375         } else {
 376                 rc = -1;
 377         }
 378 
 379         param->rw_count = (uint32_t)datalen_low;
 380 
 381         /*
 382          * Work-around a Win7 bug, where it fails to set the
 383          * CAP_LARGE_WRITEX flag during session setup.  Assume
 384          * a large write if the data remaining is >= 64k.
 385          */
 386         if ((sr->session->capabilities & CAP_LARGE_WRITEX) != 0 ||
 387             (sr->smb_data.max_bytes > (sr->smb_data.chain_offset + 0xFFFF)))
 388                 param->rw_count |= ((uint32_t)datalen_high << 16);
 389 
 390         DTRACE_SMB_2(op__WriteX__start, smb_request_t *, sr,
 391             smb_rw_param_t *, param);
 392 
 393         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 394 }
 395 
 396 void
 397 smb_post_write_andx(smb_request_t *sr)
 398 {
 399         DTRACE_SMB_2(op__WriteX__done, smb_request_t *, sr,
 400             smb_rw_param_t *, sr->arg.rw);
 401 
 402         kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
 403 }
 404 
 405 smb_sdrc_t
 406 smb_com_write_andx(smb_request_t *sr)
 407 {
 408         smb_rw_param_t *param = sr->arg.rw;
 409         uint16_t count_high;
 410         uint16_t count_low;
 411         int rc;
 412 
 413         ASSERT(param);
 414         ASSERT(param->rw_magic == SMB_RW_MAGIC);
 415 
 416         smbsr_lookup_file(sr);
 417         if (sr->fid_ofile == NULL) {
 418                 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
 419                 return (SDRC_ERROR);
 420         }




  44  * server encountered a resource issue.
  45  */
  46 smb_sdrc_t
  47 smb_pre_write(smb_request_t *sr)
  48 {
  49         smb_rw_param_t *param;
  50         uint32_t off;
  51         uint16_t count;
  52         int rc;
  53 
  54         param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
  55         sr->arg.rw = param;
  56         param->rw_magic = SMB_RW_MAGIC;
  57 
  58         rc = smbsr_decode_vwv(sr, "wwl", &sr->smb_fid, &count, &off);
  59 
  60         param->rw_count = (uint32_t)count;
  61         param->rw_offset = (uint64_t)off;
  62         param->rw_vdb.vdb_uio.uio_loffset = (offset_t)param->rw_offset;
  63 
  64         DTRACE_SMB_1(op__Write__start, smb_request_t *, sr); /* arg.rw */

  65 
  66         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
  67 }
  68 
  69 void
  70 smb_post_write(smb_request_t *sr)
  71 {
  72         DTRACE_SMB_1(op__Write__done, smb_request_t *, sr); /* arg.rw */

  73 
  74         kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
  75 }
  76 
  77 smb_sdrc_t
  78 smb_com_write(smb_request_t *sr)
  79 {
  80         smb_rw_param_t *param = sr->arg.rw;
  81         int rc;
  82 
  83         smbsr_lookup_file(sr);
  84         if (sr->fid_ofile == NULL) {
  85                 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
  86                 return (SDRC_ERROR);
  87         }
  88 
  89         sr->user_cr = smb_ofile_getcred(sr->fid_ofile);
  90 
  91         if (param->rw_count == 0) {
  92                 rc = smb_write_truncate(sr, param);


 132         smb_rw_param_t *param;
 133         uint32_t off;
 134         uint16_t count;
 135         int rc;
 136 
 137         param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
 138         sr->arg.rw = param;
 139         param->rw_magic = SMB_RW_MAGIC;
 140 
 141         if (sr->smb_wct == 12) {
 142                 rc = smbsr_decode_vwv(sr, "wwll12.", &sr->smb_fid,
 143                     &count, &off, &param->rw_last_write);
 144         } else {
 145                 rc = smbsr_decode_vwv(sr, "wwll", &sr->smb_fid,
 146                     &count, &off, &param->rw_last_write);
 147         }
 148 
 149         param->rw_count = (uint32_t)count;
 150         param->rw_offset = (uint64_t)off;
 151 
 152         DTRACE_SMB_1(op__WriteAndClose__start, smb_request_t *, sr); /* arg.rw */

 153 
 154         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 155 }
 156 
 157 void
 158 smb_post_write_and_close(smb_request_t *sr)
 159 {
 160         DTRACE_SMB_1(op__WriteAndClose__done, smb_request_t *, sr); /* arg.rw */

 161 
 162         kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
 163 }
 164 
 165 smb_sdrc_t
 166 smb_com_write_and_close(smb_request_t *sr)
 167 {
 168         smb_rw_param_t *param = sr->arg.rw;
 169         uint16_t count;
 170         int rc = 0;
 171 
 172         smbsr_lookup_file(sr);
 173         if (sr->fid_ofile == NULL) {
 174                 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
 175                 return (SDRC_ERROR);
 176         }
 177 
 178         sr->user_cr = smb_ofile_getcred(sr->fid_ofile);
 179 
 180         if (param->rw_count == 0) {


 228  * server encountered a resource issue.
 229  */
 230 smb_sdrc_t
 231 smb_pre_write_and_unlock(smb_request_t *sr)
 232 {
 233         smb_rw_param_t *param;
 234         uint32_t off;
 235         uint16_t count;
 236         uint16_t remcnt;
 237         int rc;
 238 
 239         param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
 240         sr->arg.rw = param;
 241         param->rw_magic = SMB_RW_MAGIC;
 242 
 243         rc = smbsr_decode_vwv(sr, "wwlw", &sr->smb_fid, &count, &off, &remcnt);
 244 
 245         param->rw_count = (uint32_t)count;
 246         param->rw_offset = (uint64_t)off;
 247 
 248         DTRACE_SMB_1(op__WriteAndUnlock__start, smb_request_t *, sr); /* arg.rw */

 249 
 250         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 251 }
 252 
 253 void
 254 smb_post_write_and_unlock(smb_request_t *sr)
 255 {
 256         DTRACE_SMB_1(op__WriteAndUnlock__done, smb_request_t *, sr); /* arg.rw */

 257 
 258         kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
 259 }
 260 
 261 smb_sdrc_t
 262 smb_com_write_and_unlock(smb_request_t *sr)
 263 {
 264         smb_rw_param_t *param = sr->arg.rw;
 265         uint32_t lk_pid;
 266         uint32_t status;
 267         int rc = 0;
 268 
 269         if (STYPE_ISDSK(sr->tid_tree->t_res_type) == 0) {
 270                 smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS, ERRnoaccess);
 271                 return (SDRC_ERROR);
 272         }
 273 
 274         smbsr_lookup_file(sr);
 275         if (sr->fid_ofile == NULL) {
 276                 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);


 302         }
 303 
 304 
 305         /* Note: SMB1 locking uses 16-bit PIDs. */
 306         lk_pid = sr->smb_pid & 0xFFFF;
 307 
 308         status = smb_unlock_range(sr, param->rw_offset,
 309             (uint64_t)param->rw_count, lk_pid);
 310         if (status != NT_STATUS_SUCCESS) {
 311                 smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
 312                     ERRDOS, ERROR_NOT_LOCKED);
 313                 return (SDRC_ERROR);
 314         }
 315 
 316         rc = smbsr_encode_result(sr, 1, 0, "bww", 1,
 317             (uint16_t)param->rw_count, 0);
 318         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 319 }
 320 
 321 /*
 322  * The SMB_COM_WRITE_RAW protocol was a negotiated option introduced in
 323  * SMB Core Plus to maximize performance when writing a large block
 324  * of data to a server.  It's obsolete and no longer supported.
 325  *
 326  * We keep a handler for it so the dtrace provider can see if
 327  * the client tried to use this command.
 328  */
 329 smb_sdrc_t
 330 smb_pre_write_raw(smb_request_t *sr)
 331 {
 332         smb_rw_param_t *param;
 333         uint32_t off_low;
 334         uint32_t timeout;
 335         uint32_t off_high;
 336         uint16_t datalen;
 337         uint16_t total;
 338         int rc;
 339 
 340         param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP);
 341         sr->arg.rw = param;
 342 
 343         if (sr->smb_wct == 12) {
 344                 rc = smbsr_decode_vwv(sr, "ww2.llw4.ww", &sr->smb_fid, &total,
 345                     &off_low, &timeout, &param->rw_mode, &datalen,
 346                     &param->rw_dsoff);
 347 
 348                 param->rw_offset = (uint64_t)off_low;
 349         } else {
 350                 rc = smbsr_decode_vwv(sr, "ww2.llw4.wwl", &sr->smb_fid, &total,
 351                     &off_low, &timeout, &param->rw_mode, &datalen,
 352                     &param->rw_dsoff, &off_high);
 353 
 354                 param->rw_offset = ((uint64_t)off_high << 32) | off_low;
 355         }
 356 
 357         param->rw_count = (uint32_t)datalen;
 358         param->rw_total = (uint32_t)total;
 359 
 360         DTRACE_SMB_1(op__WriteRaw__start, smb_request_t *, sr); /* arg.rw */
 361 
 362         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 363 }
 364 
 365 void
 366 smb_post_write_raw(smb_request_t *sr)
 367 {
 368         DTRACE_SMB_1(op__WriteRaw__done, smb_request_t *, sr); /* arg.rw */
 369 
 370         kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
 371 }
 372 
 373 smb_sdrc_t
 374 smb_com_write_raw(struct smb_request *sr)
 375 {
 376         smbsr_error(sr, NT_STATUS_NOT_SUPPORTED, ERRDOS,
 377             ERROR_NOT_SUPPORTED);
 378         return (SDRC_ERROR);
 379 }
 380 
 381 /*
 382  * Write bytes to a file (SMB Core).  This request was extended in
 383  * LM 0.12 to support 64-bit offsets, indicated by sending a wct of
 384  * 14, instead of 12, and including additional offset information.
 385  *
 386  * A ByteCount of 0 does not truncate the file - use SMB_COM_WRITE
 387  * to truncate a file.  A zero length merely transfers zero bytes.
 388  *
 389  * If bit 0 of WriteMode is set, Fid must refer to a disk file and
 390  * the data must be on stable storage before responding.
 391  *
 392  * MS-SMB 3.3.5.8 update to LM 0.12 4.2.5:
 393  * If CAP_LARGE_WRITEX is set, the byte count may be larger than the
 394  * negotiated buffer size and the server is expected to write the
 395  * number of bytes specified.
 396  */
 397 smb_sdrc_t
 398 smb_pre_write_andx(smb_request_t *sr)
 399 {
 400         smb_rw_param_t *param;
 401         uint32_t off_low;


 424 
 425                 if (param->rw_dsoff >= 59)
 426                         param->rw_dsoff -= 59;
 427                 param->rw_offset = (uint64_t)off_low;
 428                 /* off_high not present */
 429         } else {
 430                 rc = -1;
 431         }
 432 
 433         param->rw_count = (uint32_t)datalen_low;
 434 
 435         /*
 436          * Work-around a Win7 bug, where it fails to set the
 437          * CAP_LARGE_WRITEX flag during session setup.  Assume
 438          * a large write if the data remaining is >= 64k.
 439          */
 440         if ((sr->session->capabilities & CAP_LARGE_WRITEX) != 0 ||
 441             (sr->smb_data.max_bytes > (sr->smb_data.chain_offset + 0xFFFF)))
 442                 param->rw_count |= ((uint32_t)datalen_high << 16);
 443 
 444         DTRACE_SMB_1(op__WriteX__start, smb_request_t *, sr); /* arg.rw */

 445 
 446         return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
 447 }
 448 
 449 void
 450 smb_post_write_andx(smb_request_t *sr)
 451 {
 452         DTRACE_SMB_1(op__WriteX__done, smb_request_t *, sr); /* arg.rw */

 453 
 454         kmem_free(sr->arg.rw, sizeof (smb_rw_param_t));
 455 }
 456 
 457 smb_sdrc_t
 458 smb_com_write_andx(smb_request_t *sr)
 459 {
 460         smb_rw_param_t *param = sr->arg.rw;
 461         uint16_t count_high;
 462         uint16_t count_low;
 463         int rc;
 464 
 465         ASSERT(param);
 466         ASSERT(param->rw_magic == SMB_RW_MAGIC);
 467 
 468         smbsr_lookup_file(sr);
 469         if (sr->fid_ofile == NULL) {
 470                 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
 471                 return (SDRC_ERROR);
 472         }