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 2014 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_NO_SUCH_FILE }, 51 /* NB: ESRCH is used to represent stream lookup failures. */ 52 { ESRCH, NT_STATUS_OBJECT_NAME_NOT_FOUND }, 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 should be: NT_STATUS_NOT_A_DIRECTORY, but not yet */ 66 { ENOTDIR, NT_STATUS_OBJECT_PATH_NOT_FOUND }, 67 { EISDIR, NT_STATUS_FILE_IS_A_DIRECTORY }, 68 { EINVAL, NT_STATUS_INVALID_PARAMETER }, 69 { ENFILE, NT_STATUS_TOO_MANY_OPENED_FILES }, 70 { EMFILE, NT_STATUS_TOO_MANY_OPENED_FILES }, 71 { ENOTTY, NT_STATUS_INVALID_DEVICE_REQUEST }, 72 /* ENOTTY, ETXTBSY, EFBIG */ 73 { ENOSPC, NT_STATUS_DISK_FULL }, 74 /* ESPIPE */ 75 { EROFS, NT_STATUS_ACCESS_DENIED }, 76 { EMLINK, NT_STATUS_TOO_MANY_LINKS }, 77 { EPIPE, NT_STATUS_PIPE_BROKEN }, 78 /* EDOM */ 79 /* NB: ERANGE is used to represent lock range I/O conflicts. */ 80 { ERANGE, NT_STATUS_FILE_LOCK_CONFLICT }, 81 /* ENOMSG, EIDRM, ... */ 82 { ENOTSUP, NT_STATUS_NOT_SUPPORTED }, 83 { EDQUOT, NT_STATUS_DISK_FULL }, 84 { EREMOTE, NT_STATUS_PATH_NOT_COVERED}, 85 { ENAMETOOLONG, NT_STATUS_OBJECT_NAME_INVALID }, 86 { EILSEQ, NT_STATUS_OBJECT_NAME_INVALID }, 87 { ENOTEMPTY, NT_STATUS_DIRECTORY_NOT_EMPTY }, 88 { ENOTSOCK, NT_STATUS_INVALID_HANDLE }, 89 { ESTALE, NT_STATUS_INVALID_HANDLE }, 90 { 0, 0 } 91 }; 92 93 uint_t 94 smb_errno2status(int errnum) 95 { 96 const struct errno2status *es; 97 98 if (errnum == 0) 99 return (0); 100 101 for (es = smb_errno2status_map; es->errnum != 0; es++) 102 if (es->errnum == errnum) 103 return (es->status); 104 105 return (NT_STATUS_INTERNAL_ERROR); 106 } 107 108 /* 109 * Map NT Status codes to Win32 API error numbers. 110 * But note: we only want the ones below 0xFFFF, 111 * which can be returned in SMB with class=DOSERR. 112 */ 113 uint16_t 114 smb_status2doserr(uint_t status) 115 { 116 const struct status2winerr *sw; 117 118 if (status == 0) 119 return (0); 120 121 for (sw = smb_status2winerr_map; sw->status != 0; sw++) 122 if (sw->status == status && (sw->winerr < 0xFFFF)) 123 return ((uint16_t)sw->winerr); 124 125 return (ERROR_GEN_FAILURE); 126 } 127