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