Detecting unusable pooled SqlConnections

无人久伴 提交于 2019-12-04 18:38:33

This is going on logic and not to much experience with using sp_setapprole but would it not be possible to check the security context before making the call? Or alternatively check the security permission and context first?

It would seem that you are calling sp_setapprole but not calling sp_unsetapprole and then letting the connection just be returned to the pool.

I would suggest using a structure (or a class, if you have to use this across methods) with an implementation of IDisposable which will take care of this for you:

public struct ConnectionManager : IDisposable
{
    // The backing for the connection.
    private SqlConnection connection;

    // The connection.
    public SqlConnection Connection { get { return connection; } }

    public void Dispose()
    {
        // If there is no connection, get out.
        if (connection == null)
        {
            // Get out.
            return;
        }

        // Make sure connection is cleaned up.
        using (SqlConnection c = connection)
        {
            // See (1).  Create the command for sp_unsetapprole
            // and then execute.
            using (SqlCommand command = ...)
            {
                // Execute the command.
                command.ExecuteNonQuery();
            }
        }
    }

    public ConnectionManager Release()
    {
        // Create a copy to return.
        ConnectionManager retVal = this;

        // Set the connection to null.
        retVal.connection = null;

        // Return the copy.
        return retVal;        
    }

    public static ConnectionManager Create()
    {
        // Create the return value, use a using statement.
        using (ConnectionManager cm = new ConnectionManager())
        {
            // Create the connection and assign here.
            // See (2).
            cm.connection = ...

            // Create the command to call sp_setapprole here.
            using (SqlCommand command = ...)
            {
                // Execute the command.
                command.ExecuteNonQuery();

                // Return the connection, but call release
                // so the connection is still live on return.
                return cm.Release();
            }
        }
    }
}
  1. You will create the SqlCommand that corresponds to calling the sp_setapprole stored procedure. You can generate the cookie and store it in a private member variable as well.
  2. This is where you create your connection.

The client code then looks like this:

using (ConnectionManager cm = ConnectionManager.Create())
{
    // Get the SqlConnection for use.
    // No need for a using statement, when Dispose is
    // called on the connection manager, the connection will be
    // closed.
    SqlConnection connection = cm.Connection;

    // Use connection appropriately.
}

Nope, it's not possible.

Ed Green

This is a bit dirty but if your original user has rights to VIEW SERVER STATE, select * from sys.sysprocesses will return all processes when the role is not active and a single row for the current process when it is.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!