void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) { int flgs2; if(!cli->initialised) { return; } /* Deal with socket errors first. */ if (cli->fd == -1 && cli->smb_rw_error) { NTSTATUS status = cli_smb_rw_error_to_ntstatus(cli); ntstatus_to_dos( status, eclass, ecode); return; } flgs2 = SVAL(cli->inbuf,smb_flg2); if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { NTSTATUS ntstatus = NT_STATUS(IVAL(cli->inbuf, smb_rcls)); ntstatus_to_dos(ntstatus, eclass, ecode); return; } *eclass = CVAL(cli->inbuf,smb_rcls); *ecode = SVAL(cli->inbuf,smb_err); }
void set_saved_ntstatus(NTSTATUS status) { uint8 tmp_eclass; /* Hmmm. override_ERR_class is not uint8... */ override_ERR_ntstatus = status; ntstatus_to_dos(status, &tmp_eclass, &override_ERR_code); override_ERR_class = tmp_eclass; }
int error_packet(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file) { int outsize = set_message(outbuf,0,0,True); BOOL force_nt_status = False; BOOL force_dos_status = False; if (override_ERR_class != SMB_SUCCESS || !NT_STATUS_IS_OK(override_ERR_ntstatus)) { eclass = override_ERR_class; ecode = override_ERR_code; ntstatus = override_ERR_ntstatus; override_ERR_class = SMB_SUCCESS; override_ERR_code = 0; override_ERR_ntstatus = NT_STATUS_OK; } if (eclass == (uint8)-1) { force_nt_status = True; } else if (NT_STATUS_IS_INVALID(ntstatus)) { force_dos_status = True; } if (force_nt_status || (!force_dos_status && lp_nt_status_support() && (global_client_caps & CAP_STATUS32))) { /* We're returning an NT error. */ if (NT_STATUS_V(ntstatus) == 0 && eclass) { ntstatus = dos_to_ntstatus(eclass, ecode); } SIVAL(outbuf,smb_rcls,NT_STATUS_V(ntstatus)); SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2)|FLAGS2_32_BIT_ERROR_CODES); DEBUG(3,("error packet at %s(%d) cmd=%d (%s) %s\n", file, line, (int)CVAL(outbuf,smb_com), smb_fn_name(CVAL(outbuf,smb_com)), nt_errstr(ntstatus))); } else { /* We're returning a DOS error only. */ if (eclass == 0 && NT_STATUS_V(ntstatus)) { ntstatus_to_dos(ntstatus, &eclass, &ecode); } SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2)&~FLAGS2_32_BIT_ERROR_CODES); SSVAL(outbuf,smb_rcls,eclass); SSVAL(outbuf,smb_err,ecode); DEBUG(3,("error packet at %s(%d) cmd=%d (%s) eclass=%d ecode=%d\n", file, line, (int)CVAL(outbuf,smb_com), smb_fn_name(CVAL(outbuf,smb_com)), eclass, ecode)); } return outsize; }
void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) { if (!cli_state_is_connected(cli)) { *eclass = ERRDOS; *ecode = ERRnotconnected; return; } if (!NT_STATUS_IS_DOS(cli->raw_status)) { ntstatus_to_dos(cli->raw_status, eclass, ecode); return; } *eclass = NT_STATUS_DOS_CLASS(cli->raw_status); *ecode = NT_STATUS_DOS_CODE(cli->raw_status); }
void error_packet_set(char *outbuf, uint8 eclass, uint32 ecode, NTSTATUS ntstatus, int line, const char *file) { BOOL force_nt_status = False; BOOL force_dos_status = False; if (eclass == (uint8)-1) { force_nt_status = True; } else if (NT_STATUS_IS_DOS(ntstatus)) { force_dos_status = True; } if (force_nt_status || (!force_dos_status && lp_nt_status_support() && (global_client_caps & CAP_STATUS32))) { /* We're returning an NT error. */ if (NT_STATUS_V(ntstatus) == 0 && eclass) { ntstatus = dos_to_ntstatus(eclass, ecode); } SIVAL(outbuf,smb_rcls,NT_STATUS_V(ntstatus)); SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2)|FLAGS2_32_BIT_ERROR_CODES); DEBUG(3,("error packet at %s(%d) cmd=%d (%s) %s\n", file, line, (int)CVAL(outbuf,smb_com), smb_fn_name(CVAL(outbuf,smb_com)), nt_errstr(ntstatus))); } else { /* We're returning a DOS error only. */ if (NT_STATUS_IS_DOS(ntstatus)) { eclass = NT_STATUS_DOS_CLASS(ntstatus); ecode = NT_STATUS_DOS_CODE(ntstatus); } else if (eclass == 0 && NT_STATUS_V(ntstatus)) { ntstatus_to_dos(ntstatus, &eclass, &ecode); } SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2)&~FLAGS2_32_BIT_ERROR_CODES); SSVAL(outbuf,smb_rcls,eclass); SSVAL(outbuf,smb_err,ecode); DEBUG(3,("error packet at %s(%d) cmd=%d (%s) eclass=%d ecode=%d\n", file, line, (int)CVAL(outbuf,smb_com), smb_fn_name(CVAL(outbuf,smb_com)), eclass, ecode)); } }
/* setup the header of a reply to include an NTSTATUS code */ void smbsrv_setup_error(struct smbsrv_request *req, NTSTATUS status) { if (!req->smb_conn->config.nt_status_support || !(req->smb_conn->negotiate.client_caps & CAP_STATUS32)) { /* convert to DOS error codes */ uint8_t eclass; uint32_t ecode; ntstatus_to_dos(status, &eclass, &ecode); SCVAL(req->out.hdr, HDR_RCLS, eclass); SSVAL(req->out.hdr, HDR_ERR, ecode); SSVAL(req->out.hdr, HDR_FLG2, SVAL(req->out.hdr, HDR_FLG2) & ~FLAGS2_32_BIT_ERROR_CODES); return; } if (NT_STATUS_IS_DOS(status)) { /* its a encoded DOS error, using the reserved range */ SSVAL(req->out.hdr, HDR_RCLS, NT_STATUS_DOS_CLASS(status)); SSVAL(req->out.hdr, HDR_ERR, NT_STATUS_DOS_CODE(status)); SSVAL(req->out.hdr, HDR_FLG2, SVAL(req->out.hdr, HDR_FLG2) & ~FLAGS2_32_BIT_ERROR_CODES); } else { SIVAL(req->out.hdr, HDR_RCLS, NT_STATUS_V(status)); SSVAL(req->out.hdr, HDR_FLG2, SVAL(req->out.hdr, HDR_FLG2) | FLAGS2_32_BIT_ERROR_CODES); } }
int map_smb_to_linux_error(struct smb_hdr *smb, int logErr) { unsigned int i; int rc = -EIO; /* if transport error smb error may not be set */ __u8 smberrclass; __u16 smberrcode; /* BB if NT Status codes - map NT BB */ /* old style smb error codes */ if (smb->Status.CifsError == 0) return 0; if (smb->Flags2 & SMBFLG2_ERR_STATUS) { /* translate the newer STATUS codes to old style SMB errors * and then to POSIX errors */ __u32 err = le32_to_cpu(smb->Status.CifsError); if (logErr && (err != (NT_STATUS_MORE_PROCESSING_REQUIRED))) cifs_print_status(err); else if (cifsFYI & CIFS_RC) cifs_print_status(err); ntstatus_to_dos(err, &smberrclass, &smberrcode); } else { smberrclass = smb->Status.DosError.ErrorClass; smberrcode = le16_to_cpu(smb->Status.DosError.Error); } /* old style errors */ /* DOS class smb error codes - map DOS */ if (smberrclass == ERRDOS) { /* 1 byte field no need to byte reverse */ for (i = 0; i < sizeof(mapping_table_ERRDOS) / sizeof(struct smb_to_posix_error); i++) { if (mapping_table_ERRDOS[i].smb_err == 0) break; else if (mapping_table_ERRDOS[i].smb_err == smberrcode) { rc = mapping_table_ERRDOS[i].posix_code; break; } /* else try next error mapping one to see if match */ } } else if (smberrclass == ERRSRV) { /* server class of error codes */ for (i = 0; i < sizeof(mapping_table_ERRSRV) / sizeof(struct smb_to_posix_error); i++) { if (mapping_table_ERRSRV[i].smb_err == 0) break; else if (mapping_table_ERRSRV[i].smb_err == smberrcode) { rc = mapping_table_ERRSRV[i].posix_code; break; } /* else try next error mapping to see if match */ } } /* else ERRHRD class errors or junk - return EIO */ cFYI(1, "Mapping smb error code %d to POSIX err %d", smberrcode, rc); /* generic corrective action e.g. reconnect SMB session on * ERRbaduid could be added */ return rc; }