public AccessControlEntry(SecurityIdentifier trustee, AccessControlEntryType aceType, AccessMask accessMask) { // parameters validation if (trustee == null) throw new ArgumentNullException("trustee"); _aceType = aceType; _aceFlags = AccessControlEntryFlags.Normal; _accessMask = accessMask; Trustee = trustee; }
internal AccessControlEntry(IntPtr pAce) { // parameters validation if (pAce == IntPtr.Zero) throw new ArgumentNullException("pAce"); // read ACE properties _aceType = (AccessControlEntryType)MarshalHelper.ReadByte(pAce, typeof(SecurityNative.ACE), "AceType"); _aceFlags = (AccessControlEntryFlags)MarshalHelper.ReadByte(pAce, typeof(SecurityNative.ACE), "AceFlags"); _accessMask = (AccessMask)MarshalHelper.ReadInt32(pAce, typeof(SecurityNative.ACE), "AccessMask"); // read SID IntPtr pSid = IntPtrHelper.Add(pAce, Marshal.OffsetOf(typeof(SecurityNative.ACE), "SidStart")); Trustee = new SecurityIdentifier(pSid, true); }
public SetFieldBinder(string name, RuntimeTypeHandle classContext, AccessMask access) { _name = name; _classContext = Type.GetTypeFromHandle(classContext); _access = access & AccessMask.WriteMask; }
internal static extern SafeKernelObjectHandle CreateWindowStation( string lpwinsta, int dwFlags, AccessMask dwDesiredAccess, SECURITY_ATTRIBUTES lpsa );
public GetClassConstBinder(string name, RuntimeTypeHandle classContext, RuntimeTypeHandle returnType, AccessMask access) : base(name, classContext, returnType, access) { }
/// <summary> /// Will return desired FileAccess rights to the file data. /// </summary> public static FileAccess ToFileAccess(AccessMask desiredAccess) { return(ToFileAccess((FileAccessMask)desiredAccess)); }
private void DoAccessCheck(IEnumerable <TokenEntry> tokens, IEnumerable <NtProcess> processes, AccessMask access_rights, AccessMask thread_access_rights) { foreach (NtProcess process in processes) { ProcessDetails proc_details = ProcessDetails.FromProcess(process); if (CheckProcess()) { var sd = GetSecurityDescriptorReOpen(process); if (sd.IsSuccess) { foreach (TokenEntry token in tokens) { CheckAccess(token, proc_details, null, _process_type, access_rights, sd.Result); } } else { // Try and open process when under impersonation. foreach (TokenEntry token in tokens) { using (var new_process = token.Token.RunUnderImpersonate(() => ReOpen(process))) { if (new_process.IsSuccess && IsAccessGranted(new_process.Result.GrantedAccessMask, access_rights)) { WriteAccessCheckResult(proc_details, null, new_process.Result.GrantedAccessMask, _process_type.GenericMapping, null, token.Information); } } } } } if (CheckThread()) { using (var new_process = process.ReOpen(ProcessAccessRights.QueryInformation, false)) { if (new_process.IsSuccess) { using (var threads = new_process.Result.GetThreads(ThreadAccessRights.QueryLimitedInformation).ToDisposableList()) { foreach (var thread in threads) { DoAccessCheck(tokens, proc_details, thread, thread_access_rights); } } } } } } }
public void OpenFile( string server, string share, string file, SecurityPackageType securityPackageType, string domainName, string userName, string password, AccessMask accessMask) { IPHostEntry hostEntry = Dns.GetHostEntry(server); client.ConnectOverTCP(hostEntry.AddressList[0]); serverPrincipleName = Smb2Utility.GetPrincipleName(hostEntry.HostName); Packet_Header header; NEGOTIATE_Response negotiateResponse; DialectRevision selectedDialect; byte[] serverGssToken; CheckStatusCode( Negotiate( 1, 1, messageId++, clientGuid, out selectedDialect, out serverGssToken, out header, out negotiateResponse)); // 3.2.5.2: If the SecurityMode field in the SMB2 header of the response has the SMB2_NEGOTIATE_SIGNING_REQUIRED bit set, // the client MUST set Connection.RequireSigning to TRUE. // 3.2.5.3.1: If the global setting RequireMessageSigning is set to TRUE or // Connection.RequireSigning is set to TRUE then Session.SigningRequired MUST be set to TRUE bool session_SigningRequired = negotiateResponse.SecurityMode.HasFlag(NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED); if (session_SigningRequired) { // 3.2.4.1.1: If the client signs the request, it MUST set the SMB2_FLAGS_SIGNED bit in the Flags field of the SMB2 header. headerFlags |= Packet_Header_Flags_Values.FLAGS_SIGNED; } SESSION_SETUP_Response sessionSetupResponse; SspiClientSecurityContext sspiClientGss = new SspiClientSecurityContext( securityPackageType, new AccountCredential(domainName, userName, password), Smb2Utility.GetCifsServicePrincipalName(server), ClientSecurityContextAttribute.None, SecurityTargetDataRepresentation.SecurityNativeDrep); if (securityPackageType == SecurityPackageType.Negotiate) sspiClientGss.Initialize(serverGssToken); else sspiClientGss.Initialize(null); uint status; do { status = client.SessionSetup( 1, 1, Packet_Header_Flags_Values.NONE, messageId++, sessionId, SESSION_SETUP_Request_Flags.NONE, SESSION_SETUP_Request_SecurityMode_Values.NONE, SESSION_SETUP_Request_Capabilities_Values.NONE, 0, sspiClientGss.Token, out sessionId, out serverGssToken, out header, out sessionSetupResponse); CheckStatusCode(status); if ((status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED || status == Smb2Status.STATUS_SUCCESS) && serverGssToken != null && serverGssToken.Length > 0) { sspiClientGss.Initialize(serverGssToken); } } while (status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED); client.GenerateCryptoKeys(sessionId, sspiClientGss.SessionKey, session_SigningRequired, false); TREE_CONNECT_Response treeConnectResponse; CheckStatusCode( TreeConnect( 1, 1, headerFlags, messageId++, sessionId, server, share, out header, out treeConnectResponse)); CREATE_Response createResponse; Smb2CreateContextResponse[] serverCreateContexts; CheckStatusCode( client.Create( 1, 1, headerFlags, messageId++, sessionId, treeId, file, accessMask, ShareAccess_Values.FILE_SHARE_READ, CreateOptions_Values.NONE, CreateDisposition_Values.FILE_OPEN_IF, File_Attributes.NONE, ImpersonationLevel_Values.Impersonation, SecurityFlags_Values.NONE, RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE, null, out fileId, out serverCreateContexts, out header, out createResponse)); }
/// <summary> /// Attempt to trigger LeaseBreakNotification from a separate client /// </summary> /// <param name="client">Client to trigger LeaseBreakNotification</param> /// <param name="requestDialect">Negotiate dialects</param> /// <param name="serverName">Name of file server to access</param> /// <param name="isDirectory">True value indicating to open a directory, false for a file</param> /// <param name="requestedLeaseState">LeaseState when open the directory or file</param> /// <param name="accessMask">AccessMask when open the directory or file</param> private void TriggerBreakFromClient( Smb2FunctionalClient client, DialectRevision[] requestDialect, string serverName, bool isDirectory, LeaseStateValues requestedLeaseState, AccessMask accessMask) { BaseTestSite.Log.Add(LogEntryKind.Debug, "AfterFailover: Attempt to access same file/directory to trigger LeaseBreakNotification from a separate client with LeaseState {0} and AccessMask {1}", requestedLeaseState, accessMask); #region Negotiate status = client.Negotiate( requestDialect, TestConfig.IsSMB1NegotiateEnabled, capabilityValue: Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES, checker: (Packet_Header header, NEGOTIATE_Response response) => { TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response); }); #endregion #region SESSION_SETUP status = client.SessionSetup( TestConfig.DefaultSecurityPackage, serverName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); #endregion #region TREE_CONNECT to share uint treeId; status = client.TreeConnect(uncSharePath, out treeId); #endregion #region CREATE Smb2CreateContextResponse[] serverCreateContexts; FILEID fileId; status = client.Create( treeId, // To break lease on directory, create a new child item isDirectory ? testDirectory + @"\child.txt" : fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE, new Smb2CreateContextRequest[] { new Smb2CreateRequestLeaseV2 { LeaseKey = Guid.NewGuid(), LeaseState = requestedLeaseState } }, accessMask: accessMask, shareAccess: ShareAccess_Values.NONE, checker: (header, response) => { }); #endregion BaseTestSite.Log.Add( LogEntryKind.Debug, "AfterFailover: Finish triggering a LeaseBreakNotification from a separate client."); }
public static bool EnsureObject(this AccessMask flags) => (flags & AccessMask.EnsureObject) == AccessMask.EnsureObject;
internal static SMB1Command GetNTCreateResponse(SMB1Header header, NTCreateAndXRequest request, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); bool isExtended = (request.Flags & NTCreateFlags.NT_CREATE_REQUEST_EXTENDED_RESPONSE) > 0; string path = request.FileName; if (!path.StartsWith(@"\")) { path = @"\" + path; } FileAccess createAccess = NTFileStoreHelper.ToCreateFileAccess(request.DesiredAccess, request.CreateDisposition); if (share is FileSystemShare) { if (!((FileSystemShare)share).HasAccess(session.SecurityContext, path, createAccess)) { state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. User '{2}' was denied access.", share.Name, request.FileName, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(new ErrorResponse(request.CommandName)); } } object handle; FileStatus fileStatus; FileAttributes fileAttributes = ToFileAttributes(request.ExtFileAttributes); // GetFileInformation/FileNetworkOpenInformation requires FILE_READ_ATTRIBUTES AccessMask desiredAccess = request.DesiredAccess | (AccessMask)FileAccessMask.FILE_READ_ATTRIBUTES; NTStatus createStatus = share.FileStore.CreateFile(out handle, out fileStatus, path, desiredAccess, fileAttributes, request.ShareAccess, request.CreateDisposition, request.CreateOptions, session.SecurityContext); if (createStatus != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. NTStatus: {2}.", share.Name, path, createStatus); header.Status = createStatus; return(new ErrorResponse(request.CommandName)); } FileAccess fileAccess = NTFileStoreHelper.ToFileAccess(desiredAccess); ushort? fileID = session.AddOpenFile(header.TID, share.Name, path, handle, fileAccess); if (!fileID.HasValue) { share.FileStore.CloseFile(handle); state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. Too many open files.", share.Name, path); header.Status = NTStatus.STATUS_TOO_MANY_OPENED_FILES; return(new ErrorResponse(request.CommandName)); } state.LogToServer(Severity.Verbose, "Create: Opened '{0}{1}'. (UID: {2}, TID: {3}, FID: {4})", share.Name, path, header.UID, header.TID, fileID.Value); if (share is NamedPipeShare) { if (isExtended) { return(CreateResponseExtendedForNamedPipe(fileID.Value, FileStatus.FILE_OPENED)); } else { return(CreateResponseForNamedPipe(fileID.Value, FileStatus.FILE_OPENED)); } } else // FileSystemShare { FileNetworkOpenInformation fileInfo = NTFileStoreHelper.GetNetworkOpenInformation(share.FileStore, handle); if (isExtended) { NTCreateAndXResponseExtended response = CreateResponseExtendedFromFileInformation(fileInfo, fileID.Value, fileStatus); return(response); } else { NTCreateAndXResponse response = CreateResponseFromFileInformation(fileInfo, fileID.Value, fileStatus); return(response); } } }
public AllowedAce(PrincipalIdentifier principal, AccessMask accessMask) : base(AceType.Allowed, principal, accessMask) { }
/// <summary> /// The main entry point for the application. /// </summary> public static void Main(string[] args) { string database_file = null; string save_file = null; bool do_enum = false; bool enum_clsid = false; bool enum_runtime = false; bool show_help = false; bool query_interfaces = false; int concurrent_queries = Environment.ProcessorCount; bool refresh_interfaces = false; bool enable_activation_filter = false; string symbol_dir = null; bool delete_database = false; string view_access_sd = null; string view_launch_sd = null; string view_name = null; COMRegistryMode mode = COMRegistryMode.Merged; IEnumerable <COMServerType> server_types = new COMServerType[] { COMServerType.InProcHandler32, COMServerType.InProcServer32, COMServerType.LocalServer32 }; NtToken token = null; OptionSet opts = new OptionSet() { { "i|in=", "Open a database file.", v => database_file = v }, { "o|out=", "Save database and exit.", v => save_file = v }, { "e|enum", "Enumerate the provided CLSID (GUID).", v => enum_clsid = v != null }, { "r|rt", "Enumerate the provided Runtime Class.", v => enum_runtime = v != null }, { "q|query", "Query all interfaces for database", v => query_interfaces = v != null }, { "c|conn=", "Number of concurrent interface queries", v => concurrent_queries = int.Parse(v) }, { "s|server=", "Specify server types for query", v => server_types = ParseServerTypes(v) }, { "refresh", "Refresh interfaces in query", v => refresh_interfaces = v != null }, { "m", "Loading mode is machine only.", v => mode = COMRegistryMode.MachineOnly }, { "u", "Loading mode is user only.", v => mode = COMRegistryMode.UserOnly }, { "a", "Enable activation filter.", v => enable_activation_filter = v != null }, { "g=", "Generate a symbol file in the specified directory.", v => symbol_dir = v }, { "d", "Delete the input database once loaded", v => delete_database = v != null }, { "v=", "View a COM access security descriptor (specify the SDDL)", v => view_access_sd = v }, { "l=", "View a COM launch security descriptor (specify the SDDL)", v => view_launch_sd = v }, { "n=", "Name any simple form display such as security descriptor", v => view_name = v }, { "t=", "Specify a token to use when enumerating interfaces", v => token = NtToken.FromHandle(new IntPtr(int.Parse(v))) }, { "h|help", "Show this message and exit.", v => show_help = v != null }, }; List <string> additional_args = new List <string>(); try { additional_args = opts.Parse(args); } catch { show_help = true; } do_enum = enum_clsid || enum_runtime; if (show_help || (do_enum && additional_args.Count < 4) || (symbol_dir != null && !Directory.Exists(symbol_dir))) { StringWriter writer = new StringWriter(); writer.WriteLine("Usage: OleViewDotNet [options] [enum args]"); writer.WriteLine(); writer.WriteLine("Options:"); opts.WriteOptionDescriptions(writer); MessageBox.Show(writer.ToString(), "Help", MessageBoxButtons.OK, MessageBoxIcon.Information); Environment.Exit(1); } if (do_enum) { try { Environment.Exit(EnumInterfaces(new Queue <string>(additional_args), enum_runtime, token)); } catch { Environment.Exit(42); } } else if (symbol_dir != null) { try { COMUtilities.GenerateSymbolFile(symbol_dir, Environment.Is64BitProcess ? Properties.Settings.Default.DbgHelpPath64 : Properties.Settings.Default.DbgHelpPath32, Properties.Settings.Default.SymbolPath); Environment.Exit(0); } catch (Exception) { Environment.Exit(1); } } else { AutoSaveLoadConfiguration autoload_config = new AutoSaveLoadConfiguration(); AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); try { if (view_access_sd != null || view_launch_sd != null) { bool access = view_access_sd != null; SecurityDescriptor sd = new SecurityDescriptor(view_access_sd ?? view_launch_sd); bool has_container = false; if (sd.DaclPresent) { foreach (var ace in sd.Dacl) { if (ace.Mask.IsAccessGranted(COMAccessRights.ActivateContainer | COMAccessRights.ExecuteContainer)) { has_container = true; break; } } } AccessMask valid_access = access ? 0x7 : 0x1F; if (has_container) { valid_access |= (access ? 0x20 : 0x60); } SecurityDescriptorViewerControl control = new SecurityDescriptorViewerControl(); DocumentForm frm = new DocumentForm(control); string title = $"{(access ? "Access Security" : "Launch Security")}"; if (!string.IsNullOrWhiteSpace(view_name)) { title = $"{view_name} {title}"; } frm.Text = title; control.SetSecurityDescriptor(sd, typeof(COMAccessRights), new GenericMapping() { GenericExecute = valid_access, GenericRead = valid_access, GenericWrite = valid_access, GenericAll = valid_access }, valid_access); Application.Run(frm); return; } COMRegistry registry = null; if (database_file == null && autoload_config.AutoLoad && File.Exists(autoload_config.DatabasePath)) { try { registry = COMUtilities.LoadRegistry(null, autoload_config.DatabasePath); } catch { MessageBox.Show($"Error loading database {autoload_config.DatabasePath}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } if (registry == null) { registry = database_file != null?COMUtilities.LoadRegistry(null, database_file) : COMUtilities.LoadRegistry(null, mode); } if (delete_database && database_file != null) { File.Delete(database_file); } if (query_interfaces) { if (!COMUtilities.QueryAllInterfaces(null, registry.Clsids.Values, server_types, concurrent_queries, refresh_interfaces)) { Environment.Exit(1); } } if (save_file != null) { registry.Save(save_file); Environment.Exit(0); } _appContext = new MultiApplicationContext(new MainForm(registry)); if (enable_activation_filter) { COMUtilities.CoRegisterActivationFilter(new ActivationFilter()); } Application.Run(_appContext); autoload_config = new AutoSaveLoadConfiguration(); if (autoload_config.AutoSave) { registry.Save(autoload_config.DatabasePath); } } catch (Exception ex) { if (!(ex is OperationCanceledException)) { ShowError(null, ex); } } } }
/// <summary> /// Test AppInstanceId with leasing /// </summary> /// <param name="isDirectory">Set true if test lease on directory, otherwise set false</param> /// <param name="requestedLeaseState">Lease state that client will request</param> /// <param name="accessMask">Access mask that client is used to access file/directory</param> /// <param name="accessMaskToTriggerBreak">Access mask that a separate client is used to access file/directory to trigger LeaseBreak</param> private void AppInstanceIdTestWithLeasing(bool isDirectory, LeaseStateValues requestedLeaseState, AccessMask accessMask, AccessMask accessMaskToTriggerBreak) { testDirectory = CreateTestDirectory(uncSharePath); #region InitialOpen: Connect to server via Nic1 and create an open with AppInstanceId and leasing BaseTestSite.Log.Add( LogEntryKind.TestStep, "InitialOpen: Connect to share via Nic1."); FILEID fileIdForInitialOpen; uint treeIdForInitialOpen; ConnectShare(TestConfig.SutIPAddress, TestConfig.ClientNic1IPAddress, clientForInitialOpen, out treeIdForInitialOpen); #region Create an open with AppInstanceId and leasing BaseTestSite.Log.Add(LogEntryKind.TestStep, "InitialOpen: Create an open with AppInstanceId and leasing."); appInstanceId = Guid.NewGuid(); Smb2CreateContextResponse[] serverCreateContexts; status = clientForInitialOpen.Create( treeIdForInitialOpen, isDirectory ? testDirectory : fileName, isDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileIdForInitialOpen, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE, new Smb2CreateContextRequest[] { new Smb2CreateDurableHandleRequestV2 { CreateGuid = Guid.NewGuid(), }, new Smb2CreateRequestLeaseV2 { LeaseKey = Guid.NewGuid(), LeaseState = requestedLeaseState, }, new Smb2CreateAppInstanceId { AppInstanceId = appInstanceId } }, accessMask: accessMask, shareAccess: ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE); #endregion if (!isDirectory) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "InitialOpen: Write contents to file."); status = clientForInitialOpen.Write(treeIdForInitialOpen, fileIdForInitialOpen, contentWrite); } #endregion #region ReOpen: Connect to server via Nic2 and create an open with same AppInstanceId but without leasing BaseTestSite.Log.Add( LogEntryKind.TestStep, "ReOpen: Connect to same share via Nic2."); FILEID fileIdForReOpen; uint treeIdForReOpen; clientForReOpen.Smb2Client.LeaseBreakNotificationReceived += new Action<Packet_Header, LEASE_BREAK_Notification_Packet>(this.OnLeaseBreakNotificationReceived); ConnectShare(TestConfig.SutIPAddress, TestConfig.ClientNic2IPAddress, clientForReOpen, out treeIdForReOpen); #region Create an open with AppInstanceId but without leasing BaseTestSite.Log.Add(LogEntryKind.TestStep, "ReOpen: Create an open with AppInstanceId but without leasing."); status = clientForReOpen.Create( treeIdForReOpen, isDirectory ? testDirectory : fileName, isDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileIdForReOpen, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE, new Smb2CreateContextRequest[] { new Smb2CreateDurableHandleRequestV2 { CreateGuid = Guid.NewGuid(), }, new Smb2CreateAppInstanceId { // Use the same application instance id to force the server close all files // And will clear previous lease AppInstanceId = appInstanceId } }, accessMask: AccessMask.GENERIC_READ); #endregion if (!isDirectory) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "ReOpen: Read the contents written by InitialOpen."); status = clientForReOpen.Read(treeIdForReOpen, fileIdForReOpen, 0, (uint)contentWrite.Length, out contentRead); BaseTestSite.Assert.IsTrue( contentRead.Equals(contentWrite), "The written content should equal to read content."); } #endregion #region ReOpen: Access same file/directory from a separate client and expect SUCCESS if (!isDirectory) { Smb2FunctionalClient separateClient = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client3: Connect to same server."); separateClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress, TestConfig.ClientNic2IPAddress); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client3: Trigger a Lease Break."); TriggerBreakFromClient(separateClient, TestConfig.RequestDialects, isDirectory, LeaseStateValues.SMB2_LEASE_NONE, accessMaskToTriggerBreak); BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client3: Disconnect from the server."); separateClient.Disconnect(); } else { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client3: Attempt to create an empty file to trigger lease break."); sutProtocolController.CreateFile(Path.Combine(Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare), testDirectory), CurrentTestCaseName, string.Empty); } Thread.Sleep(500); BaseTestSite.Assert.AreNotEqual( true, isLeaseBreakReceived, "No LeaseBreak is expected to be received"); #endregion #region Client tear down BaseTestSite.Log.Add(LogEntryKind.TestStep, "ReOpen: Close file."); status = clientForReOpen.Close(treeIdForReOpen, fileIdForReOpen); BaseTestSite.Log.Add(LogEntryKind.TestStep, "ReOpen: Disconnect from the share."); status = clientForReOpen.TreeDisconnect(treeIdForReOpen); BaseTestSite.Log.Add(LogEntryKind.TestStep, "ReOpen: Log Off."); status = clientForReOpen.LogOff(); #endregion }
static Expression BindArrayAccess(Expression arr, Expression key, Expression ctx, AccessMask access, Expression rvalue) { Debug.Assert(key.Type == typeof(IntStringKey)); if (access.EnsureObject()) { // (arr ?? arr = []).EnsureItemObject(key) return(Expression.Call( EnsureNotNullPhpArray(arr), Cache.Operators.PhpArray_EnsureItemObject, key)); } else if (access.EnsureArray()) { // (arr ?? arr = []).EnsureItemArray(key) return(Expression.Call( EnsureNotNullPhpArray(arr), Cache.Operators.PhpArray_EnsureItemArray, key)); } else if (access.EnsureAlias()) { // (arr ?? arr = []).EnsureItemAlias(key) return(Expression.Call( EnsureNotNullPhpArray(arr), Cache.Operators.PhpArray_EnsureItemAlias, key)); } else if (access.WriteAlias()) { Debug.Assert(rvalue.Type == typeof(PhpAlias)); rvalue = ConvertExpression.Bind(rvalue, typeof(PhpAlias), ctx); // (arr ?? arr = []).SetItemAlias(key, value) return(Expression.Call( EnsureNotNullPhpArray(arr), Cache.Operators.PhpArray_SetItemAlias, key, rvalue)); } else if (access.Unset()) { Debug.Assert(rvalue == null); // remove key // arr.RemoveKey(name) // TODO: if (arr != null) return(Expression.Call(arr, Cache.Operators.PhpArray_RemoveKey, key)); } else if (access.Write()) { rvalue = ConvertExpression.Bind(rvalue, typeof(PhpValue), ctx); return(Expression.Call( EnsureNotNullPhpArray(arr), Cache.Operators.PhpArray_SetItemValue, key, rvalue)); } else { // read // TODO: (arr != null) ? arr[key] : (quiet ? void : ERROR) return(Expression.Call(arr, Cache.Operators.PhpArray_GetItemValue, key)); } }
/// <summary> /// Binds recursion check for property magic method. /// </summary> static Expression InvokeHandler(Expression ctx, Expression target, string field, Expression getter, AccessMask access, Expression @default = null, Type resultType = null) { // default resultType = resultType ?? Cache.Types.PhpValue[0]; @default = @default ?? Expression.Field(null, Cache.Properties.PhpValue_Null); // TODO: ERR field not found @default = ConvertExpression.Bind(@default, resultType, ctx); if (getter == null) { return(@default); } else { /* Template: * var token; * try { * return (token = new Context.RecursionCheckToken(_ctx, target, access))).IsInRecursion) * ? default * : getter; * } finally { * token.Dispose(); * } */ // recursion prevention key ~ do not invoke getter twice for the same field int subkey1 = access.Write() ? 1 : access.Unset() ? 2 : access.Isset() ? 3 : 4; int subkey = field.GetHashCode() ^ (1 << subkey1); // Template: RecursionCheckToken token; var tokenvar = Expression.Variable(typeof(Context.RecursionCheckToken), "token"); // Template: token = new RecursionCheckToken(_ctx, (object)target, (int)subkey)) var tokenassign = Expression.Assign(tokenvar, Expression.New(Cache.RecursionCheckToken.ctor_ctx_object_int, ctx, Expression.Convert(target, Cache.Types.Object[0]), Expression.Constant(subkey))); // bind getter access if (access.EnsureAlias() || access.EnsureArray() || access.EnsureObject()) { getter = BindAccess(getter, ctx, access, rvalue: null); } getter = ConvertExpression.Bind(getter, resultType, ctx); // return(Expression.Block(resultType, new[] { tokenvar }, Expression.TryFinally( Expression.Condition(Expression.Property(tokenassign, Cache.RecursionCheckToken.IsInRecursion), @default, getter), Expression.Call(tokenvar, Cache.RecursionCheckToken.Dispose) ))); } }
public static bool EnsureArray(this AccessMask flags) => (flags & AccessMask.EnsureArray) == AccessMask.EnsureArray;
/// <summary> /// Attempt to trigger LeaseBreakNotification from a separate client /// </summary> /// <param name="client">Client to trigger LeaseBreakNotification</param> /// <param name="requestDialect">Negotiate dialects</param> /// <param name="isDirectory">True value indicating to open a directory, false for a file</param> /// <param name="requestedLeaseState">LeaseState when open the directory or file</param> /// <param name="accessMask">AccessMask when open the directory or file</param> private void TriggerBreakFromClient( Smb2FunctionalClient client, DialectRevision[] requestDialect, bool isDirectory, LeaseStateValues requestedLeaseState, AccessMask accessMask) { BaseTestSite.Log.Add( LogEntryKind.Debug, "Trigger a lease break notification by accessing same file/directory from a separate client with LeaseState {0} and AccessMask {1}", requestedLeaseState, accessMask); #region Negotiate status = client.Negotiate( requestDialect, TestConfig.IsSMB1NegotiateEnabled, capabilityValue: Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES); #endregion #region SESSION_SETUP status = client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); #endregion #region TREE_CONNECT to share uint treeId; status = client.TreeConnect(uncSharePath, out treeId); #endregion #region CREATE FILEID fileId; Smb2CreateContextResponse[] serverCreateContexts; status = client.Create( treeId, isDirectory ? testDirectory : fileName, isDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE, new Smb2CreateContextRequest[] { new Smb2CreateRequestLeaseV2 { LeaseKey = Guid.NewGuid(), LeaseState = requestedLeaseState } }, accessMask: accessMask); #endregion BaseTestSite.Log.Add( LogEntryKind.Debug, "Finish triggering lease break notification"); }
public static bool EnsureAlias(this AccessMask flags) => (flags & AccessMask.ReadRef) == AccessMask.ReadRef;
public static bool Quiet(this AccessMask flags) => (flags & AccessMask.ReadQuiet) != 0;
public static bool Read(this AccessMask flags) => (flags & AccessMask.Read) != 0;
public static extern SafeFileHandle CreateFile(string lpFileName, AccessMask dwDesiredAccess, System.IO.FileShare dwShareMode, uint SecurityAttributes, System.IO.FileMode dwCreationDisposition, FileAttributesAndFlags dwFlagsAndAttributes, IntPtr hTemplateFile);
public static bool WriteAlias(this AccessMask flags) => (flags & AccessMask.WriteRef) == AccessMask.WriteRef;
public NTStatus CreateFile(out object handle, out FileStatus fileStatus, string path, AccessMask desiredAccess, FileAttributes fileAttributes, ShareAccess shareAccess, CreateDisposition createDisposition, CreateOptions createOptions, SecurityContext securityContext) { handle = null; fileStatus = FileStatus.FILE_DOES_NOT_EXIST; CreateRequest request = new CreateRequest(); request.Name = path; request.DesiredAccess = desiredAccess; request.FileAttributes = fileAttributes; request.ShareAccess = shareAccess; request.CreateDisposition = createDisposition; request.CreateOptions = createOptions; request.ImpersonationLevel = ImpersonationLevel.Impersonation; TrySendCommand(request); SMB2Command response = m_client.WaitForCommand(SMB2CommandName.Create); if (response != null) { if (response.Header.Status == NTStatus.STATUS_SUCCESS && response is CreateResponse) { CreateResponse createResponse = ((CreateResponse)response); handle = createResponse.FileId; fileStatus = ToFileStatus(createResponse.CreateAction); } return(response.Header.Status); } return(NTStatus.STATUS_INVALID_SMB); }
public static bool Write(this AccessMask flags) => (flags & AccessMask.Write) != 0;
public GetFieldBinder(string name, RuntimeTypeHandle classContext, RuntimeTypeHandle returnType, AccessMask access) { _name = name; _returnType = Type.GetTypeFromHandle(returnType); // should correspond to AccessFlags _classContext = Type.GetTypeFromHandle(classContext); _access = access & AccessMask.ReadMask; }
public static bool Isset(this AccessMask flags) => (flags & AccessMask.Isset) == AccessMask.Isset;
private void UpdateTokenData() { UserGroup user = _token.User; txtUsername.Text = user.ToString(); txtUserSid.Text = user.Sid.ToString(); TokenType tokentype = _token.TokenType; txtTokenType.Text = _token.TokenType.ToString(); if (_token.TokenType == TokenType.Impersonation) { SecurityImpersonationLevel implevel = _token.ImpersonationLevel; txtImpLevel.Text = implevel.ToString(); } else { txtImpLevel.Text = "N/A"; } txtTokenId.Text = FormatLuid(_token.Id); txtModifiedId.Text = FormatLuid(_token.ModifiedId); txtAuthId.Text = FormatLuid(_token.AuthenticationId); if (Enum.IsDefined(typeof(TokenIntegrityLevel), _token.IntegrityLevel)) { comboBoxIL.SelectedItem = _token.IntegrityLevel; comboBoxILForDup.SelectedItem = _token.IntegrityLevel; } else { comboBoxIL.Text = _token.IntegrityLevel.ToString(); comboBoxILForDup.Text = _token.IntegrityLevel.ToString(); } txtSessionId.Text = _token.SessionId.ToString(); if (_token.IsAccessGranted(TokenAccessRights.QuerySource)) { txtSourceName.Text = _token.Source.SourceName; txtSourceId.Text = FormatLuid(_token.Source.SourceIdentifier); } else { txtSourceName.Text = "N/A"; txtSourceId.Text = "N/A"; } TokenElevationType evtype = _token.ElevationType; txtElevationType.Text = evtype.ToString(); txtIsElevated.Text = _token.Elevated.ToString(); txtOriginLoginId.Text = FormatLuid(_token.Origin); btnLinkedToken.Enabled = evtype != TokenElevationType.Default; UpdateGroupList(); txtPrimaryGroup.Text = _token.PrimaryGroup.Name; txtOwner.Text = _token.Owner.Name; Acl defdacl = _token.DefaultDacl; if (!defdacl.NullAcl) { foreach (Ace ace in defdacl) { UserGroup group = new UserGroup(ace.Sid, GroupAttributes.None); ListViewItem item = new ListViewItem(group.ToString()); AccessMask mask = GenericAccessRights.GenericAll | GenericAccessRights.GenericExecute | GenericAccessRights.GenericRead | GenericAccessRights.GenericWrite; string maskstr; if ((ace.Mask & ~mask).HasAccess) { maskstr = String.Format("0x{0:X08}", ace.Mask); } else { maskstr = ace.Mask.ToGenericAccess().ToString(); } item.SubItems.Add(maskstr); item.SubItems.Add(ace.AceFlags.ToString()); item.SubItems.Add(ace.AceType.ToString()); listViewDefDacl.Items.Add(item); } } else { listViewDefDacl.Items.Add("No Default DACL"); } listViewDefDacl.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent); listViewDefDacl.AutoResizeColumns(ColumnHeaderAutoResizeStyle.HeaderSize); if (_token.Restricted) { PopulateGroupList(listViewRestrictedSids, _token.RestrictedSids); } else { tabControlMain.TabPages.Remove(tabPageRestricted); } if (_token.AppContainer) { PopulateGroupList(listViewCapabilities, _token.Capabilities); txtACNumber.Text = _token.AppContainerNumber.ToString(); txtPackageSid.Text = _token.AppContainerSid.Name; } else { tabControlMain.TabPages.Remove(tabPageAppContainer); } txtUIAccess.Text = _token.UIAccess.ToString(); txtSandboxInert.Text = _token.SandboxInert.ToString(); bool virtAllowed = _token.VirtualizationAllowed; txtVirtualizationAllowed.Text = virtAllowed.ToString(); btnToggleVirtualizationEnabled.Enabled = virtAllowed; if (virtAllowed) { txtVirtualizationEnabled.Text = _token.VirtualizationEnabled.ToString(); } else { txtVirtualizationEnabled.Text = "N/A"; } txtMandatoryILPolicy.Text = _token.MandatoryPolicy.ToString(); txtHandleAccess.Text = _token.GrantedAccess.ToString(); UpdatePrivileges(); UpdateSecurityAttributes(); }
public static bool IsNotRef(this AccessMask flags) => (flags & AccessMask.IsNotRef) != 0;
static Expression BindAccess(Expression expr, Expression ctx, AccessMask access, Expression rvalue) { if (access.EnsureObject()) { if (expr.Type == typeof(PhpAlias)) { // ((PhpAlias)fld).EnsureObject() expr = Expression.Call(expr, Cache.Operators.PhpAlias_EnsureObject); } else if (expr.Type == typeof(PhpValue)) { // ((PhpValue)fld).EnsureObject() expr = Expression.Call(expr, Cache.Operators.PhpValue_EnsureObject); } else { // getter // TODO: ensure it is not null Debug.Assert(!expr.Type.GetTypeInfo().IsValueType); } } else if (access.EnsureArray()) { if (expr.Type == typeof(PhpAlias)) { // ((PhpAlias)fld).EnsureArray() expr = Expression.Call(expr, Cache.Operators.PhpAlias_EnsureArray); } else if (expr.Type == typeof(PhpValue)) { // ((PhpValue)fld).EnsureArray() expr = Expression.Call(expr, Cache.Operators.PhpValue_EnsureArray); } else if (expr.Type == typeof(PhpArray)) { // (PhpArray)fld // TODO: ensure it is not null } else { // Operators.EnsureArray( fld ) // TODO: string expr = Expression.Call(Cache.Operators.Object_EnsureArray, expr); } } else if (access.EnsureAlias()) { if (expr.Type == typeof(PhpAlias)) { // (PhpAlias)getter } else if (expr.Type == typeof(PhpValue)) { // ((PhpValue)fld).EnsureAlias() expr = Expression.Call(expr, Cache.Operators.PhpValue_EnsureAlias); } else { // getter // cannot read as reference } } else if (access.WriteAlias()) { // write alias Debug.Assert(rvalue.Type == typeof(PhpAlias)); rvalue = ConvertExpression.Bind(rvalue, typeof(PhpAlias), ctx); if (expr.Type == typeof(PhpAlias)) { // ok } else if (expr.Type == typeof(PhpValue)) { // fld = PhpValue.Create(alias) rvalue = Expression.Call(typeof(PhpValue).GetMethod("Create", Cache.Types.PhpAlias), rvalue); } else { // fld is not aliasable Debug.Assert(false, "Cannot assign aliased value to field of type " + expr.Type.ToString()); rvalue = ConvertExpression.Bind(rvalue, expr.Type, ctx); } expr = Expression.Assign(expr, rvalue); } else if (access.Unset()) { Debug.Assert(rvalue == null); expr = Expression.Assign(expr, ConvertExpression.BindDefault(expr.Type)); } else if (access.Write()) { // write by value if (expr.Type == typeof(PhpAlias)) { // Template: fld.Value = (PhpValue)value expr = Expression.Assign(Expression.Field(expr, Cache.Properties.PhpAlias_Value), ConvertExpression.Bind(rvalue, typeof(PhpValue), ctx)); } else if (expr.Type == typeof(PhpValue)) { // Template: Operators.SetValue(ref fld, (PhpValue)value) expr = Expression.Call(Cache.Operators.SetValue_PhpValueRef_PhpValue, expr, ConvertExpression.Bind(rvalue, typeof(PhpValue), ctx)); } else { // Template: fld = value // default behaviour by value to value expr = Expression.Assign(expr, ConvertExpression.Bind(rvalue, expr.Type, ctx)); } } else if (access.ReadValue()) { // dereference if (expr.Type == typeof(PhpValue)) { // Template: value.GetValue().DeepCopy() expr = Expression.Call(expr, Cache.Operators.PhpValue_GetValue); } else if (expr.Type == typeof(PhpAlias)) { // Template: alias.Value // expecting alias cannot be null ref expr = Expression.Field(expr, Cache.Properties.PhpAlias_Value); } } else if (access.ReadValueCopy()) { // dereference & copy if (expr.Type == typeof(PhpValue)) { // Template: value.GetValue().DeepCopy() expr = Expression.Call(Expression.Call(expr, Cache.Operators.PhpValue_GetValue), Cache.Operators.PhpValue_DeepCopy); } else if (expr.Type == typeof(PhpAlias)) { // TODO: specify - ReadCopy | ReadValue | ReadValueCopy - currently not consistent } } // Read, IsSet return(expr); }
private protected override void WriteAccessCheckResult(string name, string type_name, AccessMask granted_access, GenericMapping generic_mapping, SecurityDescriptor sd, Type enum_type, bool is_directory, TokenInformation token_info) { _cmdlet.WriteAccessCheckResult(name, type_name, granted_access, generic_mapping, sd, enum_type, is_directory, token_info); }
public static Expression BindField(PhpTypeInfo type, Type classCtx, Expression target, string field, Expression ctx, AccessMask access, Expression rvalue) { if (access.Write() != (rvalue != null)) { throw new ArgumentException(); } // lookup a declared field for (var t = type; t != null; t = t.BaseType) { foreach (var p in t.DeclaredFields.GetPhpProperties(field)) { if (p.IsStatic == (target == null) && p.IsVisible(classCtx)) { return(BindAccess(p.Bind(ctx, target), ctx, access, rvalue)); } } } // // runtime fields & magic methods // if (type.RuntimeFieldsHolder != null) // we don't handle magic methods without the runtime fields { var runtimeflds = Expression.Field(target, type.RuntimeFieldsHolder); // Template: target->__runtime_fields var fieldkey = Expression.Constant(new IntStringKey(field)); // Template: IntStringKey(field) var resultvar = Expression.Variable(Cache.Types.PhpValue[0], "result"); // Template: PhpValue result; // Template: runtimeflds != null && runtimeflds.TryGetValue(field, out result) var trygetfield = Expression.AndAlso(Expression.ReferenceNotEqual(runtimeflds, Expression.Constant(null)), Expression.Call(runtimeflds, Cache.Operators.PhpArray_TryGetValue, fieldkey, resultvar)); // Template: runtimeflds != null && runtimeflds.ContainsKey(field) var containsfield = Expression.AndAlso(Expression.ReferenceNotEqual(runtimeflds, Expression.Constant(null)), Expression.Call(runtimeflds, Cache.Operators.PhpArray_ContainsKey, fieldkey)); Expression result; // if (access.EnsureObject()) { // (object)target->field-> // Template: runtimeflds.EnsureObject(key) result = Expression.Call(EnsureNotNullPhpArray(runtimeflds), Cache.Operators.PhpArray_EnsureItemObject, fieldkey); var __get = BindMagicMethod(type, classCtx, target, ctx, TypeMethods.MagicMethods.__get, field, null); if (__get != null) { // Template: runtimeflds.Contains(key) ? runtimeflds.EnsureObject(key) : ( __get(key) ?? runtimeflds.EnsureObject(key)) return(Expression.Condition(containsfield, Expression.Call(runtimeflds, Cache.Operators.PhpArray_EnsureItemObject, fieldkey), InvokeHandler(ctx, target, field, __get, access, result, Cache.Types.Object[0]))); } else { return(result); } } else if (access.EnsureArray()) { // (IPhpArray)target->field[] = result = Expression.Call(EnsureNotNullPhpArray(runtimeflds), Cache.Operators.PhpArray_EnsureItemArray, fieldkey); var __get = BindMagicMethod(type, classCtx, target, ctx, TypeMethods.MagicMethods.__get, field, null); if (__get != null) { // Template: runtimeflds.Contains(key) ? runtimeflds.EnsureArray(key) : ( __get(key) ?? runtimeflds.EnsureArray(key)) return(Expression.Condition(containsfield, Expression.Call(runtimeflds, Cache.Operators.PhpArray_EnsureItemArray, fieldkey), InvokeHandler(ctx, target, field, __get, access, result, typeof(IPhpArray)))); } else { // runtimeflds.EnsureItemArray(key) return(result); } } else if (access.EnsureAlias()) { // (PhpAlias)&target->field result = Expression.Call(EnsureNotNullPhpArray(runtimeflds), Cache.Operators.PhpArray_EnsureItemAlias, fieldkey); var __get = BindMagicMethod(type, classCtx, target, ctx, TypeMethods.MagicMethods.__get, field, null); if (__get != null) { // Template: runtimeflds.Contains(key) ? runtimeflds.EnsureItemAlias(key) : ( __get(key) ?? runtimeflds.EnsureItemAlias(key)) return(Expression.Condition(containsfield, Expression.Call(runtimeflds, Cache.Operators.PhpArray_EnsureItemAlias, fieldkey), InvokeHandler(ctx, target, field, __get, access, result, Cache.Types.PhpAlias[0]))); } else { // runtimeflds.EnsureItemAlias(key) return(result); } } else if (access.Unset()) { // unset(target->field) // Template: if (!runtimeflds.RemoveKey(key)) __unset(key) var removekey = Expression.Call(runtimeflds, Cache.Operators.PhpArray_RemoveKey, fieldkey); var __unset = BindMagicMethod(type, classCtx, target, ctx, TypeMethods.MagicMethods.__unset, field, null); if (__unset != null) { return(Expression.IfThen( Expression.OrElse(Expression.ReferenceEqual(runtimeflds, Expression.Constant(null)), Expression.IsFalse(removekey)), InvokeHandler(ctx, target, field, __unset, access, Expression.Block(), typeof(void)))); } else { // if (runtimeflds != null) runtimeflds.RemoveKey(key) return(Expression.IfThen( Expression.ReferenceNotEqual(runtimeflds, Expression.Constant(null)), removekey)); } } else if (access.Write()) { var __set = BindMagicMethod(type, classCtx, target, ctx, TypeMethods.MagicMethods.__set, field, rvalue); if (access.WriteAlias()) { // target->field = (PhpAlias)&rvalue Debug.Assert(rvalue.Type == typeof(PhpAlias)); rvalue = ConvertExpression.Bind(rvalue, typeof(PhpAlias), ctx); // EnsureNotNull(runtimeflds).SetItemAlias(key, rvalue) result = Expression.Call(EnsureNotNullPhpArray(runtimeflds), Cache.Operators.PhpArray_SetItemAlias, fieldkey, rvalue); if (__set != null) { // if (ContainsKey(key)) ? runtimeflds.SetItemAlias(rvalue) : (__set(key, rvalue) ?? runtimeflds.SetItemAlias(key, rvalue) return(Expression.Condition(containsfield, Expression.Call(runtimeflds, Cache.Operators.PhpArray_SetItemAlias, fieldkey, rvalue), InvokeHandler(ctx, target, field, __set, access, result, typeof(void)))); } else { return(result); } } else { // target->field = rvalue rvalue = ConvertExpression.Bind(rvalue, typeof(PhpValue), ctx); /* Template: * return runtimeflds != null && runtimeflds.ContainsKey(field) * ? runtimeflds.SetItemValue(key, rvalue) * : (__set(field, value) ?? runtimeflds.SetItemValue(key, value)) */ result = Expression.Call(EnsureNotNullPhpArray(runtimeflds), Cache.Operators.PhpArray_SetItemValue, fieldkey, rvalue); if (__set != null) { return(Expression.Condition(containsfield, Expression.Call(runtimeflds, Cache.Operators.PhpArray_SetItemValue, fieldkey, rvalue), InvokeHandler(ctx, target, field, __set, access, result, typeof(void)))); } else { return(result); } } } else if (access.Isset()) { // isset(target->field) var __isset = BindMagicMethod(type, classCtx, target, ctx, TypeMethods.MagicMethods.__isset, field, null); // Template: (TryGetField(result) || (bool)__isset(key)) ? true : void result = Expression.Condition(Expression.OrElse( trygetfield, ConvertExpression.BindToBool(InvokeHandler(ctx, target, field, __isset, access))), Expression.Property(null, Cache.Properties.PhpValue_True), Expression.Field(null, Cache.Properties.PhpValue_Void)); } else { // = target->field /* Template: * return runtimeflds.TryGetValue(field, out result) ? result : (__get(field) ?? ERR); */ var __get = BindMagicMethod(type, classCtx, target, ctx, TypeMethods.MagicMethods.__get, field, null); result = Expression.Condition(trygetfield, resultvar, InvokeHandler(ctx, target, field, __get, access)); // TODO: @default = { ThrowError; return null; } } // return(Expression.Block(result.Type, new[] { resultvar }, result)); } // TODO: IDynamicMetaObject // return(null); }
private protected override void RunAccessCheck(IEnumerable <TokenEntry> tokens) { if (CheckScmAccess) { SecurityDescriptor sd = ServiceUtils.GetScmSecurityDescriptor(); GenericMapping scm_mapping = ServiceUtils.GetScmGenericMapping(); foreach (TokenEntry token in tokens) { AccessMask granted_access = NtSecurity.GetMaximumAccess(sd, token.Token, scm_mapping); WriteAccessCheckResult("SCM", "SCM", granted_access, scm_mapping, sd, typeof(ServiceControlManagerAccessRights), false, token.Information); } } else { IEnumerable <RunningService> services = GetServices(); InternalGetAccessibleFileCmdlet file_cmdlet = null; HashSet <string> checked_files = new HashSet <string>(StringComparer.OrdinalIgnoreCase); if (CheckFiles) { file_cmdlet = new InternalGetAccessibleFileCmdlet(this) { FormatWin32Path = true }; } GenericMapping service_mapping = ServiceUtils.GetServiceGenericMapping(); AccessMask access_rights = service_mapping.MapMask(AccessRights); foreach (var service in services.Where(s => s?.SecurityDescriptor != null)) { foreach (TokenEntry token in tokens) { AccessMask granted_access = NtSecurity.GetMaximumAccess(service.SecurityDescriptor, token.Token, service_mapping); ServiceAccessRights trigger_access = GetTriggerAccess(service, token.Token); if (IsAccessGranted(granted_access, access_rights)) { WriteObject(new ServiceAccessCheckResult(service.Name, granted_access | trigger_access, service.SecurityDescriptor, token.Information, trigger_access, granted_access.ToSpecificAccess <ServiceAccessRights>(), service)); } } if (CheckFiles) { if (!string.IsNullOrWhiteSpace(service.ImagePath) && File.Exists(service.ImagePath) && checked_files.Add(service.ImagePath)) { file_cmdlet.RunAccessCheckPathInternal(tokens, service.ImagePath); } if (!string.IsNullOrWhiteSpace(service.ServiceDll) && File.Exists(service.ServiceDll) && checked_files.Add(service.ServiceDll)) { file_cmdlet.RunAccessCheckPathInternal(tokens, service.ServiceDll); } } } } }
private void AddAclTab(TabPage tab_page, AclViewerControl control, Acl acl, Type access_type, GenericMapping mapping, AccessMask valid_access) { if (acl == null) { tabControl.TabPages.Remove(tab_page); } else { if (acl.NullAcl) { tab_page.Controls.Remove(control); tab_page.Controls.Add(new Label() { Text = "NULL ACL", Dock = DockStyle.Fill }); } else { control.SetAcl(acl, access_type, mapping, valid_access); } } }
private static string AccessMaskToString(AccessMask granted_access, NtType type) { return(NtObjectUtils.GrantedAccessAsString(granted_access, type.GenericMapping, typeof(KeyAccessRights), _map_to_generic)); }
/// <summary> /// Test FileServer failover with leasing /// </summary> /// <param name="isDirectory">True to indicate target is directory, otherwise is file</param> /// <param name="requestedLeaseState">Original LeaseState to request for durable open</param> /// <param name="accessMask">Original AccessMask to request for durable open</param> /// <param name="accessMaskToTriggerBreak">AccessMask that a separate client to request to open the same file/directory to trigger LeaseBreakNotification</param> private void FileServerFailoverWithLeasing(bool isDirectory, LeaseStateValues requestedLeaseState, AccessMask accessMask, AccessMask accessMaskToTriggerBreak) { clientAfterFailover.Smb2Client.LeaseBreakNotificationReceived += new Action<Packet_Header, LEASE_BREAK_Notification_Packet>(base.OnLeaseBreakNotificationReceived); FILEID fileIdBeforeFailover; uint treeIdBeforeFailover; BaseTestSite.Log.Add(LogEntryKind.TestStep, "BeforeFailover: Connect to general file server {0}.", TestConfig.ClusteredFileServerName); ConnectGeneralFileServerBeforeFailover(TestConfig.ClusteredFileServerName, out treeIdBeforeFailover); #region CREATE a durable open with flag DHANDLE_FLAG_PERSISTENT BaseTestSite.Log.Add(LogEntryKind.TestStep, "BeforeFailover: CREATE a durable open with flag DHANDLE_FLAG_PERSISTENT."); Smb2CreateContextResponse[] serverCreateContexts; createGuid = Guid.NewGuid(); leaseKey = Guid.NewGuid(); status = clientBeforeFailover.Create( treeIdBeforeFailover, isDirectory ? testDirectory : fileName, isDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileIdBeforeFailover, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE, new Smb2CreateContextRequest[] { new Smb2CreateDurableHandleRequestV2 { CreateGuid = createGuid, Flags = CREATE_DURABLE_HANDLE_REQUEST_V2_Flags.DHANDLE_FLAG_PERSISTENT, Timeout = 3600000, }, new Smb2CreateRequestLeaseV2 { LeaseKey = leaseKey, LeaseState = requestedLeaseState, } }, accessMask: accessMask); #endregion BaseTestSite.Log.Add( LogEntryKind.TestStep, "Do failover of the file server."); FailoverServer(currentAccessIp, TestConfig.ClusteredFileServerName, FileServerType.GeneralFileServer); FILEID fileIdAfterFailover = FILEID.Zero; uint treeIdAfterFailover; BaseTestSite.Log.Add(LogEntryKind.TestStep, "AfterFailover: Reconnect to the same general file server {0}.", TestConfig.ClusteredFileServerName); ReconnectServerAfterFailover(TestConfig.ClusteredFileServerName, FileServerType.GeneralFileServer, out treeIdAfterFailover); #region CREATE to reconnect previous duarable open with flag DHANDLE_FLAG_PERSISTENT BaseTestSite.Log.Add(LogEntryKind.TestStep, "AfterFailover: CREATE to reconnect previous duarable open with flag DHANDLE_FLAG_PERSISTENT."); status = DoUntilSucceed( () => clientAfterFailover.Create( treeIdAfterFailover, isDirectory ? testDirectory : fileName, isDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileIdAfterFailover, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE, new Smb2CreateContextRequest[] { new Smb2CreateDurableHandleReconnectV2 { FileId = new FILEID { Persistent = fileIdBeforeFailover.Persistent }, CreateGuid = createGuid, Flags = CREATE_DURABLE_HANDLE_RECONNECT_V2_Flags.DHANDLE_FLAG_PERSISTENT }, new Smb2CreateRequestLeaseV2 { LeaseKey = leaseKey, LeaseState = requestedLeaseState, } }, accessMask: accessMask, checker: (header, response) => { }), TestConfig.FailoverTimeout, "Retry Create until succeed within timeout span"); #endregion // Create a timer that signals the delegate to invoke CheckBreakNotification Timer timer = new Timer(CheckBreakNotification, treeIdAfterFailover, 0, Timeout.Infinite); base.clientToAckLeaseBreak = clientAfterFailover; Smb2FunctionalClient clientTriggeringBreak = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite); clientTriggeringBreak.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.ClusteredFileServerName, currentAccessIp); // Request CREATE from Client3 to trigger lease break notification and the operation will be blocked until notification is acknowledged or 35 seconds timeout BaseTestSite.Log.Add( LogEntryKind.TestStep, "AfterFailover: Request CREATE from Client3 to trigger lease break notification and the operation will be blocked until notification is acknowledged or 35 seconds timeout."); TriggerBreakFromClient( clientTriggeringBreak, TestConfig.RequestDialects, TestConfig.ClusteredFileServerName, isDirectory, LeaseStateValues.SMB2_LEASE_NONE, accessMaskToTriggerBreak); BaseTestSite.Log.Add( LogEntryKind.TestStep, "AfterFailover: Sleep 1 second to wait completion of LeaseBreakNotification check and acknowledgement in background thread"); Thread.Sleep(1000); status = clientAfterFailover.Close(treeIdAfterFailover, fileIdAfterFailover); status = clientAfterFailover.TreeDisconnect(treeIdAfterFailover); status = clientAfterFailover.LogOff(); }
private void WriteAccessCheckResult(ProcessDetails process, ThreadDetails thread, AccessMask granted_access, GenericMapping generic_mapping, SecurityDescriptor sd, TokenInformation token) { if (thread == null) { WriteObject(new ProcessAccessCheckResult(process.Name, process.ImagePath, process.ProcessId, process.SessionId, process.CommandLine, granted_access, false, process.IsDeleting, process.User, _process_type, sd, token)); } else { WriteObject(new ThreadAccessCheckResult(process.Name, process.ImagePath, thread.ThreadId, thread.Description, process.ProcessId, process.IsDeleting, process.SessionId, process.CommandLine, granted_access, process.User, _thread_type, sd, token)); } }
/// <summary> /// Create an open from client, this include NEGOTIATE and SESSION_SETUP with server, TREE_CONNECT to the share and CREATE an open to file/directory /// </summary> /// <param name="client">Client used to take the operation</param> /// <param name="clientGuid">Client GUID for negotiation</param> /// <param name="targetName">File/directory name for the open</param> /// <param name="isDirectory">Set true if create open to a directory, set false if create open to a file</param> /// <param name="accessMask">Desired access when create the open</param> /// <param name="treeId">Out param for tree id used to connect to the share</param> /// <param name="fileId">Out param for file id that is associated with the open</param> /// <param name="shareAccess">Optional param for share access when create the open</param> /// <returns>Status value returned from CREATE request</returns> private uint CreateOpenFromClient(Smb2FunctionalClient client, Guid clientGuid, string targetName, bool isDirectory, LeaseStateValues requestLeaseState, AccessMask accessMask, out uint treeId, out FILEID fileId, ShareAccess_Values shareAccess = ShareAccess_Values.FILE_SHARE_DELETE | ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE) { #region Negotiate BaseTestSite.Log.Add( LogEntryKind.TestStep, "Client {0} sends NEGOTIATE request with the following capabilities: Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES.", clientGuid.ToString()); client.Negotiate( TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled, capabilityValue: Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES, clientGuid: clientGuid, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "Negotiation is expected success, actually server returns {0}", Smb2Status.GetStatusCode(header.Status)); TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response); TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING, response); }); #endregion #region SESSION_SETUP BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client {0} sends SESSION_SETUP request.", clientGuid.ToString()); status = client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); #endregion #region TREE_CONNECT to share BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client {0} sends TREE_CONNECT request.", clientGuid.ToString()); status = client.TreeConnect(uncSharePath, out treeId); #endregion #region CREATE Smb2CreateContextResponse[] serverCreateContexts; CreateOptions_Values createOptions; if (isDirectory) { createOptions = CreateOptions_Values.FILE_DIRECTORY_FILE; } else { createOptions = CreateOptions_Values.FILE_NON_DIRECTORY_FILE; } // Include FILE_DELETE_ON_CLOSE if accessMask has DELETE if ((accessMask & AccessMask.DELETE) == AccessMask.DELETE) { createOptions = createOptions | CreateOptions_Values.FILE_DELETE_ON_CLOSE; } BaseTestSite.Log.Add( LogEntryKind.TestStep, "Client {0} sends CREATE request with the lease state in SMB2_CREATE_REQUEST_LEASE_V2 set to {1}.", clientGuid.ToString(), requestLeaseState); status = client.Create( treeId, targetName, createOptions, out fileId, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE, new Smb2CreateContextRequest[] { new Smb2CreateRequestLeaseV2 { LeaseKey = clientGuid, LeaseState = requestLeaseState } }, accessMask: accessMask, shareAccess: shareAccess, checker: (header, response) => { }); return status; #endregion }
private void CheckAccess(TokenEntry token, ProcessDetails process, ThreadDetails thread, NtType type, AccessMask access_rights, SecurityDescriptor sd) { AccessMask granted_access = NtSecurity.GetMaximumAccess(sd, token.Token, type.GenericMapping); if (IsAccessGranted(granted_access, access_rights)) { WriteAccessCheckResult(process, thread, granted_access, type.GenericMapping, sd, token.Information); } }
internal static extern NtStatus LsaOpenPolicy( IntPtr systemName, ref LsaObjectAttributes objectAttributes, AccessMask desiredAccess, out IntPtr policyHandle);
/// <summary> /// Check the status code of create response /// </summary> /// <param name="isNonAdmin">true for non admin credential</param> /// <param name="createOption">The create option set in create request</param> /// <param name="accessMask">The access mark set in create request</param> /// <param name="header">Header of create response</param> /// <param name="response">create response</param> /// <param name="fileNameType">file name type</param> private void CheckCreateResponse(bool isNonAdmin, CreateOptions_Values createOption, AccessMask accessMask, Packet_Header header, CREATE_Response response, FileNameType fileNameType) { switch (fileNameType) { case FileNameType.SymbolicLinkInMiddle: { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_STOPPED_ON_SYMLINK, header.Status, "3.3.5.9: If any intermediate component of the path specified in the create request is a symbolic link, " + "the server MUST return an error as specified in section 2.2.2.1. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); break; } case FileNameType.SymbolicLinkAtLast: { if (!createOption.HasFlag(CreateOptions_Values.FILE_OPEN_REPARSE_POINT)) { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_STOPPED_ON_SYMLINK, header.Status, "3.3.5.9: If the final component of the path is a symbolic link, the server behavior depends on whether the flag FILE_OPEN_REPARSE_POINT was specified in the CreateOptions field of the request. " + "If FILE_OPEN_REPARSE_POINT was specified, the server MUST open the underlying file or directory and return a handle to it. " + "Otherwise, the server MUST return an error as specified in section 2.2.2.1. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); } break; } case FileNameType.InvalidSymbolicLink: { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_STOPPED_ON_SYMLINK, header.Status, "3.3.5.9: If the underlying object store returns a failure indicating that the attempted open operation failed due to the presence of a symbolic link in the target path name, " + "the server MUST fail the create operation with the error code STATUS_STOPPED_ON_SYMLINK. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); break; } case FileNameType.NotExistedValidFileName: { if (createOption.HasFlag(CreateOptions_Values.FILE_DELETE_ON_CLOSE) && !(accessMask.HasFlag(AccessMask.DELETE) || accessMask.HasFlag(AccessMask.GENERIC_ALL))) { if (testConfig.Platform == Platform.NonWindows) { BaseTestSite.Assert.AreNotEqual( Smb2Status.STATUS_SUCCESS, header.Status, "3.3.5.9: If the FILE_DELETE_ON_CLOSE flag is set in CreateOptions and any of the following conditions is TRUE, the server SHOULD<242> fail the request with STATUS_ACCESS_DENIED. " + "DesiredAccess does not include DELETE or GENERIC_ALL. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); } else if (testConfig.Platform == Platform.WindowsServer2008 || testConfig.Platform == Platform.WindowsServer2008R2) { //TD does not specify the behavior of windows 2008 and 2008R2, not check here } else if(testConfig.Platform == Platform.WindowsServer2012) { //For platform windows 2012 BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_INVALID_PARAMETER, header.Status, "3.3.5.9: If the FILE_DELETE_ON_CLOSE flag is set in CreateOptions and any of the following conditions is TRUE, the server SHOULD<242> fail the request with STATUS_ACCESS_DENIED. " + "DesiredAccess does not include DELETE or GENERIC_ALL. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); } else { //For platform windows 2012R2 and above BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_ACCESS_DENIED, header.Status, "3.3.5.9: If the FILE_DELETE_ON_CLOSE flag is set in CreateOptions and any of the following conditions is TRUE, the server SHOULD<242> fail the request with STATUS_ACCESS_DENIED. " + "DesiredAccess does not include DELETE or GENERIC_ALL. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); } } else if (createOption.HasFlag(CreateOptions_Values.FILE_DELETE_ON_CLOSE) && isNonAdmin) { //NonAdminAccountCredential does not include DELETE or GENERIC_ALL in MaximalAccess if (testConfig.Platform == Platform.NonWindows) { BaseTestSite.Assert.AreNotEqual( Smb2Status.STATUS_SUCCESS, header.Status, "3.3.5.9: If the FILE_DELETE_ON_CLOSE flag is set in CreateOptions and any of the following conditions is TRUE, the server SHOULD<242> fail the request with STATUS_ACCESS_DENIED. " + "Treeconnect.MaximalAccess does not include DELETE or GENERIC_ALL. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); } else if (testConfig.Platform == Platform.WindowsServer2008 || testConfig.Platform == Platform.WindowsServer2008R2) { //TD does not specify te behavior of windows 2008 and 2008R2, not check here } else { //For platform win2012 and 2012R2 BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_ACCESS_DENIED, header.Status, "3.3.5.9: If the FILE_DELETE_ON_CLOSE flag is set in CreateOptions and any of the following conditions is TRUE, the server SHOULD<242> fail the request with STATUS_ACCESS_DENIED. " + "Treeconnect.MaximalAccess does not include DELETE or GENERIC_ALL. " + "Actually server returns with {0}.", Smb2Status.GetStatusCode(header.Status)); } } else { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should be successful, actually server returns with {1}.", header.Command, Smb2Status.GetStatusCode(header.Status)); } break; } case FileNameType.ExistedValidFileName: { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should be successful, actually server returns with {1}.", header.Command, Smb2Status.GetStatusCode(header.Status)); } break; default: throw new ArgumentException("fileNameType"); } }