Help: SQL Server

Sharing my knowlege about SQL Server Troubleshooting Skills

  • Blog Stats

    • 1,882,453 hits
  • Select GETDATE()

    May 2021
    M T W T F S S
     12
    3456789
    10111213141516
    17181920212223
    24252627282930
    31  

Archive for the ‘Uncategorized’ Category

Help : Getting drive free space details without sysadmin permission

Posted by blakhani on July 15, 2011


Recently I worked with a customer where they wanted to run xp_fixeddrives without sysadmin permissions. This procedure was running from an application which was using non-sysadmin account. The major challenge in helping on such cases is that xp_fixeddrives is “undocumented” and hence “unsupported”

I love my customers and hate to say “No” and send them back empty handed. So, I put a little efforts to help them and found way to do it using proxy account. Here are the steps.

  • Enable xp_cmdshell if its not enabled already.
  • sp_configure 'show advanced options', 1
    go
    reconfigure with override
    go
    sp_configure 'xp_cmdshell', 1
    go
    reconfigure with override
  • Create below stored procedure which would provide the details about disk space. This has taken from internet and I am not author of this. I have done little modification to original code to get same output as xp_fixeddrives.
  • CREATE PROC Usp_fixeddrives 
    WITH EXECUTE AS OWNER 
    AS 
      BEGIN 
        set nocount on
          DECLARE @Drive TINYINT, 
                  @SQL   VARCHAR(100) 
    
          SET @Drive = 97 
    
          DECLARE @Drives TABLE ( 
            drive CHAR(1), 
            info  VARCHAR(80)) 
    
          WHILE @Drive <= 122 
            BEGIN 
                SET @SQL = 'EXEC XP_CMDSHELL ''fsutil volume diskfree ' + CHAR( 
                           @Drive) 
                           + 
                           ':''' 
    
                INSERT @Drives 
                       (info) 
                EXEC (@SQL) 
    
                UPDATE @Drives 
                SET    drive = CHAR(@Drive) 
                WHERE  drive IS NULL 
    
                SET @Drive = @Drive + 1 
            END 
    
          -- Show the expected output 
          SELECT upper(drive) AS drive, 
                 cast (SUM(CASE 
                       WHEN info LIKE 'Total # of free bytes        : %' THEN CAST( 
                       REPLACE( 
                       Substring(info, 32, 48), 
                       CHAR(13), '') AS BIGINT) 
                       ELSE CAST(0 AS BIGINT) 
                     END)/1024.0/1024.0 as bigint) AS 'MB free'
                 FROM   (SELECT drive, 
                         info 
                  FROM   @Drives 
                  WHERE  info LIKE 'Total # of %') AS d 
          GROUP  BY drive 
          ORDER  BY drive 
      END  
    

 

  • Since we are not going to give permission to SQL login on xp_cmdshell so we need to use proxy account. Windows account would be a Admin account.
  • EXEC sp_xp_cmdshell_proxy_account  'Domain\User', 'Password_For_User';
    GO
  • To test this we need to create a new SQL login, user and grant execute permission on the stored proc created.
  • -- Create login
    USE [master]
    GO
    CREATE LOGIN [AppAdmin] WITH PASSWORD=N'P@ssw0rd1', DEFAULT_DATABASE=[master], DEFAULT_LANGUAGE=[us_english], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
    GO
    
    -- Create User
    USE [master]
    GO
    CREATE USER [AppAdmin] FOR LOGIN [AppAdmin]
    GO
    
    -- Grant execute on the stored procedure.
    Grant exec on Usp_fixeddrives to [AppAdmin]
    GO
  • To test the functionality you need to login with AppAdmin account and run procedure as below.
  • — Execute procedure
    exec Usp_fixeddrives

     /*————————
     execute Usp_fixeddrives
      ————————*/
      drive MB free
      —– ——————–
      C     23523
      D     196197

  • Here is the output from sysadmin account and they are matching!!!

      /*————————
      execute xp_fixeddrives
      ————————*/
      drive MB free
      —– ———–
      C     23523
      D     196197

Hope this would help someone in the world!

Cheers,
Balmukund Lakhani
Twitter @blakhani

Posted in Uncategorized | 3 Comments »

Help : How can I hide databases from users?

Posted by blakhani on June 25, 2011


This is one of the common questions I have seen on forums, most common request from administrators who have been given task to create multi-tenant SQL Server. This essentially means various department of company or various client of the hosting company would access same SQL Server Instance. Business owners demand that they want clients to see only those databases which are relevant for them. I have worked with a company where the database name was name of the client. Inability to hide name of databases would essentially mean exposing information about their other clients.

In simple words, if Contoso is a database hosting company who has “Northwind traders” and “TailSpin Toys” as their client. If TailSpin logs in to the SQL Server, they should not see “Northwind” database and vice versa.

SQL Server Enterprise Manager calls the sp_MSdbuseraccess stored procedure to determine the accessibility of each database. The sp_MSdbuseraccess stored procedure then runs against every database in SQL Server to determine the user’s permission level in that database. So this can be achieved by altering the stored procedure as documented in KB http://support.microsoft.com/?id=889696 (You may experience a slow response from SQL Server Enterprise Manager when many databases exist in an instance of SQL Server)

In SQL 2005 onwards we fire queries to get the information in SQL Server Management Studio (a.k.a. SSMS) . Now, SQL Server 2005 onwards, we also have limited metadata visibility which I am going to use as “trick” to achieve our goal. As per http://msdn.microsoft.com/en-us/library/ms178534.aspx
{

If the caller of sys.databases is not the owner of the database and the database is not master or tempdb, the minimum permissions required to see the corresponding row are ALTER ANY DATABASE or VIEW ANY DATABASE server-level permission, or CREATE DATABASE permission in the master database. The database to which the caller is connected can always be viewed in sys.databases.
}

So, here is the quick script which can be used to demo this. If you love SSMS then I have also given instruction.

  • Create Two databases.
Create Database [NorthWindDB]
go
Create Database [TailSpinDB]
go
  • Create Logins (Not mapped to any Database)
CREATE LOGIN [NorthWindLogin] WITH
PASSWORD=‘E@syP@ssw0rd’
go
CREATE LOGIN [TailSpinLogin] WITH
PASSWORD=‘E@syP@ssw0rd’
go
  • Right Click on the Root section of the SSMS Tree (SQL Server Name)>Properties>Permissions>Click on the account, and select Deny to view databases. OR use below T-SQL
REVOKE VIEW ANY DATABASE TO [NorthWindLogin]
go
REVOKE VIEW ANY DATABASE TO [TailSpinLogin]
go
  • Right Click on the newly created databases > Properties > Files, and change the Owner to the newly created accounts. OR use below T-SQL
use [NorthWindDB]
go
sp_changedbowner 'NorthWindLogin'
go
use [TailSpinDB]
go
sp_changedbowner 'TailSpinLogin'
go

Here is the final out come…

SSMS

NorthWindLogin can see only NorthWindDB database and TailSpinLogin can see only his database.

Erland Sommarskog, SQL MVP, has filed request “Need VIEW DEFINITION permissions per database”. If you feel this is useful then please vote here!

Hope this would help someone in the world!

Cheers,
Balmukund Lakhani
Twitter @blakhani

Posted in Uncategorized | 2 Comments »

Help : How can I move Storage in Windows Cluster 2008

Posted by blakhani on June 11, 2011


While working on a case few days ago, I faced this question by customer and i found it interesting to blog about. (Today I found this in forum so finalizing and posting it). Here is the question.

I have created two node windows cluster. All disk are available in “storage” but I don’t see any option to do manual failover unless they are part of some group. How can I test if failover is working fine for disks without shutting down the node or adding them to a group.

Here is the screenshot to explain the problem better. As you can see that U and W are not part of any group defined under “Services and Applications”. So by default they are the part of “Available Storage” group.

Storage

And indeed there is no option in UI to do failover of those disks.

No Option

I spend sometime with windows team and I was able to find the answer. so here it goes.
This can only be done by command line. We need to use cluster.exe command to achieve this.

Cluster Group “Available Storage” /Move:NodeName

In above command NodeName is optional. If you have two nodes, it would move storage automatically to other node.

Move Using Command

Hope this would help someone in the world!

Cheers,
Balmukund Lakhani
Twitter @blakhani

Posted in Uncategorized | 7 Comments »