1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System.Collections.Generic;
6 using System.Runtime.Serialization;
7 
8 namespace System.DirectoryServices.Protocols
9 {
10     internal enum LdapError
11     {
12         IsLeaf = 0x23,
13         InvalidCredentials = 49,
14         ServerDown = 0x51,
15         LocalError = 0x52,
16         EncodingError = 0x53,
17         DecodingError = 0x54,
18         TimeOut = 0x55,
19         AuthUnknown = 0x56,
20         FilterError = 0x57,
21         UserCancelled = 0x58,
22         ParameterError = 0x59,
23         NoMemory = 0x5a,
24         ConnectError = 0x5b,
25         NotSupported = 0x5c,
26         NoResultsReturned = 0x5e,
27         ControlNotFound = 0x5d,
28         MoreResults = 0x5f,
29         ClientLoop = 0x60,
30         ReferralLimitExceeded = 0x61,
31         SendTimeOut = 0x70
32     }
33 
34     internal class LdapErrorMappings
35     {
36         private static readonly Dictionary<LdapError, string> s_resultCodeMapping = new Dictionary<LdapError, string>(capacity: 20)
37         {
38             { LdapError.IsLeaf, SR.LDAP_IS_LEAF },
39             { LdapError.InvalidCredentials, SR.LDAP_INVALID_CREDENTIALS },
40             { LdapError.ServerDown, SR.LDAP_SERVER_DOWN },
41             { LdapError.LocalError, SR.LDAP_LOCAL_ERROR },
42             { LdapError.EncodingError, SR.LDAP_ENCODING_ERROR },
43             { LdapError.DecodingError, SR.LDAP_DECODING_ERROR },
44             { LdapError.TimeOut, SR.LDAP_TIMEOUT },
45             { LdapError.AuthUnknown, SR.LDAP_AUTH_UNKNOWN },
46             { LdapError.FilterError, SR.LDAP_FILTER_ERROR },
47             { LdapError.UserCancelled, SR.LDAP_USER_CANCELLED },
48             { LdapError.ParameterError, SR.LDAP_PARAM_ERROR },
49             { LdapError.NoMemory, SR.LDAP_NO_MEMORY },
50             { LdapError.ConnectError, SR.LDAP_CONNECT_ERROR },
51             { LdapError.NotSupported, SR.LDAP_NOT_SUPPORTED },
52             { LdapError.NoResultsReturned, SR.LDAP_NO_RESULTS_RETURNED },
53             { LdapError.ControlNotFound, SR.LDAP_CONTROL_NOT_FOUND },
54             { LdapError.MoreResults, SR.LDAP_MORE_RESULTS_TO_RETURN },
55             { LdapError.ClientLoop, SR.LDAP_CLIENT_LOOP },
56             { LdapError.ReferralLimitExceeded, SR.LDAP_REFERRAL_LIMIT_EXCEEDED },
57             { LdapError.SendTimeOut, SR.LDAP_SEND_TIMEOUT }
58         };
59 
MapResultCode(int errorCode)60         public static string MapResultCode(int errorCode)
61         {
62             s_resultCodeMapping.TryGetValue((LdapError)errorCode, out string errorMessage);
63             return errorMessage;
64         }
65     }
66 
67     [Serializable]
68 #if !MONO
69     [System.Runtime.CompilerServices.TypeForwardedFrom("System.DirectoryServices.Protocols, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
70 #endif
71     public class LdapException : DirectoryException, ISerializable
72     {
LdapException(SerializationInfo info, StreamingContext context)73         protected LdapException(SerializationInfo info, StreamingContext context) : base(info, context) { }
74 
LdapException()75         public LdapException() : base() { }
76 
LdapException(string message)77         public LdapException(string message) : base(message) { }
78 
LdapException(string message, Exception inner)79         public LdapException(string message, Exception inner) : base(message, inner) { }
80 
LdapException(int errorCode)81         public LdapException(int errorCode) : base(SR.DefaultLdapError)
82         {
83             ErrorCode = errorCode;
84         }
85 
LdapException(int errorCode, string message)86         public LdapException(int errorCode, string message) : base(message)
87         {
88             ErrorCode = errorCode;
89         }
90 
LdapException(int errorCode, string message, string serverErrorMessage)91         public LdapException(int errorCode, string message, string serverErrorMessage) : base(message)
92         {
93             ErrorCode = errorCode;
94             ServerErrorMessage = serverErrorMessage;
95         }
96 
LdapException(int errorCode, string message, Exception inner)97         public LdapException(int errorCode, string message, Exception inner) : base(message, inner)
98         {
99             ErrorCode = errorCode;
100         }
101 
102         public int ErrorCode { get; }
103 
104         public string ServerErrorMessage { get; }
105 
106         public PartialResultsCollection PartialResults { get; } = new PartialResultsCollection();
107     }
108 
109     [Serializable]
110 #if !MONO
111     [System.Runtime.CompilerServices.TypeForwardedFrom("System.DirectoryServices.Protocols, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
112 #endif
113     public class TlsOperationException : DirectoryOperationException
114     {
TlsOperationException(SerializationInfo info, StreamingContext context)115         protected TlsOperationException(SerializationInfo info, StreamingContext context) : base(info, context) { }
116 
TlsOperationException()117         public TlsOperationException() : base() { }
118 
TlsOperationException(string message)119         public TlsOperationException(string message) : base(message) { }
120 
TlsOperationException(string message, Exception inner)121         public TlsOperationException(string message, Exception inner) : base(message, inner) { }
122 
TlsOperationException(DirectoryResponse response)123         public TlsOperationException(DirectoryResponse response) : base(response)
124         {
125         }
126 
TlsOperationException(DirectoryResponse response, string message)127         public TlsOperationException(DirectoryResponse response, string message) : base(response, message)
128         {
129         }
130 
TlsOperationException(DirectoryResponse response, string message, Exception inner)131         public TlsOperationException(DirectoryResponse response, string message, Exception inner) : base(response, message, inner)
132         {
133         }
134     }
135 
136     internal class ErrorChecking
137     {
CheckAndSetLdapError(int error)138         public static void CheckAndSetLdapError(int error)
139         {
140             if (error != (int)ResultCode.Success)
141             {
142                 if (Utility.IsResultCode((ResultCode)error))
143                 {
144                     string errorMessage = OperationErrorMappings.MapResultCode(error);
145                     throw new DirectoryOperationException(null, errorMessage);
146                 }
147                 else if (Utility.IsLdapError((LdapError)error))
148                 {
149                     string errorMessage = LdapErrorMappings.MapResultCode(error);
150                     throw new LdapException(error, errorMessage);
151                 }
152                 else
153                 {
154                     throw new LdapException(error);
155                 }
156             }
157         }
158     }
159 }
160