/* 
 *  Unix SMB/CIFS implementation.
 *  error mapping functions
 *  Copyright (C) Andrew Tridgell 2001
 *  Copyright (C) Andrew Bartlett 2001
 *  Copyright (C) Tim Potter 2000
 *  
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "includes.h"

#if HAVE_GSSAPI_GSSAPI_H
#include <gssapi/gssapi.h>
#elif HAVE_GSSAPI_GSSAPI_GENERIC_H
#include <gssapi/gssapi_generic.h>
#elif HAVE_GSSAPI_H
#include <gssapi.h>
#endif

/* dos -> nt status error map */
static const struct {
	uint8 dos_class;
	uint32 dos_code;
	NTSTATUS ntstatus;
} dos_to_ntstatus_map[] = {
	{ERRDOS,	ERRbadfunc,	NT_STATUS_NOT_IMPLEMENTED},
	{ERRDOS,	ERRbadfile,	NT_STATUS_NO_SUCH_FILE},
	{ERRDOS,	ERRbadpath,	NT_STATUS_OBJECT_PATH_NOT_FOUND},
	{ERRDOS,	ERRnofids,	NT_STATUS_TOO_MANY_OPENED_FILES},
	{ERRDOS,	ERRnoaccess,	NT_STATUS_ACCESS_DENIED},
	{ERRDOS,	ERRbadfid,	NT_STATUS_INVALID_HANDLE},
	{ERRDOS,	ERRnomem,	NT_STATUS_INSUFFICIENT_RESOURCES},
	{ERRDOS,	ERRbadaccess,	NT_STATUS_ACCESS_DENIED},
	{ERRDOS,	ERRbaddata,	NT_STATUS_DATA_ERROR},
	{ERRDOS,	14,	NT_STATUS_SECTION_NOT_EXTENDED},
	{ERRDOS,	ERRremcd,	NT_STATUS_DIRECTORY_NOT_EMPTY},
	{ERRDOS,	ERRdiffdevice,	NT_STATUS_NOT_SAME_DEVICE},
	{ERRDOS,	ERRnofiles,	STATUS_NO_MORE_FILES},
	{ERRDOS,	19,	NT_STATUS_MEDIA_WRITE_PROTECTED},
	{ERRDOS,	21,	NT_STATUS_NO_MEDIA_IN_DEVICE},
	{ERRDOS,	22,	NT_STATUS_INVALID_DEVICE_STATE},
	{ERRDOS,	23,	NT_STATUS_DATA_ERROR},
	{ERRDOS,	24,	NT_STATUS_DATA_ERROR},
	{ERRDOS,	26,	NT_STATUS_DISK_CORRUPT_ERROR},
	{ERRDOS,	27,	NT_STATUS_NONEXISTENT_SECTOR},
	{ERRDOS,	28,	NT_STATUS(0x8000000e)},
	{ERRDOS,	31,	NT_STATUS_UNSUCCESSFUL},
	{ERRDOS,	ERRbadshare,	NT_STATUS_SHARING_VIOLATION},
	{ERRDOS,	ERRlock,	NT_STATUS_FILE_LOCK_CONFLICT},
	{ERRDOS,	34,	NT_STATUS_WRONG_VOLUME},
	{ERRDOS,	38,	NT_STATUS_END_OF_FILE},
	{ERRDOS,	ERRunsup,	NT_STATUS_CTL_FILE_NOT_SUPPORTED},
	{ERRDOS,	51,	NT_STATUS_REMOTE_NOT_LISTENING},
	{ERRDOS,	52,	NT_STATUS_DUPLICATE_NAME},
	{ERRDOS,	53,	NT_STATUS_BAD_NETWORK_PATH},
	{ERRDOS,	54,	NT_STATUS_NETWORK_BUSY},
	{ERRDOS,	55,	NT_STATUS_DEVICE_DOES_NOT_EXIST},
	{ERRDOS,	56,	NT_STATUS_TOO_MANY_COMMANDS},
	{ERRDOS,	57,	NT_STATUS_ADAPTER_HARDWARE_ERROR},
	{ERRDOS,	58,	NT_STATUS_INVALID_NETWORK_RESPONSE},
	{ERRDOS,	59,	NT_STATUS_UNEXPECTED_NETWORK_ERROR},
	{ERRDOS,	60,	NT_STATUS_BAD_REMOTE_ADAPTER},
	{ERRDOS,	61,	NT_STATUS_PRINT_QUEUE_FULL},
	{ERRDOS,	62,	NT_STATUS_NO_SPOOL_SPACE},
	{ERRDOS,	63,	NT_STATUS_PRINT_CANCELLED},
	{ERRDOS,	64,	NT_STATUS_NETWORK_NAME_DELETED},
	{ERRDOS,	65,	NT_STATUS_NETWORK_ACCESS_DENIED},
	{ERRDOS,	66,	NT_STATUS_BAD_DEVICE_TYPE},
	{ERRDOS,	ERRnosuchshare,	NT_STATUS_BAD_NETWORK_NAME},
	{ERRDOS,	68,	NT_STATUS_TOO_MANY_GUIDS_REQUESTED},
	{ERRDOS,	69,	NT_STATUS_TOO_MANY_SESSIONS},
	{ERRDOS,	70,	NT_STATUS_SHARING_PAUSED},
	{ERRDOS,	71,	NT_STATUS_REQUEST_NOT_ACCEPTED},
	{ERRDOS,	72,	NT_STATUS_REDIRECTOR_PAUSED},
	{ERRDOS,	ERRfilexists,	NT_STATUS_OBJECT_NAME_COLLISION},
	{ERRDOS,	86,	NT_STATUS_WRONG_PASSWORD},
	{ERRDOS,	87,	NT_STATUS_INVALID_INFO_CLASS},
	{ERRDOS,	88,	NT_STATUS_NET_WRITE_FAULT},
	{ERRDOS,	109,	NT_STATUS_PIPE_BROKEN},
	{ERRDOS,	111,	STATUS_MORE_ENTRIES},
	{ERRDOS,	112,	NT_STATUS_DISK_FULL},
	{ERRDOS,	121,	NT_STATUS_IO_TIMEOUT},
	{ERRDOS,	122,	NT_STATUS_BUFFER_TOO_SMALL},
	{ERRDOS,	ERRinvalidname,	NT_STATUS_OBJECT_NAME_INVALID},
	{ERRDOS,	ERRunknownlevel,	NT_STATUS_INVALID_LEVEL},
	{ERRDOS,	126,	NT_STATUS_DLL_NOT_FOUND},
	{ERRDOS,	127,	NT_STATUS_PROCEDURE_NOT_FOUND},
	{ERRDOS,	145,	NT_STATUS_DIRECTORY_NOT_EMPTY},
	{ERRDOS,	154,	NT_STATUS_INVALID_VOLUME_LABEL},
	{ERRDOS,	156,	NT_STATUS_SUSPEND_COUNT_EXCEEDED},
	{ERRDOS,	158,	NT_STATUS_NOT_LOCKED},
	{ERRDOS,	161,	NT_STATUS_OBJECT_PATH_INVALID},
	{ERRDOS,	170,	NT_STATUS(0x80000011)},
	{ERRDOS,	182,	NT_STATUS_ORDINAL_NOT_FOUND},
	{ERRDOS,	183,	NT_STATUS_OBJECT_NAME_COLLISION},
	{ERRDOS,	193,	NT_STATUS_BAD_INITIAL_PC},
	{ERRDOS,	203,	NT_STATUS(0xc0000100)},
	{ERRDOS,	206,	NT_STATUS_NAME_TOO_LONG},
	{ERRDOS,	ERRbadpipe,	NT_STATUS_INVALID_INFO_CLASS},
	{ERRDOS,	ERRpipebusy,	NT_STATUS_INSTANCE_NOT_AVAILABLE},
	{ERRDOS,	ERRpipeclosing,	NT_STATUS_PIPE_CLOSING},
	{ERRDOS,	ERRnotconnected,	NT_STATUS_PIPE_DISCONNECTED},
	{ERRDOS,	ERRmoredata,	NT_STATUS_MORE_PROCESSING_REQUIRED},
	{ERRDOS,	240,	NT_STATUS_VIRTUAL_CIRCUIT_CLOSED},
	{ERRDOS,	254,	NT_STATUS(0x80000013)},
	{ERRDOS,	255,	NT_STATUS_EA_TOO_LARGE},
	{ERRDOS,	259,	NT_STATUS_GUIDS_EXHAUSTED},
	{ERRDOS,	267,	NT_STATUS_NOT_A_DIRECTORY},
	{ERRDOS,	275,	NT_STATUS_EA_TOO_LARGE},
	{ERRDOS,	276,	NT_STATUS_NONEXISTENT_EA_ENTRY},
	{ERRDOS,	277,	NT_STATUS_NONEXISTENT_EA_ENTRY},
	{ERRDOS,	278,	NT_STATUS_NONEXISTENT_EA_ENTRY},
	{ERRDOS,	ERReasnotsupported,	NT_STATUS_EAS_NOT_SUPPORTED},
	{ERRDOS,	288,	NT_STATUS_MUTANT_NOT_OWNED},
	{ERRDOS,	298,	NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED},
	{ERRDOS,	299,	NT_STATUS(0x8000000d)},
	{ERRDOS,	300,	NT_STATUS_OPLOCK_NOT_GRANTED},
	{ERRDOS,	301,	NT_STATUS_INVALID_OPLOCK_PROTOCOL},
	{ERRDOS,	487,	NT_STATUS_CONFLICTING_ADDRESSES},
	{ERRDOS,	534,	NT_STATUS_INTEGER_OVERFLOW},
	{ERRDOS,	535,	NT_STATUS_PIPE_CONNECTED},
	{ERRDOS,	536,	NT_STATUS_PIPE_LISTENING},
	{ERRDOS,	995,	NT_STATUS_CANCELLED},
	{ERRDOS,	997,	NT_STATUS(0x00000103)},
	{ERRDOS,	998,	NT_STATUS_ACCESS_VIOLATION},
	{ERRDOS,	999,	NT_STATUS_IN_PAGE_ERROR},
	{ERRDOS,	1001,	NT_STATUS_BAD_INITIAL_STACK},
	{ERRDOS,	1005,	NT_STATUS_UNRECOGNIZED_VOLUME},
	{ERRDOS,	1006,	NT_STATUS_FILE_INVALID},
	{ERRDOS,	1007,	NT_STATUS_FULLSCREEN_MODE},
	{ERRDOS,	1008,	NT_STATUS_NO_TOKEN},
	{ERRDOS,	1009,	NT_STATUS_REGISTRY_CORRUPT},
	{ERRDOS,	1016,	NT_STATUS_REGISTRY_IO_FAILED},
	{ERRDOS,	1017,	NT_STATUS_NOT_REGISTRY_FILE},
	{ERRDOS,	1018,	NT_STATUS_KEY_DELETED},
	{ERRDOS,	1019,	NT_STATUS_NO_LOG_SPACE},
	{ERRDOS,	1020,	NT_STATUS_KEY_HAS_CHILDREN},
	{ERRDOS,	1021,	NT_STATUS_CHILD_MUST_BE_VOLATILE},
	{ERRDOS,	1022,	NT_STATUS(0x0000010c)},
	{ERRSRV,	ERRbadpw,	NT_STATUS_WRONG_PASSWORD},
	{ERRSRV,	ERRbaduid,	NT_STATUS_USER_SESSION_DELETED},
	{ERRSRV,	ERRbadtype,	NT_STATUS_BAD_DEVICE_TYPE},
	{ERRSRV,	ERRaccess,	NT_STATUS_NETWORK_ACCESS_DENIED},
	{ERRSRV,	ERRinvnid,	NT_STATUS_NETWORK_NAME_DELETED},
	{ERRSRV,	ERRinvnetname,	NT_STATUS_BAD_NETWORK_NAME},
	{ERRSRV,	ERRinvdevice,	NT_STATUS_BAD_DEVICE_TYPE},
	{ERRSRV,	ERRqfull,	NT_STATUS_PRINT_QUEUE_FULL},
	{ERRSRV,	ERRqtoobig,	NT_STATUS_NO_SPOOL_SPACE},
	{ERRSRV,	ERRinvpfid,	NT_STATUS_PRINT_CANCELLED},
	{ERRSRV,	ERRsmbcmd,	NT_STATUS_NOT_IMPLEMENTED},
	{ERRSRV,	ERRbadpermits,	NT_STATUS_NETWORK_ACCESS_DENIED},
	{ERRSRV,	ERRpaused,	NT_STATUS_SHARING_PAUSED},
	{ERRSRV,	ERRmsgoff,	NT_STATUS_REQUEST_NOT_ACCEPTED},
	{ERRSRV,	ERRnoroom,	NT_STATUS_DISK_FULL},
	{ERRSRV,	ERRnoresource,	NT_STATUS_REQUEST_NOT_ACCEPTED},
	{ERRSRV,	ERRtoomanyuids,	NT_STATUS_TOO_MANY_SESSIONS},
	{ERRSRV,	123,	NT_STATUS_OBJECT_NAME_INVALID},
	{ERRSRV,	206,	NT_STATUS_OBJECT_NAME_INVALID},
	{ERRHRD,	1,	NT_STATUS_NOT_IMPLEMENTED},
	{ERRHRD,	2,	NT_STATUS_NO_SUCH_DEVICE},
	{ERRHRD,	3,	NT_STATUS_OBJECT_PATH_NOT_FOUND},
	{ERRHRD,	4,	NT_STATUS_TOO_MANY_OPENED_FILES},
	{ERRHRD,	5,	NT_STATUS_INVALID_LOCK_SEQUENCE},
	{ERRHRD,	6,	NT_STATUS_INVALID_HANDLE},
	{ERRHRD,	8,	NT_STATUS_INSUFFICIENT_RESOURCES},
	{ERRHRD,	12,	NT_STATUS_INVALID_LOCK_SEQUENCE},
	{ERRHRD,	13,	NT_STATUS_DATA_ERROR},
	{ERRHRD,	14,	NT_STATUS_SECTION_NOT_EXTENDED},
	{ERRHRD,	16,	NT_STATUS_DIRECTORY_NOT_EMPTY},
	{ERRHRD,	17,	NT_STATUS_NOT_SAME_DEVICE},
	{ERRHRD,	18,	NT_STATUS(0x80000006)},
	{ERRHRD,	ERRnowrite,	NT_STATUS_MEDIA_WRITE_PROTECTED},
	{ERRHRD,	ERRnotready,	NT_STATUS_NO_MEDIA_IN_DEVICE},
	{ERRHRD,	ERRbadcmd,	NT_STATUS_INVALID_DEVICE_STATE},
	{ERRHRD,	ERRdata,	NT_STATUS_DATA_ERROR},
	{ERRHRD,	ERRbadreq,	NT_STATUS_DATA_ERROR},
	{ERRHRD,	ERRbadmedia,	NT_STATUS_DISK_CORRUPT_ERROR},
	{ERRHRD,	ERRbadsector,	NT_STATUS_NONEXISTENT_SECTOR},
	{ERRHRD,	ERRnopaper,	NT_STATUS(0x8000000e)},
	{ERRHRD,	ERRgeneral,	NT_STATUS_UNSUCCESSFUL},
	{ERRHRD,	ERRbadshare,	NT_STATUS_SHARING_VIOLATION},
	{ERRHRD,	ERRlock,	NT_STATUS_FILE_LOCK_CONFLICT},
	{ERRHRD,	ERRwrongdisk,	NT_STATUS_WRONG_VOLUME},
	{ERRHRD,	38,	NT_STATUS_END_OF_FILE},
	{ERRHRD,	ERRdiskfull,	NT_STATUS_DISK_FULL},
	{ERRHRD,	50,	NT_STATUS_CTL_FILE_NOT_SUPPORTED},
	{ERRHRD,	51,	NT_STATUS_REMOTE_NOT_LISTENING},
	{ERRHRD,	52,	NT_STATUS_DUPLICATE_NAME},
	{ERRHRD,	53,	NT_STATUS_BAD_NETWORK_PATH},
	{ERRHRD,	54,	NT_STATUS_NETWORK_BUSY},
	{ERRHRD,	55,	NT_STATUS_DEVICE_DOES_NOT_EXIST},
	{ERRHRD,	56,	NT_STATUS_TOO_MANY_COMMANDS},
	{ERRHRD,	57,	NT_STATUS_ADAPTER_HARDWARE_ERROR},
	{ERRHRD,	58,	NT_STATUS_INVALID_NETWORK_RESPONSE},
	{ERRHRD,	59,	NT_STATUS_UNEXPECTED_NETWORK_ERROR},
	{ERRHRD,	60,	NT_STATUS_BAD_REMOTE_ADAPTER},
	{ERRHRD,	61,	NT_STATUS_PRINT_QUEUE_FULL},
	{ERRHRD,	62,	NT_STATUS_NO_SPOOL_SPACE},
	{ERRHRD,	63,	NT_STATUS_PRINT_CANCELLED},
	{ERRHRD,	64,	NT_STATUS_NETWORK_NAME_DELETED},
	{ERRHRD,	65,	NT_STATUS_NETWORK_ACCESS_DENIED},
	{ERRHRD,	66,	NT_STATUS_BAD_DEVICE_TYPE},
	{ERRHRD,	67,	NT_STATUS_BAD_NETWORK_NAME},
	{ERRHRD,	68,	NT_STATUS_TOO_MANY_GUIDS_REQUESTED},
	{ERRHRD,	69,	NT_STATUS_TOO_MANY_SESSIONS},
	{ERRHRD,	70,	NT_STATUS_SHARING_PAUSED},
	{ERRHRD,	71,	NT_STATUS_REQUEST_NOT_ACCEPTED},
	{ERRHRD,	72,	NT_STATUS_REDIRECTOR_PAUSED},
	{ERRHRD,	80,	NT_STATUS_OBJECT_NAME_COLLISION},
	{ERRHRD,	86,	NT_STATUS_WRONG_PASSWORD},
	{ERRHRD,	87,	NT_STATUS_INVALID_INFO_CLASS},
	{ERRHRD,	88,	NT_STATUS_NET_WRITE_FAULT},
	{ERRHRD,	109,	NT_STATUS_PIPE_BROKEN},
	{ERRHRD,	111,	STATUS_MORE_ENTRIES},
	{ERRHRD,	112,	NT_STATUS_DISK_FULL},
	{ERRHRD,	121,	NT_STATUS_IO_TIMEOUT},
	{ERRHRD,	122,	NT_STATUS_BUFFER_TOO_SMALL},
	{ERRHRD,	123,	NT_STATUS_OBJECT_NAME_INVALID},
	{ERRHRD,	124,	NT_STATUS_INVALID_LEVEL},
	{ERRHRD,	126,	NT_STATUS_DLL_NOT_FOUND},
	{ERRHRD,	127,	NT_STATUS_PROCEDURE_NOT_FOUND},
	{ERRHRD,	145,	NT_STATUS_DIRECTORY_NOT_EMPTY},
	{ERRHRD,	154,	NT_STATUS_INVALID_VOLUME_LABEL},
	{ERRHRD,	156,	NT_STATUS_SUSPEND_COUNT_EXCEEDED},
	{ERRHRD,	158,	NT_STATUS_NOT_LOCKED},
	{ERRHRD,	161,	NT_STATUS_OBJECT_PATH_INVALID},
	{ERRHRD,	170,	NT_STATUS(0x80000011)},
	{ERRHRD,	182,	NT_STATUS_ORDINAL_NOT_FOUND},
	{ERRHRD,	183,	NT_STATUS_OBJECT_NAME_COLLISION},
	{ERRHRD,	193,	NT_STATUS_BAD_INITIAL_PC},
	{ERRHRD,	203,	NT_STATUS(0xc0000100)},
	{ERRHRD,	206,	NT_STATUS_NAME_TOO_LONG},
	{ERRHRD,	230,	NT_STATUS_INVALID_INFO_CLASS},
	{ERRHRD,	231,	NT_STATUS_INSTANCE_NOT_AVAILABLE},
	{ERRHRD,	232,	NT_STATUS_PIPE_CLOSING},
	{ERRHRD,	233,	NT_STATUS_PIPE_DISCONNECTED},
	{ERRHRD,	234,	STATUS_MORE_ENTRIES},
	{ERRHRD,	240,	NT_STATUS_VIRTUAL_CIRCUIT_CLOSED},
	{ERRHRD,	254,	NT_STATUS(0x80000013)},
	{ERRHRD,	255,	NT_STATUS_EA_TOO_LARGE},
	{ERRHRD,	259,	NT_STATUS_GUIDS_EXHAUSTED},
	{ERRHRD,	267,	NT_STATUS_NOT_A_DIRECTORY},
	{ERRHRD,	275,	NT_STATUS_EA_TOO_LARGE},
	{ERRHRD,	276,	NT_STATUS_NONEXISTENT_EA_ENTRY},
	{ERRHRD,	277,	NT_STATUS_NONEXISTENT_EA_ENTRY},
	{ERRHRD,	278,	NT_STATUS_NONEXISTENT_EA_ENTRY},
	{ERRHRD,	ERReasnotsupported,	NT_STATUS_EAS_NOT_SUPPORTED},
	{ERRHRD,	288,	NT_STATUS_MUTANT_NOT_OWNED},
	{ERRHRD,	298,	NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED},
	{ERRHRD,	299,	NT_STATUS(0x8000000d)},
	{ERRHRD,	300,	NT_STATUS_OPLOCK_NOT_GRANTED},
	{ERRHRD,	301,	NT_STATUS_INVALID_OPLOCK_PROTOCOL},
	{ERRHRD,	487,	NT_STATUS_CONFLICTING_ADDRESSES},
	{ERRHRD,	534,	NT_STATUS_INTEGER_OVERFLOW},
	{ERRHRD,	535,	NT_STATUS_PIPE_CONNECTED},
	{ERRHRD,	536,	NT_STATUS_PIPE_LISTENING},
	{ERRHRD,	995,	NT_STATUS_CANCELLED},
	{ERRHRD,	997,	NT_STATUS(0x00000103)},
	{ERRHRD,	998,	NT_STATUS_ACCESS_VIOLATION},
	{ERRHRD,	999,	NT_STATUS_IN_PAGE_ERROR},
	{ERRHRD,	1001,	NT_STATUS_BAD_INITIAL_STACK},
	{ERRHRD,	1005,	NT_STATUS_UNRECOGNIZED_VOLUME},
	{ERRHRD,	1006,	NT_STATUS_FILE_INVALID},
	{ERRHRD,	1007,	NT_STATUS_FULLSCREEN_MODE},
	{ERRHRD,	1008,	NT_STATUS_NO_TOKEN},
	{ERRHRD,	1009,	NT_STATUS_REGISTRY_CORRUPT},
	{ERRHRD,	1016,	NT_STATUS_REGISTRY_IO_FAILED},
	{ERRHRD,	1017,	NT_STATUS_NOT_REGISTRY_FILE},
	{ERRHRD,	1018,	NT_STATUS_KEY_DELETED},
	{ERRHRD,	1019,	NT_STATUS_NO_LOG_SPACE},
	{ERRHRD,	1020,	NT_STATUS_KEY_HAS_CHILDREN},
	{ERRHRD,	1021,	NT_STATUS_CHILD_MUST_BE_VOLATILE},
	{ERRHRD,	1022,	NT_STATUS(0x0000010c)},
};

/*****************************************************************************
convert a dos eclas/ecode to a NT status32 code
 *****************************************************************************/
NTSTATUS dos_to_ntstatus(uint8 eclass, uint32 ecode)
{
	int i;
	if (eclass == 0) return NT_STATUS_OK;
	for (i=0; NT_STATUS_V(dos_to_ntstatus_map[i].ntstatus); i++) {
		if (eclass == dos_to_ntstatus_map[i].dos_class &&
		    ecode == dos_to_ntstatus_map[i].dos_code) {
			return dos_to_ntstatus_map[i].ntstatus;
		}
	}
	return NT_STATUS_UNSUCCESSFUL;
}

#if defined(HAVE_GSSAPI)
/*******************************************************************************
 Map between gssapi errors and NT status. I made these up :-(. JRA.
*******************************************************************************/

static const struct {
		unsigned long gss_err;
		NTSTATUS ntstatus;
} gss_to_ntstatus_errormap[] = {
#if defined(GSS_S_CALL_INACCESSIBLE_READ)
		{GSS_S_CALL_INACCESSIBLE_READ, NT_STATUS_INVALID_PARAMETER},
#endif
#if defined(GSS_S_CALL_INACCESSIBLE_WRITE)
		{GSS_S_CALL_INACCESSIBLE_WRITE, NT_STATUS_INVALID_PARAMETER},
#endif
#if defined(GSS_S_CALL_BAD_STRUCTURE)
		{GSS_S_CALL_BAD_STRUCTURE, NT_STATUS_INVALID_PARAMETER},
#endif
#if defined(GSS_S_BAD_MECH)
		{GSS_S_BAD_MECH, NT_STATUS_INVALID_PARAMETER},
#endif
#if defined(GSS_S_BAD_NAME)
		{GSS_S_BAD_NAME, NT_STATUS_INVALID_ACCOUNT_NAME},
#endif
#if defined(GSS_S_BAD_NAMETYPE)
		{GSS_S_BAD_NAMETYPE, NT_STATUS_INVALID_PARAMETER},
#endif
#if defined(GSS_S_BAD_BINDINGS)
		{GSS_S_BAD_BINDINGS, NT_STATUS_INVALID_PARAMETER},
#endif
#if defined(GSS_S_BAD_STATUS)
		{GSS_S_BAD_STATUS, NT_STATUS_UNSUCCESSFUL},
#endif
#if defined(GSS_S_BAD_SIG)
		{GSS_S_BAD_SIG, NT_STATUS_ACCESS_DENIED},
#endif
#if defined(GSS_S_NO_CRED)
		{GSS_S_NO_CRED, NT_STATUS_ACCESS_DENIED},
#endif
#if defined(GSS_S_NO_CONTEXT)
		{GSS_S_NO_CONTEXT, NT_STATUS_ACCESS_DENIED},
#endif
#if defined(GSS_S_DEFECTIVE_TOKEN)
		{GSS_S_DEFECTIVE_TOKEN, NT_STATUS_ACCESS_DENIED},
#endif
#if defined(GSS_S_DEFECTIVE_CREDENTIAL)
		{GSS_S_DEFECTIVE_CREDENTIAL, NT_STATUS_ACCESS_DENIED},
#endif
#if defined(GSS_S_CREDENTIALS_EXPIRED)
		{GSS_S_CREDENTIALS_EXPIRED, NT_STATUS_PASSWORD_EXPIRED},
#endif
#if defined(GSS_S_CONTEXT_EXPIRED)
		{GSS_S_CONTEXT_EXPIRED, NT_STATUS_PASSWORD_EXPIRED},
#endif
#if defined(GSS_S_BAD_QOP)
		{GSS_S_BAD_QOP, NT_STATUS_ACCESS_DENIED},
#endif
#if defined(GSS_S_UNAUTHORIZED)
		{GSS_S_UNAUTHORIZED, NT_STATUS_ACCESS_DENIED},
#endif
#if defined(GSS_S_UNAVAILABLE)
		{GSS_S_UNAVAILABLE, NT_STATUS_UNSUCCESSFUL},
#endif
#if defined(GSS_S_DUPLICATE_ELEMENT)
		{GSS_S_DUPLICATE_ELEMENT, NT_STATUS_INVALID_PARAMETER},
#endif
#if defined(GSS_S_NAME_NOT_MN)
		{GSS_S_NAME_NOT_MN, NT_STATUS_INVALID_PARAMETER},
#endif
		{ 0, NT_STATUS_OK }
};

/*********************************************************************
 Map an NT error code from a gssapi error code.
*********************************************************************/

NTSTATUS map_nt_error_from_gss(uint32 gss_maj, uint32 minor)
{
	int i = 0;

	if (gss_maj == GSS_S_COMPLETE) {
		return NT_STATUS_OK;
	}

	if (gss_maj == GSS_S_CONTINUE_NEEDED) {
		return NT_STATUS_MORE_PROCESSING_REQUIRED;
	}

	if (gss_maj == GSS_S_FAILURE) {
		return map_nt_error_from_unix((int)minor);
	}

	/* Look through list */
	while(gss_to_ntstatus_errormap[i].gss_err != 0) {
		if (gss_to_ntstatus_errormap[i].gss_err == gss_maj) {
			return gss_to_ntstatus_errormap[i].ntstatus;
		}
		i++;
	}

	/* Default return */
	return NT_STATUS_ACCESS_DENIED;
}
#endif