[MSBuild] Fix minor assembly resolution issue
[mono.git] / mcs / class / corlib / System.Security / SecurityContext.cs
1 //
2 // System.Security.SecurityContext class
3 //
4 // Author:
5 //      Sebastien Pouliot  <sebastien@ximian.com>
6 //
7 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 using System.Runtime.InteropServices;
30 using System.Security.Permissions;
31 using System.Security.Principal;
32 using System.Threading;
33
34 namespace System.Security {
35
36         public sealed class SecurityContext
37                 : IDisposable
38         {
39                 private bool _capture;
40                 private IntPtr _winid;
41
42 #if !MOBILE     
43                 private CompressedStack _stack;
44 #endif
45                 private bool _suppressFlowWindowsIdentity;
46                 private bool _suppressFlow;
47
48                 internal SecurityContext ()
49                 {
50                 }
51
52                 // copy constructor
53                 internal SecurityContext (SecurityContext sc)
54                 {
55                         _capture = true;
56 #if !MOBILE
57                         _winid = sc._winid;
58                         if (sc._stack != null)
59                                 _stack = sc._stack.CreateCopy ();
60 #endif
61                 }
62
63                 public SecurityContext CreateCopy ()
64                 {
65                         if (!_capture)
66                                 throw new InvalidOperationException ();
67
68                         return new SecurityContext (this);
69                 }
70
71                 // static methods
72
73                 static public SecurityContext Capture ()
74                 {
75 #if !MOBILE                     
76                         SecurityContext sc = Thread.CurrentThread.ExecutionContext.SecurityContext;
77                         if (sc.FlowSuppressed)
78                                 return null;
79 #endif
80
81                         SecurityContext capture = new SecurityContext ();
82                         capture._capture = true;
83 #if !MOBILE
84                         capture._winid = WindowsIdentity.GetCurrentToken ();
85                         capture._stack = CompressedStack.Capture ();
86 #endif
87                         return capture;
88                 }
89                 
90                 public void Dispose ()
91                 {
92                 }
93
94                 // internal stuff
95
96                 internal bool FlowSuppressed {
97                         get { return _suppressFlow; }
98                         set { _suppressFlow = value; }
99                 }
100
101                 internal bool WindowsIdentityFlowSuppressed {
102                         get { return _suppressFlowWindowsIdentity; }
103                         set { _suppressFlowWindowsIdentity = value; }
104                 }
105
106 #if !MOBILE     
107                 internal CompressedStack CompressedStack {
108                         get { return _stack; }
109                         set { _stack = value; }
110                 }
111 #endif
112
113                 internal IntPtr IdentityToken {
114                         get { return _winid; }
115                         set { _winid = value; }
116                 }
117
118                 // Suppressing the SecurityContext flow wasn't required before 2.0
119
120                 static public bool IsFlowSuppressed ()
121                 {
122 #if MOBILE
123                         return false;
124 #else
125                         return Thread.CurrentThread.ExecutionContext.SecurityContext.FlowSuppressed;
126 #endif
127                 } 
128
129                 static public bool IsWindowsIdentityFlowSuppressed ()
130                 {
131 #if MOBILE
132                         return false;
133 #else
134                         return Thread.CurrentThread.ExecutionContext.SecurityContext.WindowsIdentityFlowSuppressed;
135 #endif
136                 }
137
138                 static public void RestoreFlow ()
139                 {
140 #if !MOBILE
141                         SecurityContext sc = Thread.CurrentThread.ExecutionContext.SecurityContext;
142                         // if nothing is suppressed then throw
143                         if (!sc.FlowSuppressed && !sc.WindowsIdentityFlowSuppressed)
144                                 throw new InvalidOperationException ();
145
146                         sc.FlowSuppressed = false;
147                         sc.WindowsIdentityFlowSuppressed = false;
148 #endif
149                 }
150
151                 // if you got the context then you can use it
152                 [SecurityPermission (SecurityAction.Assert, ControlPrincipal = true)]
153                 [SecurityPermission (SecurityAction.LinkDemand, Infrastructure = true)]
154                 static public void Run (SecurityContext securityContext, ContextCallback callback, object state)
155                 {
156                         if (securityContext == null) {
157                                 throw new InvalidOperationException (Locale.GetText (
158                                         "Null SecurityContext"));
159                         }
160 #if MOBILE
161                         callback (state);
162 #else
163                         SecurityContext sc = Thread.CurrentThread.ExecutionContext.SecurityContext;
164                         IPrincipal original = Thread.CurrentPrincipal;
165                         try {
166                                 if (sc.IdentityToken != IntPtr.Zero) {
167                                         Thread.CurrentPrincipal = new WindowsPrincipal (new WindowsIdentity (sc.IdentityToken));
168                                 }
169
170                                 // FIXME: is the security manager isn't active then we may not have
171                                 // a compressed stack (bug #78652)
172                                 if (securityContext.CompressedStack != null)
173                                         CompressedStack.Run (securityContext.CompressedStack, callback, state);
174                                 else
175                                         callback (state);
176                         }
177                         finally {
178                                 if ((original != null) && (sc.IdentityToken != IntPtr.Zero))
179                                         Thread.CurrentPrincipal = original;
180                         }
181 #endif
182                 }
183
184                 [SecurityPermission (SecurityAction.LinkDemand, Infrastructure = true)]
185                 static public AsyncFlowControl SuppressFlow ()
186                 {
187 #if MOBILE
188                         throw new NotSupportedException ();
189 #else                   
190                         Thread t = Thread.CurrentThread;
191                         // suppress both flows
192                         t.ExecutionContext.SecurityContext.FlowSuppressed = true;
193                         t.ExecutionContext.SecurityContext.WindowsIdentityFlowSuppressed = true;
194                         return new AsyncFlowControl (t, AsyncFlowControlType.Security);
195 #endif
196                 }
197
198                 static public AsyncFlowControl SuppressFlowWindowsIdentity ()
199                 {
200 #if MOBILE
201                         throw new NotSupportedException ();
202 #else                   
203                         Thread t = Thread.CurrentThread;
204                         t.ExecutionContext.SecurityContext.WindowsIdentityFlowSuppressed = true;
205                         return new AsyncFlowControl (t, AsyncFlowControlType.Security);
206 #endif
207                 }
208         }
209 }