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.DirectoryServices.Interop;
6 using System.ComponentModel;
7 
8 namespace System.DirectoryServices
9 {
10     public class DirectoryEntryConfiguration
11     {
12         private readonly DirectoryEntry _entry;
13         private const int ISC_RET_MUTUAL_AUTH = 0x00000002;
14 
DirectoryEntryConfiguration(DirectoryEntry entry)15         internal DirectoryEntryConfiguration(DirectoryEntry entry)
16         {
17             _entry = entry;
18         }
19 
20         public ReferralChasingOption Referral
21         {
22             get
23             {
24                 return (ReferralChasingOption)((UnsafeNativeMethods.IAdsObjectOptions)_entry.AdsObject).GetOption((int)AdsOptions.ADS_OPTION_REFERRALS);
25             }
26             set
27             {
28                 if (value != ReferralChasingOption.None &&
29                     value != ReferralChasingOption.Subordinate &&
30                     value != ReferralChasingOption.External &&
31                     value != ReferralChasingOption.All)
32                     throw new InvalidEnumArgumentException("value", (int)value, typeof(ReferralChasingOption));
33 
34                 ((UnsafeNativeMethods.IAdsObjectOptions)_entry.AdsObject).SetOption((int)AdsOptions.ADS_OPTION_REFERRALS, value);
35             }
36         }
37 
38         public SecurityMasks SecurityMasks
39         {
40             get
41             {
42                 return (SecurityMasks)((UnsafeNativeMethods.IAdsObjectOptions)_entry.AdsObject).GetOption((int)AdsOptions.ADS_OPTION_SECURITY_MASK);
43             }
44             set
45             {
46                 if (value > (SecurityMasks.None | SecurityMasks.Owner | SecurityMasks.Group | SecurityMasks.Dacl | SecurityMasks.Sacl))
47                     throw new InvalidEnumArgumentException("value", (int)value, typeof(SecurityMasks));
48 
49                 ((UnsafeNativeMethods.IAdsObjectOptions)_entry.AdsObject).SetOption((int)AdsOptions.ADS_OPTION_SECURITY_MASK, value);
50             }
51         }
52 
53         public int PageSize
54         {
55             get
56             {
57                 return (int)((UnsafeNativeMethods.IAdsObjectOptions)_entry.AdsObject).GetOption((int)AdsOptions.ADS_OPTION_PAGE_SIZE);
58             }
59             set
60             {
61                 if (value < 0)
62                     throw new ArgumentException(SR.DSBadPageSize);
63 
64                 ((UnsafeNativeMethods.IAdsObjectOptions)_entry.AdsObject).SetOption((int)AdsOptions.ADS_OPTION_PAGE_SIZE, value);
65             }
66         }
67 
68         public int PasswordPort
69         {
70             get
71             {
72                 return (int)((UnsafeNativeMethods.IAdsObjectOptions)_entry.AdsObject).GetOption((int)AdsOptions.ADS_OPTION_PASSWORD_PORTNUMBER);
73             }
74             set
75             {
76                 ((UnsafeNativeMethods.IAdsObjectOptions)_entry.AdsObject).SetOption((int)AdsOptions.ADS_OPTION_PASSWORD_PORTNUMBER, value);
77             }
78         }
79 
80         public PasswordEncodingMethod PasswordEncoding
81         {
82             get
83             {
84                 return (PasswordEncodingMethod)((UnsafeNativeMethods.IAdsObjectOptions)_entry.AdsObject).GetOption((int)AdsOptions.ADS_OPTION_PASSWORD_METHOD);
85             }
86             set
87             {
88                 if (value < PasswordEncodingMethod.PasswordEncodingSsl || value > PasswordEncodingMethod.PasswordEncodingClear)
89                     throw new InvalidEnumArgumentException("value", (int)value, typeof(PasswordEncodingMethod));
90 
91                 ((UnsafeNativeMethods.IAdsObjectOptions)_entry.AdsObject).SetOption((int)AdsOptions.ADS_OPTION_PASSWORD_METHOD, value);
92             }
93         }
94 
GetCurrentServerName()95         public string GetCurrentServerName()
96         {
97             // underneath it uses the same handle and binds to the same object, so no permission is required as it has been done in Bind call
98             return (string)((UnsafeNativeMethods.IAdsObjectOptions)_entry.AdsObject).GetOption((int)AdsOptions.ADS_OPTION_SERVERNAME);
99         }
100 
IsMutuallyAuthenticated()101         public bool IsMutuallyAuthenticated()
102         {
103             try
104             {
105                 int val = (int)((UnsafeNativeMethods.IAdsObjectOptions)_entry.AdsObject).GetOption((int)AdsOptions.ADS_OPTION_MUTUAL_AUTH_STATUS);
106                 if ((val & ISC_RET_MUTUAL_AUTH) != 0)
107                     return true;
108                 else
109                     return false;
110             }
111             catch (System.Runtime.InteropServices.COMException e)
112             {
113                 // if SSL is used, ADSI will return E_ADS_BAD_PARAMETER, we should catch it here
114                 if (e.ErrorCode == unchecked((int)0x80005008))
115                     return false;
116                 throw;
117             }
118         }
119 
SetUserNameQueryQuota(string accountName)120         public void SetUserNameQueryQuota(string accountName)
121         {
122             ((UnsafeNativeMethods.IAdsObjectOptions)_entry.AdsObject).SetOption((int)AdsOptions.ADS_OPTION_QUOTA, accountName);
123         }
124     }
125 }
126