1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright 2017 Nexenta Systems, Inc. All rights reserved. 25 */ 26 27 /* 28 * Translate Unix errno values to NT status, and NT status to 29 * DOS-style error class+code (for SMB1) 30 */ 31 32 #include <smbsrv/smb_kproto.h> 33 #include <smbsrv/smb_kstat.h> 34 35 #include "smbclnt/smb_status2winerr.h" 36 37 38 /* 39 * Map Unix errno values to NT status values. 40 */ 41 42 struct errno2status { 43 int errnum; 44 uint_t status; 45 }; 46 47 static const struct errno2status 48 smb_errno2status_map[] = { 49 { EPERM, NT_STATUS_ACCESS_DENIED }, 50 { ENOENT, NT_STATUS_OBJECT_NAME_NOT_FOUND }, 51 /* NB: ESRCH is used in rename and stream ops. */ 52 { ESRCH, NT_STATUS_NO_SUCH_FILE }, 53 { EINTR, NT_STATUS_CANCELLED }, 54 { EIO, NT_STATUS_IO_DEVICE_ERROR }, 55 { ENXIO, NT_STATUS_BAD_DEVICE_TYPE }, 56 /* E2BIG, ENOEXEC */ 57 { EBADF, NT_STATUS_INVALID_HANDLE }, 58 /* ECHILD, EAGAIN */ 59 { ENOMEM, NT_STATUS_NO_MEMORY }, 60 { EACCES, NT_STATUS_ACCESS_DENIED }, 61 /* EFAULT, ENOTBLK, EBUSY */ 62 { EEXIST, NT_STATUS_OBJECT_NAME_COLLISION }, 63 { EXDEV, NT_STATUS_NOT_SAME_DEVICE }, 64 { ENODEV, NT_STATUS_NO_SUCH_DEVICE }, 65 { ENOTDIR, NT_STATUS_OBJECT_PATH_NOT_FOUND }, 66 { EISDIR, NT_STATUS_FILE_IS_A_DIRECTORY }, 67 { EINVAL, NT_STATUS_INVALID_PARAMETER }, 68 { ENFILE, NT_STATUS_TOO_MANY_OPENED_FILES }, 69 { EMFILE, NT_STATUS_TOO_MANY_OPENED_FILES }, 70 { ENOTTY, NT_STATUS_INVALID_DEVICE_REQUEST }, 71 /* ENOTTY, ETXTBSY, EFBIG */ 72 { ENOSPC, NT_STATUS_DISK_FULL }, 73 /* ESPIPE */ 74 { EROFS, NT_STATUS_ACCESS_DENIED }, 75 { EMLINK, NT_STATUS_TOO_MANY_LINKS }, 76 { EPIPE, NT_STATUS_PIPE_BROKEN }, 77 /* EDOM */ 78 /* NB: ERANGE is used to represent lock range I/O conflicts. */ 79 { ERANGE, NT_STATUS_FILE_LOCK_CONFLICT }, 80 /* ENOMSG, EIDRM, ... */ 81 { ENOTSUP, NT_STATUS_NOT_SUPPORTED }, 82 { EDQUOT, NT_STATUS_DISK_FULL }, 83 { EREMOTE, NT_STATUS_PATH_NOT_COVERED}, 84 { ENAMETOOLONG, NT_STATUS_OBJECT_NAME_INVALID }, 85 { EILSEQ, NT_STATUS_OBJECT_NAME_INVALID }, 86 { ENOTEMPTY, NT_STATUS_DIRECTORY_NOT_EMPTY }, 87 { ENOTSOCK, NT_STATUS_INVALID_HANDLE }, 88 { ESTALE, NT_STATUS_INVALID_HANDLE }, 89 { 0, 0 } 90 }; 91 92 uint_t 93 smb_errno2status(int errnum) 94 { 95 const struct errno2status *es; 96 97 if (errnum == 0) 98 return (0); 99 100 for (es = smb_errno2status_map; es->errnum != 0; es++) 101 if (es->errnum == errnum) 102 return (es->status); 103 104 return (NT_STATUS_INTERNAL_ERROR); 105 } 106 107 /* 108 * Map NT Status codes to Win32 API error numbers. 109 * But note: we only want the ones below 0xFFFF, 110 * which can be returned in SMB with class=DOSERR. 111 */ 112 uint16_t 113 smb_status2doserr(uint_t status) 114 { 115 const struct status2winerr *sw; 116 117 if (status == 0) 118 return (0); 119 120 for (sw = smb_status2winerr_map; sw->status != 0; sw++) 121 if (sw->status == status && (sw->winerr < 0xFFFF)) 122 return ((uint16_t)sw->winerr); 123 124 return (ERROR_GEN_FAILURE); 125 } 126