Chapter 8. Managing SQL Server 2005 Security

In this chapter:

Microsoft SQL Server 2005 is being used more frequently both within organizations and for external access to information. Whether employees, contractors, or outside users access your databases, your job as an administrator is to manage that database access efficiently. You do this by creating user logins, configuring login permissions, and assigning roles. The permissions and roles you assign determine which actions users can perform as well as what kinds of data they can access.

Your primary goals in managing security should be to:

  • Balance the user’s need for access to data against your need for protection from unauthorized access to data.

  • Restrict database permissions so that users are less likely to execute harmful commands and procedures (maliciously or accidentally).

  • Close off other security holes, such as those that may be caused by ordinary users with membership in the Windows Administrators group.

Overview of SQL Server 2005 Security

In SQL Server 2005, all objects in a database are located in schemas. Each schema is owned by roles rather than individual users, allowing multiple users to administer database objects. This resolves an issue in earlier versions of SQL Server, in which users could not be dropped from a database without having to reassign the ownership of every object they owned. Now you only need to change ownership for the schema, not for each object.

Working with Security Principals and Securables

SQL Server 2005 makes extensive uses of security principals and securables. An entity that can request a server, database, or schema resource is referred to as a security principal. Each security principal has a unique Security Identifier (SID). Security principals are managed at three levels: Windows, SQL Server, and Database. The level at which the security principal is defined sets its scope of influence. Generally, Windows- and SQL Server–level security principals have an instance-wide scope, and database-level principals have a scope of influence within a specific database.

Table 8-1 lists the security principals at each level. Some security principals, including Windows groups, database roles, and applications roles, can include other security principals. These security principals are also referred to as collections. Every database user belongs to the public database role. When a user has not been granted or denied specific permissions on a securable, the user inherits the permissions granted to the public role on that securable.

Table 8-1. SQL Server Principal Levels and the Included Principals

Principal Level

Principals Included

Windows Level

Windows Domain Login

 

Windows Local Login

 

Windows Group

SQL Server Level

Server Role

 

SQL Server Login

 

SQL Server Login mapped to an asymmetric key

 

SQL Server Login mapped to a certificate

 

SQL Server login mapped to a Windows login

Database Level

Database User

 

Database user mapped to an asymmetric key

 

Database user mapped to a certificate

 

Database user mapped to a Windows login

 

Application Role

 

Database Role

 

Public Database Role

Security principals can be assigned specific permissions on hierarchical collections of entities referred to as securables. As Table 8-2 shows, the three top-level securables are server, database, and schema. Each of these securables contains other securables, which in turn can contain other securables. These nested hierarchies are referred to as scopes. Thus, you can also say that the main securable scopes in SQL Server are server, database, and schema.

Table 8-2. SQL Server Securable Scopes and the Securables They Contain

Securable Scope

Securable Contained

Server

Servers/current instance

 

Database

 

Endpoint

 

Login

 

Server role

Database

Application role

 

Assembly

 

Asymmetric Key

 

Certificate

 

Contract

 

Database Role

 

Full-Text Catalog

 

Message Type

 

Remote Service Binding

 

Route

 

Schema

 

Service

 

Symmetric Key

 

User

Schema

Aggregate

 

Function

 

Procedure

 

Queue

 

Synonym

 

Table

 

Type

 

View

 

XML Schema Collection

Understanding Permissions of Securables

Each SQL Server 2005 securable has permissions that can be granted to a security principal. These permissions begin with a keyword or keywords that identify the permission being granted, and these are summarized in Table 8-3.

Table 8-3. Permission Keywords and How They Work

Permission Keyword(s)

Permission Granted

Primarily Applies To...

ALTER ANY <Database>

Grants ability to CREATE, ALTER, or DROP individual securables for the database. For example, granting a principal ALTER ANY SCHEMA for a database gives the principal the ability to CREATE, ALTER, or DROP any schema in the database.

ALTER ANY <Server>

Grants ability to CREATE, ALTER, or DROP individual securables for the server. For example, granting a principal ALTER ANY LOGIN for a server gives that principal the ability to CREATE, ALTER, and DROP any login in that server instance.

 

ALTER

Grants ability to alter properties of a particular securable except for ownership. When a principal is granted on a scope, the principal has the ability to ALTER, CREATE, or DROP any securable contained within that scope. For example, granting a principal ALTER on a schema gives that principal the ability to CREATE, ALTER, and DROP objects from the schema.

Stored procedures, Service Broker queues, functions, synonyms, tables, and views

BACKUP/DUMP

Grants permission to back up (dump).

 

CONTROL

Grants ownership-like capabilities. The principal has all defined permissions on the securable and can grant permissions on the securable as well. When you assign CONTROL permissions, consider the security model’s hierarchy. Granting CONTROL at a particular scope implicitly includes CONTROL on all the securables under that scope. For example, CONTROL on a database implies all permissions on the database, including all assemblies and schemas in the database and all objects within all schemas.

Stored procedures, functions, synonyms, Service Broker queues, tables, and views

CREATE <Database Securable>

Grants permission to create the database securable.

 

CREATE <Schema contained Securable>

Grants permission to create the schema-contained securable. Remember that ALTER permissions on the schema are needed to create the securable in a particular schema.

 

CREATE <Server Securable>

Grants permission to create the server securable.

 

DELETE

Grants permission to delete the securable.

Synonyms, tables, and views

EXECUTE

Grants permission to execute the securable.

Stored procedures, functions, and synonyms

IMPERSONATE <Login>

Grants ability to impersonate the login.

 

IMPERSONATE <User>

Grants ability to impersonate the user.

 

INSERT

Grants permission to insert data into the securable.

Synonyms, tables, and views

RECEIVE

Grants permission to receive Service Broker messages.

Service Broker queues

REFERENCES

Grants permission to reference the securable.

Functions, Service Broker queues, tables, and views

RESTORE/LOAD

Grants permission to restore (load).

 

SELECT

Grants permission to view data stored in the securable.

Synonyms, tables, table-valued functions, and views

TAKE OWNERSHIP

Grants ability to take ownership of the securable.

Stored procedures, functions, synonyms, tables, and views

UPDATE

Grants permission to change data stored in the securable.

Synonyms, tables, and views

VIEW DEFINITION

Grants permission to view the securable definition.

Stored procedures, Service Broker queues, functions, synonyms, tables, and views

Examining Permissions Granted to Securables

SQL Server functions that you will find helpful for examining permissions granted to securables include:

  • sys.fn_builtin_permissions

  • Has_perms_by_name

You will learn more about how these functions are used in the sections that follow.

Examining Built-in Permissions

Each object class from the server scope down has a specific set of grantable permissions. The sys.fn_builtin_permissions function returns a description of the server’s built-in permissions hierarchy:

sys.fn_built_permissions( [ DEFAULT | NULL     
    | empty_string | < securable_class > } )

< securable_class >::= APPLICATION ROLE | ASSEMBLY | ASYMMETRIC KEY    
    | CERTIFICATE | CONTRACT | DATABASE | ENDPOINT | FULLTEXT CATALOG    
    | LOGIN | MESSAGE TYPE | OBJECT | REMOTE SERVICE BINDING | ROLE    
    | ROUTE | SCHEMA | SERVER | SERVICE | SYMMETRIC KEY | TYPE     
    | USER | XML SCHEMA COLLECTION

where DEFAULT, NULL, or an empty string return a complete list of built-in permissions, or you can specify the name of a specific securable class to return all permissions that apply to the class.

The sys.fn_builtin_permissions function is accessible to the public role. You can view the grantable permissions for all objects by using the following query:

USE master
GO
SELECT * FROM sys.fn_builtin_permissions(default)
GO

If you want to view the grantable permissions for a specific object class, you can use the following query:

USE master
GO
SELECT * FROM sys.fn_builtin_permissions('object_class')  
GO

where object_class is the object class you want to work with. The following example examines the grantable permissions for the LOGIN class:

SELECT * FROM sys.fn_builtin_permissions('login')

You can also list object classes for which a specific permission has been granted. In the following example, you list object classes that have the SELECT permission:

USE master
GO
SELECT * FROM sys.fn_builtin_permissions(DEFAULT) 
       WHERE permission_name = 'SELECT';
GO

Examining Effective Permissions

The Has_perms_by_name built-in function returns the effective permission on a securable. Effective permissions include:

  • Permissions granted directly to the user, and not denied.

  • Permissions implied by a higher-level permission held by the user, and not denied.

  • Permissions granted to a role of which the user is a member, and not denied.

  • Permissions held by a role of which the user is a member, and not denied.

The Has_perms_by_name function is accessible to the public role. However, you cannot use Has_perms_by_name to check permissions on a linked server. The basic syntax of the Has_perms_by_name function follows:

Has_perms_by_name (
                   securable ,
                   securable_class ,
                   permission 
                   [, sub-securable ]
                   [, sub-securable_class ]
                   )

where securable sets the name of the securable or NULL if the securable is the server itself, securable_class sets the name of the securable class or NULL if the securable is the server itself, and permission is a non-NULL value representing the permission name to be checked. You can use the permission name "ANY" as a wildcard to determine if the securable has any effective permissions. The optional sub-securable and sub-securable_class values specify the name of the securable subentity and the class of securable subentity against which the permission is tested. Both of these optional values default to NULL. If the function returns true (1), the securable has the effective permission. If the function returns false (0), the securable does not have the effective permission. A return value of NULL indicates that the query failed.

You can determine if the currently logged-on user has a specific permission on the server by executing the following query:

USE master
GO
SELECT has_perms_by_name(null, null, 'permission_name'),
GO

where permission_name is the name of the permission to examine. The following example checks to see if the current user has the VIEW SERVER STATE permissions:

select has_perms_by_name(null, null, 'VIEW SERVER STATE'),

A true (1) or false (0) value is returned to indicate whether or not the user is granted the permission.

To determine if the current user has any permissions in a specific database, you can execute the following query:

USE master
GO
SELECT has_perms_by_name('database_name', 'DATABASE', 'ANY')
GO

where database_name is the name of the database for which you are determining permissions. The following example determines if the current user has any permissions in the Personnel database:

SELECT has_perms_by_name('Personnel', 'DATABASE', 'ANY')

If the query returns 1, the current user has some permissions for the specific database. You can indicate the current database with the db_name() function, such as:

SELECT has_perms_by_name(db_name(),'DATABASE', 'ANY')

You can determine the permissions of a specific user using EXECUTE AS. In the following example, you check to see if EdwardM has any permissions in the Personnel database:

EXECUTE AS user = 'EdwardM'
GO
SELECT has_perms_by_name('Personnel', 'DATABASE', 'ANY')
GO
REVERT
GO

Permissions on schema objects, like Tables and Views, can be examined as well. To do this, set the securable to name, the securable class to object, and permission to the permission you want to examine. To determine which tables the current user has SELECT permission on, you would use the following query:

USE Personnel
GO
SELECT has_perms_by_name(name, 'OBJECT', 'SELECT') as Have_Select,
    * from sys.tables;
go

The current user has SELECT permission on tables with a 1 in the Have_Select column. By specifying the two-part or three-part name, you can examine permissions on a specific table as well. For example, to determine if the current user has INSERT permission on the Address table in the current database, you would use a two-part name:

select has_perms_by_name('Employee.Address', 'OBJECT', 'INSERT')
       as Have_Select, * from sys.tables;

or a three-part name:

select has_perms_by_name('Personnel.Employee.Address', 'OBJECT', 'INSERT')
       as Have_Select, * from sys.tables;
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset