New test.
[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 #if NET_2_0
37         public sealed class SecurityContext {
38 #else
39         internal sealed class SecurityContext {
40 #endif
41                 private bool _capture;
42                 private IntPtr _winid;
43                 private CompressedStack _stack;
44                 private bool _suppressFlowWindowsIdentity;
45                 private bool _suppressFlow;
46
47                 internal SecurityContext ()
48                 {
49                 }
50
51                 // copy constructor
52                 internal SecurityContext (SecurityContext sc)
53                 {
54                         _capture = true;
55                         _winid = sc._winid;
56                         if (sc._stack != null)
57                                 _stack = sc._stack.CreateCopy ();
58                 }
59
60                 public SecurityContext CreateCopy ()
61                 {
62                         if (!_capture)
63                                 throw new InvalidOperationException ();
64
65                         return new SecurityContext (this);
66                 }
67
68                 // static methods
69
70                 static public SecurityContext Capture ()
71                 {
72                         SecurityContext sc = Thread.CurrentThread.ExecutionContext.SecurityContext;
73                         if (sc.FlowSuppressed)
74                                 return null;
75
76                         SecurityContext capture = new SecurityContext ();
77                         capture._capture = true;
78                         capture._winid = WindowsIdentity.GetCurrentToken ();
79                         capture._stack = CompressedStack.Capture ();
80                         return capture;
81                 }
82
83                 // internal stuff
84
85                 internal bool FlowSuppressed {
86                         get { return _suppressFlow; }
87                         set { _suppressFlow = value; }
88                 }
89
90                 internal bool WindowsIdentityFlowSuppressed {
91                         get { return _suppressFlowWindowsIdentity; }
92                         set { _suppressFlowWindowsIdentity = value; }
93                 }
94
95                 internal CompressedStack CompressedStack {
96                         get { return _stack; }
97                         set { _stack = value; }
98                 }
99
100                 internal IntPtr IdentityToken {
101                         get { return _winid; }
102                         set { _winid = value; }
103                 }
104
105                 // Suppressing the SecurityContext flow wasn't required before 2.0
106
107                 static public bool IsFlowSuppressed ()
108                 {
109                         return Thread.CurrentThread.ExecutionContext.SecurityContext.FlowSuppressed;
110                 } 
111
112                 static public bool IsWindowsIdentityFlowSuppressed ()
113                 {
114                         return Thread.CurrentThread.ExecutionContext.SecurityContext.WindowsIdentityFlowSuppressed;
115                 }
116
117                 static public void RestoreFlow ()
118                 {
119                         SecurityContext sc = Thread.CurrentThread.ExecutionContext.SecurityContext;
120                         // if nothing is suppressed then throw
121                         if (!sc.FlowSuppressed && !sc.WindowsIdentityFlowSuppressed)
122                                 throw new InvalidOperationException ();
123
124                         sc.FlowSuppressed = false;
125                         sc.WindowsIdentityFlowSuppressed = false;
126                 }
127 #if NET_2_0
128                 // if you got the context then you can use it
129                 [SecurityPermission (SecurityAction.Assert, ControlPrincipal = true)]
130                 [SecurityPermission (SecurityAction.LinkDemand, Infrastructure = true)]
131                 static public void Run (SecurityContext securityContext, ContextCallback callBack, object state)
132                 {
133                         if (securityContext == null) {
134                                 throw new InvalidOperationException (Locale.GetText (
135                                         "Null SecurityContext"));
136                         }
137
138                         SecurityContext sc = Thread.CurrentThread.ExecutionContext.SecurityContext;
139                         IPrincipal original = Thread.CurrentPrincipal;
140                         try {
141                                 if (sc.IdentityToken != IntPtr.Zero) {
142                                         Thread.CurrentPrincipal = new WindowsPrincipal (new WindowsIdentity (sc.IdentityToken));
143                                 }
144
145                                 // FIXME: is the security manager isn't active then we may not have
146                                 // a compressed stack (bug #78652)
147                                 if (securityContext.CompressedStack != null)
148                                         CompressedStack.Run (securityContext.CompressedStack, callBack, state);
149                                 else
150                                         callBack (state);
151                         }
152                         finally {
153                                 if ((original != null) && (sc.IdentityToken != IntPtr.Zero))
154                                         Thread.CurrentPrincipal = original;
155                         }
156                 }
157 #endif
158                 [SecurityPermission (SecurityAction.LinkDemand, Infrastructure = true)]
159                 static public AsyncFlowControl SuppressFlow ()
160                 {
161                         Thread t = Thread.CurrentThread;
162                         // suppress both flows
163                         t.ExecutionContext.SecurityContext.FlowSuppressed = true;
164                         t.ExecutionContext.SecurityContext.WindowsIdentityFlowSuppressed = true;
165                         return new AsyncFlowControl (t, AsyncFlowControlType.Security);
166                 }
167
168                 static public AsyncFlowControl SuppressFlowWindowsIdentity ()
169                 {
170                         Thread t = Thread.CurrentThread;
171                         t.ExecutionContext.SecurityContext.WindowsIdentityFlowSuppressed = true;
172                         return new AsyncFlowControl (t, AsyncFlowControlType.Security);
173                 }
174         }
175 }