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);
		}
Пример #3
0
 public SetFieldBinder(string name, RuntimeTypeHandle classContext, AccessMask access)
 {
     _name         = name;
     _classContext = Type.GetTypeFromHandle(classContext);
     _access       = access & AccessMask.WriteMask;
 }
Пример #4
0
 internal static extern SafeKernelObjectHandle CreateWindowStation(
     string lpwinsta,
     int dwFlags,
     AccessMask dwDesiredAccess,
     SECURITY_ATTRIBUTES lpsa
     );
Пример #5
0
 public GetClassConstBinder(string name, RuntimeTypeHandle classContext, RuntimeTypeHandle returnType, AccessMask access)
     : base(name, classContext, returnType, access)
 {
 }
Пример #6
0
 /// <summary>
 /// Will return desired FileAccess rights to the file data.
 /// </summary>
 public static FileAccess ToFileAccess(AccessMask desiredAccess)
 {
     return(ToFileAccess((FileAccessMask)desiredAccess));
 }
Пример #7
0
        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.");
        }
Пример #10
0
 public static bool EnsureObject(this AccessMask flags) => (flags & AccessMask.EnsureObject) == AccessMask.EnsureObject;
Пример #11
0
        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);
                }
            }
        }
Пример #12
0
 public AllowedAce(PrincipalIdentifier principal, AccessMask accessMask)
     : base(AceType.Allowed, principal, accessMask)
 {
 }
Пример #13
0
        /// <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
        }
Пример #15
0
        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));
            }
        }
Пример #16
0
        /// <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)
                                            )));
            }
        }
Пример #17
0
 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");
        }
Пример #19
0
 public static bool EnsureAlias(this AccessMask flags) => (flags & AccessMask.ReadRef) == AccessMask.ReadRef;
Пример #20
0
 public static bool Quiet(this AccessMask flags) => (flags & AccessMask.ReadQuiet) != 0;
Пример #21
0
 public static bool Read(this AccessMask flags) => (flags & AccessMask.Read) != 0;
Пример #22
0
 public static extern SafeFileHandle CreateFile(string lpFileName, AccessMask dwDesiredAccess, 
     System.IO.FileShare dwShareMode, uint SecurityAttributes, System.IO.FileMode dwCreationDisposition, FileAttributesAndFlags dwFlagsAndAttributes, IntPtr hTemplateFile);
Пример #23
0
 public static bool WriteAlias(this AccessMask flags) => (flags & AccessMask.WriteRef) == AccessMask.WriteRef;
Пример #24
0
        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);
        }
Пример #25
0
 public static bool Write(this AccessMask flags) => (flags & AccessMask.Write) != 0;
Пример #26
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;
 }
Пример #27
0
 public static bool Isset(this AccessMask flags) => (flags & AccessMask.Isset) == AccessMask.Isset;
Пример #28
0
        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();
        }
Пример #29
0
 public static bool IsNotRef(this AccessMask flags) => (flags & AccessMask.IsNotRef) != 0;
Пример #30
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);
        }
Пример #31
0
 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);
 }
Пример #32
0
        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);
        }
Пример #33
0
        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);
                        }
                    }
                }
            }
        }
Пример #34
0
 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);
         }
     }
 }
Пример #35
0
 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();
        }
Пример #37
0
 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
        }
Пример #39
0
        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");
     }
 }