zoukankan      html  css  js  c++  java
  • (Securing Access to the Data).sql

    CREATE DATABASE SecurityChapter
    GO
    Use SecurityChapter
    GO
    -----------------------------------------------------------
    -- Database Security Overview; Impersonation
    -----------------------------------------------------------
    CREATE LOGIN system_admin WITH PASSWORD = 'tooHardToEnterAndNoOneKnowsIt'
    EXEC sp_addsrvrolemember 'system_admin','sysadmin'
    GO
    CREATE LOGIN louis with PASSWORD = 'reasonable', DEFAULT_DATABASE=tempdb

    --Must execute in Master Database
    USE MASTER
    GRANT IMPERSONATE ON LOGIN::system_admin TO louis;
    GO

    --Disconnect and connect as Louis
    GO
    USE AdventureWorks2008
    GO
    EXECUTE AS LOGIN = 'system_admin'
    GO
    USE AdventureWorks2008
    SELECT user as [user], system_user as [system_user],
           original_login() as [original_login]
    GO
    REVERT --go back to previous context
    GO
    USE SecurityChapter
    GO

    REVERT
    SELECT user
    GO

    SELECT object_name(major_id), permission_name, state_desc,
            user_name(grantee_principal_id) as Grantee
    FROM   sys.database_permissions
    WHERE  objectproperty(major_id,'isTable') = 1
      AND  objectproperty(major_id,'isMsShipped') = 0
    GO
    --------------------------------------------------------------------------------
    -- Database Security Overview; Controlling Access to Objects; Table Security
    --------------------------------------------------------------------------------
    --You may need to reconnect as the sysadmin...

    --start with a new schema for this test
    CREATE SCHEMA TestPerms
    GO

    CREATE TABLE TestPerms.TableExample
    (
        TableExampleId int identity(1,1)
                       CONSTRAINT PKTableExample PRIMARY KEY,
        Value   varchar(10)
    )
    GO
    CREATE USER Tony WITHOUT LOGIN
    GO
    EXECUTE AS USER = 'Tony'
    INSERT INTO TestPerms.TableExample(Value)
    VALUES ('a row')
    GO

    REVERT
    GRANT INSERT on TestPerms.TableExample to Tony

    EXECUTE AS USER = 'Tony'
    INSERT INTO TestPerms.TableExample(Value)
    VALUES ('a row')
    GO

    SELECT TableExampleId, value
    FROM   TestPerms.TableExample
    GO

    REVERT
    GRANT SELECT on TestPerms.TableExample to Tony
    GO

    --------------------------------------------------------------------------------
    -- Database Security Overview; Controlling Access to Objects; Table Security
    --------------------------------------------------------------------------------

    CREATE USER Employee WITHOUT LOGIN
    CREATE USER Manager WITHOUT LOGIN

    GO
    CREATE SCHEMA Products
    go
    CREATE TABLE Products.Product
    (
        ProductId   int identity CONSTRAINT PKProduct PRIMARY KEY,
        ProductCode varchar(10) CONSTRAINT AKProduct_ProductCode UNIQUE,
        Description varchar(20),
        UnitPrice   decimal(10,4),
        ActualCost  decimal(10,4)
    )
    INSERT INTO Products.Product(ProductCode, Description, UnitPrice, ActualCost)
    VALUES ('widget12','widget number 12',10.50,8.50),
           ('snurf98','Snurfulator',99.99,2.50)

    GO
    GRANT SELECT on Products.Product to employee,manager
    DENY SELECT on Products.Product (ActualCost) to employee
    GO
    EXECUTE AS USER = 'manager'
    SELECT  *
    FROM    Products.Product
    GO
    REVERT --revert back to SA level user or you will get an error that the
           --user cannot do this operation because it is unclear if the employee
           --user actually exists
    GO
    EXECUTE AS USER = 'employee'
    GO
    SELECT *
    FROM   Products.Product
    GO

    SELECT ProductId, ProductCode, Description, UnitPrice
    FROM   Products.Product

    GO

    ------------------------------------------------------------------------------------------------
    -- Database Security Overview; Controlling Access to Objects; Roles; Standard Database Roles
    ------------------------------------------------------------------------------------------------
    GO
    SELECT is_member('HRManager')
    GO
    IF (SELECT is_member('HRManager')) = 0 or (SELECT is_member('HRManager')) is null
           SELECT 'I..DON''T THINK SO!'
    GO
    REVERT
    CREATE USER Frank WITHOUT LOGIN
    CREATE USER Julie WITHOUT LOGIN
    CREATE USER Rie WITHOUT LOGIN
    GO
    CREATE ROLE HRWorkers

    EXECUTE sp_addrolemember 'HRWorkers','Julie'
    EXECUTE sp_addrolemember 'HRWorkers','Rie'
    GO


    CREATE SCHEMA Payroll

    CREATE TABLE Payroll.EmployeeSalary
    (
        EmployeeId  int,
        SalaryAmount decimal(12,2)

    )
    GRANT SELECT ON Payroll.EmployeeSalary to HRWorkers
    GO

    EXECUTE AS USER = 'Frank'

    SELECT *
    FROM   Payroll.EmployeeSalary
    GO


    REVERT
    EXECUTE AS USER = 'Julie'

    SELECT *
    FROM   Payroll.EmployeeSalary

    GO

    REVERT
    DENY SELECT ON payroll.employeeSalary TO Rie

    EXECUTE AS USER = 'Rie'
    SELECT *
    FROM   payroll.employeeSalary
    GO
    REVERT
    --note, this query only returns rows for tables where the user has SOME rights
    SELECT  table_schema + '.' + table_name as tableName,
            has_perms_by_name(table_schema + '.' + table_name, 'object', 'SELECT')
                                                                   
                                                                     as allowSelect
    FROM    information_schema.tables

    GO
    CREATE TABLE TestPerms.BobCan
    (
        BobCanId int identity(1,1) CONSTRAINT PKBobCan PRIMARY KEY,
        Value varchar(10)
    )
    CREATE TABLE TestPerms.AppCan
    (
        AppCanId int identity(1,1) CONSTRAINT PKAppCan PRIMARY KEY,
        Value varchar(10)
    )
    GO
    CREATE USER Bob WITHOUT LOGIN
    GO
    GRANT SELECT on TestPerms.BobCan to Bob
    GO
    CREATE APPLICATION ROLE AppCan_application with password = '39292ljasll23'
    GO
    GRANT SELECT on TestPerms.AppCan to AppCan_application
    GO

    EXECUTE AS USER = 'Bob'
    GO
    SELECT * FROM TestPerms.BobCan
    GO
    SELECT * FROM TestPerms.AppCan
    GO
    REVERT
    GO
    EXECUTE sp_setapprole 'AppCan_application', '39292ljasll23'
    go
    SELECT * FROM TestPerms.BobCan
    GO
    SELECT * from TestPerms.AppCan
    GO
    SELECT user as userName, system_user as login
    GO
    --Disconnect and reconnect to clear out app role...

    Use SecurityChapter
    GO
    --Note that this must be executed as a single batch because of the variable
    --for the cookie
    DECLARE @cookie varbinary(8000);
    EXECUTE sp_setapprole 'AppCan_application', '39292ljasll23'
                  , @fCreateCookie = true, @cookie = @cookie OUTPUT

    SELECT @cookie as cookie
    SELECT USER as beforeUnsetApprole

    EXEC sp_unsetapprole @cookie

    SELECT USER as afterUnsetApprole

    REVERT --done with this user
    GO

    ------------------------------------------------------------------------------------------------
    -- Database Security Overview; Controlling Access to Objects; Roles; Schemas
    ------------------------------------------------------------------------------------------------
    GO

    USE AdventureWorks2008
    GO
    SELECT  type_desc, count(*)
    FROM    sys.objects
    WHERE   schema_name(schema_id) = 'HumanResources'
      AND   type_desc in ('SQL_STORED_PROCEDURE','CLR_STORED_PROCEDURE',
                          'SQL_SCALAR_FUNCTION','CLR_SCALAR_FUNCTION',
                          'CLR_TABLE_VALUED_FUNCTION','SYNONYM',
                          'SQL_INLINE_TABLE_VALUED_FUNCTION',
                          'SQL_TABLE_VALUED_FUNCTION','USER_TABLE','VIEW')
    GROUP BY type_desc
    GO
    USE SecurityChapter --or your own db if you are not using mine
    GO
    CREATE USER Tom WITHOUT LOGIN
    GRANT SELECT ON SCHEMA::TestPerms To Tom
    GO

    EXECUTE AS USER = 'Tom'
    GO
    SELECT * FROM TestPerms.AppCan
    GO
    REVERT
    GO

    CREATE TABLE TestPerms.SchemaGrant
    (
        SchemaGrantId int primary key
    )
    GO
    EXECUTE AS USER = 'Tom'
    GO
    SELECT * FROM TestPerms.schemaGrant
    GO
    REVERT
    GO
    ---------------------------------------------------------------------------------------------
    -- Controlling Object Access Via T-SQL Coded Objects; Stored Procedures and Scalar Functions
    --------------------------------------------------------------------------------------------

    CREATE USER procUser WITHOUT LOGIN
    GO

    CREATE SCHEMA procTest
    CREATE TABLE procTest.misc
    (
        Value varchar(20),
        Value2 varchar(20)
    )
    GO
    INSERT INTO procTest.misc
    VALUES ('somevalue','secret'),
          ('anothervalue','secret')
    GO


    CREATE PROCEDURE procTest.misc$select
    AS
        SELECT Value
        FROM   procTest.misc
    GO
    GRANT EXECUTE on procTest.misc$select to procUser
    GO

    EXECUTE AS USER = 'procUser'
    GO
    SELECT Value, Value2
    FROM   procTest.misc
    GO

    EXECUTE procTest.misc$select
    GO

    SELECT  routine_schema + '.' + routine_name as procedureName,
            has_perms_by_name(routine_schema + '.' + routine_name, 'object',
                                'EXECUTE') as allowExecute
    FROM    information_schema.routines
    WHERE   routine_type = 'PROCEDURE'

    REVERT

    GO

    ---------------------------------------------------------------------------------------------
    -- Controlling Object Access Via T-SQL Coded Objects;Impersonation Within Objects
    --------------------------------------------------------------------------------------------
    --this will be the owner of the primary schema
    CREATE USER schemaOwner WITHOUT LOGIN
    GRANT CREATE SCHEMA to schemaOwner
    GRANT CREATE TABLE to schemaOwner

    --this will be the procedure creator
    CREATE USER procedureOwner WITHOUT LOGIN
    GRANT CREATE SCHEMA to procedureOwner
    GRANT CREATE PROCEDURE to procedureOwner
    GRANT CREATE TABLE to procedureOwner
    GO
    --this will be the average user who needs to access data
    CREATE USER aveSchlub WITHOUT LOGIN
    GO


    EXECUTE AS USER = 'schemaOwner'
    GO
    CREATE SCHEMA schemaOwnersSchema
    GO
    CREATE TABLE schemaOwnersSchema.Person
    (
        PersonId    int constraint PKtestAccess_Person primary key,
        FirstName   varchar(20),
        LastName    varchar(20)
    )
    Go
    INSERT INTO schemaOwnersSchema.Person
    VALUES (1, 'Phil','Mutayblin'),
           (2, 'Del','Eets')
    GO

    GRANT SELECT on schemaOwnersSchema.Person to procedureOwner
    GO


    REVERT --we can step back on the stack of principals,
            --but we can't change directly
            --to procedureOwner. Here I step back to the db_owner user you have
            --used throughout the chapter
    GO
    EXECUTE AS USER = 'procedureOwner'
    GO

    CREATE SCHEMA procedureOwnerSchema
    GO

    CREATE TABLE procedureOwnerSchema.OtherPerson
    (
        personId    int constraint PKtestAccess_person primary key,
        FirstName   varchar(20),
        LastName    varchar(20)
    )
    go
    INSERT INTO procedureOwnerSchema.OtherPerson
    VALUES (1, 'DB','Smith')
    INSERT INTO procedureOwnerSchema.OtherPerson
    VALUES (2, 'Dee','Leater')
    GO

    REVERT
    GO
    SELECT tables.name as [table], schemas.name as [schema],
           database_principals.name as [owner]
    FROM   sys.tables
             join sys.schemas
                on tables.schema_id = schemas.schema_id
             join sys.database_principals
                on database_principals.principal_id = schemas.principal_id
    WHERE  tables.name in ('Person','OtherPerson')
    GO

    EXECUTE AS USER = 'procedureOwner'
    GO
    CREATE PROCEDURE  procedureOwnerSchema.person$asCaller
    WITH EXECUTE AS CALLER --this is the default
    AS
    SELECT  personId, FirstName, LastName
    FROM    procedureOwnerSchema.OtherPerson --<-- ownership same as proc

    SELECT  personId, FirstName, LastName
    FROM    schemaOwnersSchema.person  --<-- breaks ownership chain
    GO

    CREATE PROCEDURE procedureOwnerSchema.person$asSelf
    WITH EXECUTE AS SELF --now this runs in context of procedureOwner,
                         --since it created it
    AS
    SELECT  personId, FirstName, LastName
    FROM    procedureOwnerSchema.OtherPerson --<-- ownership same as proc

    SELECT  personId, FirstName, LastName
    FROM    schemaOwnersSchema.person  --<-- breaks ownership chain

    GO

    GRANT EXECUTE ON procedureOwnerSchema.person$asCaller to aveSchlub
    GRANT EXECUTE ON procedureOwnerSchema.person$asSelf to aveSchlub

    REVERT; EXECUTE AS USER = 'aveSchlub'
    GO

    --this proc is in context of the caller, in this case, aveSchlub
    EXECUTE procedureOwnerSchema.person$asCaller
    GO

    --procedureOwner, so it works
    execute procedureOwnerSchema.person$asSelf
    GO


    REVERT
    GO
    CREATE PROCEDURE dbo.testDboRights
    AS
     BEGIN
        CREATE TABLE dbo.test
        (
            testId int
        )
     END
    GO

    CREATE USER leroy WITHOUT LOGIN
    GO
    GRANT EXECUTE on dbo.testDboRights to leroy
    GO

    GO
    EXECUTE AS USER = 'leroy'
    EXECUTE dbo.testDboRights
    GO

    REVERT
    GO
    ALTER PROCEDURE dbo.testDboRights
    WITH EXECUTE AS 'dbo'
    AS
     BEGIN
        CREATE TABLE dbo.test
        (
            testId int
        )
     END
    GO

    EXECUTE AS USER = 'leroy'
    EXECUTE dbo.testDboRights
    GO
    REVERT
    GO

    ---------------------------------------------------------------------------------------------
    --  Controlling Object Access Via T-SQL Coded Objects;Crossing Database Lines;Cross Database Chaining
    --------------------------------------------------------------------------------------------
    GO
    CREATE DATABASE externalDb
    GO
    USE externalDb
    GO
                                       --smurf theme song :)
    CREATE LOGIN smurf WITH PASSWORD = 'La la, la la la la, la, la la la la'
    CREATE USER smurf FROM LOGIN smurf
    CREATE TABLE dbo.table1 ( value int )
    GO
    CREATE DATABASE localDb
    GO
    USE localDb
    GO
    CREATE USER smurf FROM LOGIN smurf
    GO

    CREATE PROCEDURE dbo.externalDb$testCrossDatabase
    AS
    SELECT Value
    FROM   externalDb.dbo.table1
    GO
    GRANT execute on dbo.externalDb$testCrossDatabase to smurf
    GO

    EXECUTE AS USER = 'smurf'
    go
    EXECUTE dbo.externalDb$testCrossDatabase
    GO
    REVERT

    GO
    ALTER DATABASE localDb
       SET DB_CHAINING ON
    ALTER DATABASE localDb
       SET TRUSTWORTHY ON

    ALTER DATABASE externalDb
       SET DB_CHAINING ON
    GO
    SELECT cast(name as varchar(10)) as name,
           cast(suser_sname(owner_sid) as varchar(10)) as owner,
           is_trustworthy_on, is_db_chaining_on
    FROM   sys.databases where name in ('localdb','externaldb')
    GO
    EXECUTE AS USER = 'smurf'
    go
    EXECUTE dbo.externalDb$testCrossDatabase
    GO
    REVERT
    GO

    ---------------------------------------------------------------------------------------------
    --  Controlling Object Access Via T-SQL Coded Objects;Crossing Database Lines;Using Impersonation to Cross Database Lines
    --------------------------------------------------------------------------------------------

    ALTER DATABASE localDb
       SET DB_CHAINING OFF
    ALTER DATABASE localDb
       SET TRUSTWORTHY ON

    ALTER DATABASE externalDb
       SET DB_CHAINING OFF

    GO

    CREATE PROCEDURE dbo.externalDb$testCrossDatabase_Impersonation
    WITH EXECUTE AS SELF --as procedure creator
    AS
    SELECT Value
    FROM   externalDb.dbo.table1
    GO
    GRANT execute on dbo.externalDb$testCrossDatabase_impersonation to smurf
    GO

    EXECUTE AS USER = 'smurf'
    go
    EXECUTE dbo.externalDb$testCrossDatabase_impersonation
    GO
    REVERT
    GO

    ---------------------------------------------------------------------------------------------
    --  Controlling Object Access Via T-SQL Coded Objects;Crossing Database Lines;Using a Certificate-Based User
    --------------------------------------------------------------------------------------------
    GO
    REVERT
    GO
    USE localDb
    GO
    ALTER DATABASE localDb
       SET TRUSTWORTHY OFF
    GO
    SELECT cast(name as varchar(10)) as name,
           cast(suser_sname(owner_sid) as varchar(10)) as owner,
           is_trustworthy_on, is_db_chaining_on
    FROM   sys.databases where name in ('localdb','externaldb')
    GO


    CREATE PROCEDURE dbo.externalDb$testCrossDatabase_Certificate
    AS
    SELECT Value
    FROM   externalDb.dbo.table1
    GO
    GRANT EXECUTE on dbo.externalDb$testCrossDatabase_Certificate to smurf
    GO

    CREATE CERTIFICATE procedureExecution ENCRYPTION BY PASSWORD = 'Cert Password'
     WITH SUBJECT = 
             'Used to sign procedure:externalDb$testCrossDatabase_Certificate'
    GO
    ADD SIGNATURE TO dbo.externalDb$testCrossDatabase_Certificate
         BY CERTIFICATE procedureExecution WITH PASSWORD = 'Cert Password'
    GO
    BACKUP CERTIFICATE procedureExecution TO FILE = 'c:\temp\procedureExecution.cer'
    GO

    USE externalDb
    GO
    CREATE CERTIFICATE procedureExecution FROM FILE = 'c:\temp\procedureExecution.cer'
    GO

    CREATE USER procCertificate FOR CERTIFICATE procedureExecution
    GO
    GRANT SELECT on dbo.table1 TO procCertificate

    GO

    USE localDb
    GO
    EXECUTE AS LOGIN = 'smurf'
    EXECUTE dbo.externalDb$testCrossDatabase_Certificate

    GO
    REVERT
    GO
    USE MASTER
    GO
    DROP DATABASE externalDb
    DROP DATABASE localDb
    GO
    USE SecurityChapter

    --------------------------------------------------------------------------------
    -- Views and Table-Valued Functions; General Usage
    --------------------------------------------------------------------------------
    GO
    SELECT *
    FROM Products.Product
    GO
    CREATE VIEW Products.allProducts
    AS
    SELECT ProductId,ProductCode, Description, UnitPrice, ActualCost
    FROM   Products.Product
    GO
    CREATE VIEW Products.WarehouseProducts
    AS
    SELECT ProductId,ProductCode, Description
    FROM   Products.Product
    GO
    CREATE FUNCTION Products.ProductsLessThanPrice
    (
        @UnitPrice  decimal(10,4)
    )
    RETURNS table
    AS
         RETURN ( SELECT ProductId, ProductCode, Description, UnitPrice
                  FROM   Products.Product
                  WHERE  UnitPrice <= @UnitPrice)
    GO
    SELECT * FROM Products.ProductsLessThanPrice(20)
    GO
    CREATE FUNCTION Products.ProductsLessThanPrice_GroupEnforced
    (
        @UnitPrice  decimal(10,4)
    )
    RETURNS @output table (ProductId int,
                           ProductCode varchar(10),
                           Description varchar(20),
                           UnitPrice decimal(10,4))
    AS
     BEGIN
        --cannot raise an error, so you have to implement your own
        --signal, or perhaps simply return no data.
        IF @UnitPrice > 100 and (
                                 IS_MEMBER('HighPriceProductViewer') = 0
                                 or IS_MEMBER('HighPriceProductViewer') is null)
            INSERT @output
            SELECT -1,'ERROR','',-1
        ELSE
            INSERT @output
            SELECT ProductId, ProductCode, Description, UnitPrice
            FROM   Products.Product
            WHERE  UnitPrice <= @UnitPrice
        RETURN
     END
    GO
    CREATE ROLE HighPriceProductViewer
    CREATE ROLE ProductViewer

    CREATE USER HighGuy WITHOUT LOGIN
    CREATE USER LowGuy WITHOUT LOGIN

    EXEC sp_addrolemember 'HighPriceProductViewer','HighGuy'
    EXEC sp_addrolemember 'ProductViewer','HighGuy'
    EXEC sp_addrolemember 'ProductViewer','LowGuy'
    GO
    GRANT SELECT ON Products.ProductsLessThanPrice_GroupEnforced TO ProductViewer
    GO

    EXECUTE AS USER = 'HighGuy'
    SELECT * FROM Products.ProductsLessThanPrice_GroupEnforced(10000)
    REVERT
    GO
    EXECUTE AS USER = 'LowGuy'
    SELECT * FROM Products.ProductsLessThanPrice_GroupEnforced(10000)
    REVERT
    GO
    --------------------------------------------------------------------------------
    -- Views and Table-Valued Functions; Implementing Configurable Row-Level Security with Views
    --------------------------------------------------------------------------------
    Go
    ALTER TABLE Products.Product
       ADD ProductType varchar(20) NULL
    GO
    UPDATE Products.Product
    SET    ProductType = 'widget'
    WHERE  ProductCode = 'widget12'
    GO
    UPDATE Products.Product
    SET    ProductType = 'snurf'
    WHERE  ProductCode = 'snurf98'
    GO
    CREATE VIEW Products.WidgetProducts
    AS
    SELECT ProductId, ProductCode, Description, UnitPrice, ActualCost
    FROM   Products.Product
    WHERE  ProductType = 'widget'
    WITH CHECK OPTION --This prevents the user from entering data that would not
                      --match the view's criteria
    GO
    SELECT *
    FROM   Products.WidgetProducts
    GO
    CREATE VIEW Products.ProductsSelective
    AS
    SELECT ProductId, ProductCode, Description, UnitPrice, ActualCost
    FROM   Products.Product
    WHERE  ProductType <> 'snurf'
       or  (is_member('snurfViewer') = 1)
       or  (is_member('db_owner') = 1) --can't add db_owner to a role
    WITH CHECK OPTION
    GO
    GRANT SELECT ON Products.ProductsSelective to public
    GO

    CREATE USER chrissy WITHOUT LOGIN
    CREATE ROLE snurfViewer
    GO
    EXECUTE AS USER = 'chrissy'
    SELECT * from Products.ProductsSelective
    REVERT
    GO

    execute sp_addrolemember 'snurfViewer', 'chrissy'
    GO
    EXECUTE AS USER = 'chrissy'
    SELECT * from Products.ProductsSelective
    REVERT
    GO
    CREATE TABLE Products.ProductSecurity
    (
        ProductsSecurityId int identity(1,1)
                    CONSTRAINT PKProducts_ProductsSecurity PRIMARY KEY,
        ProductType varchar(20), --at this point you probably will create a
                                 --ProductType domain table, but this keeps the                            
                                 --example a bit simpler
        DatabaseRole    sysname,
                    CONSTRAINT AKProducts_ProductsSecurity_typeRoleMapping
                                UNIQUE (ProductType, DatabaseRole)
    )
    GO
    INSERT INTO Products.ProductSecurity(ProductType, DatabaseRole)
    VALUES ('widget','public')
    GO
    ALTER VIEW Products.ProductsSelective
    AS
    SELECT Product.ProductId, Product.ProductCode, Product.Description,
           Product.UnitPrice, Product.ActualCost, Product.ProductType
    FROM   Products.Product as Product
             JOIN Products.ProductSecurity as ProductSecurity
                on  (Product.ProductType = ProductSecurity.ProductType
                    and is_member(ProductSecurity.DatabaseRole) = 1)
                    or is_member('db_owner') = 1 --don't leave out the dbo!
    GO

    EXECUTE AS USER = 'chrissy'
    SELECT *
    FROM   PRoducts.ProductsSelective
    GO
    REVERT
    GO

    INSERT INTO Products.ProductSecurity(ProductType, databaseRole)
    VALUES ('snurf','snurfViewer')
    go
    EXECUTE AS USER = 'chrissy'
    SELECT * from PRoducts.ProductsSelective
    REVERT


    --------------------------------------------------------------------------------------
    -- Obfuscating Data
    --------------------------------------------------------------------------------------
    SELECT encryptByPassPhrase('hi', 'Secure data')
    GO
    SELECT decryptByPassPhrase('hi',
       0x010000004D2B87C6725612388F8BA4DA082495E8C836FF76F32BCB642B36476594B4F014)
    GO

    SELECT cast(decryptByPassPhrase('hi',
         0x010000004D2B87C6725612388F8BA4DA082495E8C836FF76F32BCB642B36476594B4F014)
                                                  as varchar(30))

    GO
    CREATE DATABASE EncryptionMaster
    go
    USE EncryptionMaster
    go
    CREATE SCHEMA Security
    CREATE TABLE Security.passphrase
    (
        passphrase nvarchar(4000) --the max size of the passphrase
    )
    GO

    INSERT  into Security.passphrase
    VALUES ('ljlOIUEojljljieo#*JlLjlIu*o7G8i&t87*&Yh[p00') --the more unobvious the
                                                           --better!

    GO

    CREATE DATABASE CreditInfo
    GO
    ALTER DATABASE EncryptionMaster  -- we will be using impersonation to keep the
        SET TRUSTWORTHY ON           -- example simple, in practice I would
                                     -- probably use certificates
    GO
    USE CreditInfo
    GO

    CREATE SCHEMA Sales
    GO
    CREATE TABLE Sales.Customer
    (
        CustomerId  char(10),
        FirstName   varchar(30),
        LastName    varchar(30),
        CreditCardLastFour char(4),
        CreditCardNumber varbinary(44)
    )
    GO

    CREATE PROCEDURE Customer$insert
    (
        @CustomerId  char(10),
        @FirstName   varchar(10),
        @LastName    varchar(10),
        @CreditCardNumber char(16)
    )
    WITH EXECUTE AS 'dbo'
    as

    INSERT INTO Sales.Customer (CustomerId,FirstName, LastName, CreditCardLastFour,
                                CreditCardNumber)
    SELECT  @CustomerId, @FirstName,@LastName,substring(@CreditCardNumber,13,4),
            encryptByPassPhrase(pass.passPhrase, @CreditCardNumber)
    FROM    encryptionMaster.Security.passphrase as pass

    GO

    EXEC Customer$insert 'cust1','Bob','jones','0000111122223333'
    GO

    CREATE PROCEDURE Sales.CustomerWithCreditCard
    WITH EXECUTE AS 'dbo'
    AS
     BEGIN
            SELECT  Customer.CustomerId, FirstName, LastName,
                    CreditCardLastFour,
                    cast(decryptByPassPhrase(pass.passPhrase,CreditCardNumber)
                                 as char(16)) as CreditCardNumber
            FROM    Sales.Customer
                            CROSS JOIN encryptionMaster.Security.passphrase as pass
     END
    GO

    EXEC Sales.CustomerWithCreditCard
    GO

    --------------------------------------------------------------------------------------
    -- Monitoring and Auditing; Server and Database Audit; Defining an Audit Specification
    --------------------------------------------------------------------------------------
    Go
    USE master
    GO
    CREATE SERVER AUDIT ProSQLServerDatabaseDesign_Audit
    TO FILE                        --choose your own directory, I expect most people
    (     FILEPATH = N'c:\temp\' --have a temp directory on their system drive
          ,MAXSIZE = 15 MB
         ,MAX_ROLLOVER_FILES = 0 --unlimited
    )
    WITH
    (
         ON_FAILURE = SHUTDOWN --if the file cannot be written to,
                          --shutdown the server
    )
    GO

    CREATE SERVER AUDIT SPECIFICATION ProSQLServerDatabaseDesign_Server_Audit
        FOR SERVER AUDIT ProSQLServerDatabaseDesign_Audit
        WITH (STATE = OFF) --disabled. we will enable it later
    GO

    ALTER SERVER AUDIT SPECIFICATION ProSQLServerDatabaseDesign_Server_Audit
        ADD (SERVER_PRINCIPAL_CHANGE_GROUP)

    GO

    USE SecurityChapter
    GO
    CREATE DATABASE AUDIT SPECIFICATION
                       ProSQLServerDatabaseDesign_Database_Audit
        FOR SERVER AUDIT ProSQLServerDatabaseDesign_Audit
        WITH (STATE = OFF)
    GO

    ALTER DATABASE AUDIT SPECIFICATION
    ProSQLServerDatabaseDesign_Database_Audit
        ADD (SELECT ON Products.Product BY employee,manager),
        ADD (SELECT ON Products.AllProducts BY public)
    GO

    USE master
    GO
    ALTER SERVER AUDIT ProSQLServerDatabaseDesign_Audit
        WITH (STATE = ON)
    ALTER SERVER AUDIT SPECIFICATION ProSQLServerDatabaseDesign_Server_Audit
        WITH (STATE = ON)
    GO
    USE SecurityChapter
    GO
    ALTER DATABASE AUDIT SPECIFICATION ProSQLServerDatabaseDesign_Database_Audit
        WITH (STATE = ON)
    GO


    CREATE drop LOGIN MrSmith WITH PASSWORD = 'Not a good password'
    GO
    EXECUTE AS USER = 'manager'
    GO
    SELECT *
    FROM   Products.Product
    GO
    SELECT  *
    FROM     Products.AllProducts
    REVERT
    GO
    SELECT  *
    FROM     Products.AllProducts
    GO

    SELECT event_time, succeeded,
           database_principal_name,statement
    FROM sys.fn_get_audit_file ('c:\temp\*',default,default);
    GO

    SELECT  sas.name as audit_specification_name,
            audit_action_name
    FROM    sys.server_audits as sa
              join sys.server_audit_specifications as sas
                 on sa.audit_guid = sas.audit_guid
              join sys.server_audit_specification_details as sasd
                 on sas.server_specification_id = sasd.server_specification_id
    WHERE  sa.name = 'ProSQLServerDatabaseDesign_Audit'

    SELECT --sas.name  as audit_specification_name,
           audit_action_name,dp.name as [principal],
           SCHEMA_NAME(o.schema_id) + '.' + o.name as object
    FROM   sys.server_audits as sa
             join sys.database_audit_specifications as sas
                 on sa.audit_guid = sas.audit_guid
             join sys.database_audit_specification_details as sasd
                 on sas.database_specification_id = sasd.database_specification_id
             join sys.database_principals as dp
                 on dp.principal_id = sasd.audited_principal_id
             join sys.objects as o
                 on o.object_id = sasd.major_id
    WHERE  sa.name = 'ProSQLServerDatabaseDesign_Audit'
      and  sasd.minor_id = 0 --need another query for column level audits
    GO

    --------------------------------------------------------------------------------------
    -- Monitoring and Auditing; Watching Table History Using DML Triggers
    --------------------------------------------------------------------------------------
    GO
    USE SecurityChapter
    GO
    CREATE SCHEMA Sales
    GO
    CREATE SCHEMA Inventory
    GO
    CREATE TABLE Sales.invoice
    (
        InvoiceId   int not null identity(1,1) CONSTRAINT PKInvoice PRIMARY KEY,
        InvoiceNumber char(10) not null
                          CONSTRAINT AKInvoice_InvoiceNumber UNIQUE,
        CustomerName varchar(60) not null , --should be normalized in real database
        InvoiceDate smalldatetime not null
    )
    CREATE TABLE Inventory.Product
    (
        ProductId int identity(1,1) CONSTRAINT PKProduct PRIMARY KEY,
        name varchar(30) not null CONSTRAINT AKProduct_name UNIQUE,
        Description varchar(60) not null ,
        Cost numeric(12,4) not null
    )
    CREATE TABLE Sales.InvoiceLineItem
    (
        InvoiceLineItemId int identity(1,1)
                          CONSTRAINT PKInvoiceLineItem PRIMARY KEY,
        InvoiceId int not null,
        ProductId int not null,
        Quantity numeric(6,2) not null,
        Cost numeric(12,4) not null,
        discount numeric(3,2) not null,
        discountExplanation varchar(200) not null,
        CONSTRAINT AKInvoiceLineItem_InvoiceAndProduct
                 UNIQUE (InvoiceId, ProductId),
        CONSTRAINT FKSales_Invoice$listsSoldProductsIn$Sales_InvoiceLineItem
                 FOREIGN KEY (InvoiceId) REFERENCES Sales.Invoice(InvoiceId),
        CONSTRAINT FKSales_Product$isSoldVia$Sales_InvoiceLineItem
                 FOREIGN KEY (InvoiceId) REFERENCES Sales.Invoice(InvoiceId)
        --more constraints should be in place for full implementation
    )

    GO
    CREATE TABLE Sales.InvoiceLineItemDiscountAudit
    (
        InvoiceLineItemDiscountAudit  int identity(1,1)
              CONSTRAINT PKInvoiceLineItemDiscountAudit PRIMARY KEY,
        InvoiceId   int,
        InvoiceLineItemId int,
        AuditTime   datetime,
        SetByUserId sysname,
        Quantity numeric(6,2) not null,
        Cost numeric(12,4) not null,
        Discount numeric(3,2) not null,
        DiscountExplanation varchar(300) not null
    )

    GO

    CREATE TRIGGER Sales.InvoiceLineItem$insertAndUpdateAuditTrail
    ON Sales.InvoiceLineItem
    AFTER INSERT,UPDATE AS
    BEGIN

       DECLARE @rowsAffected int,    --stores the number of rows affected
               @msg varchar(2000)    --used to hold the error message

       SET @rowsAffected = @@rowcount

       --no need to continue on if no rows affected
       IF @rowsAffected = 0 return

       SET NOCOUNT ON --to avoid the rowcount messages
       SET ROWCOUNT 0 --in case the client has modified the rowcount
       BEGIN TRY
          --[validation blocks]
          --[modification blocks]
          IF UPDATE(Cost)
             INSERT INTO Sales.InvoiceLineItemDiscountAudit (InvoiceId,
                             InvoiceLineItemId, AuditTime, SetByUserId, Quantity,
                             Cost, Discount, DiscountExplanation)
             SELECT inserted.InvoiceId, inserted.InvoiceLineItemId,
                    current_timestamp, suser_sname(), inserted.Quantity,
                    inserted.Cost, inserted.Discount,
                    inserted.DiscountExplanation

             from   inserted
                       join Inventory.Product as Product
                          on inserted.ProductId = Product.ProductId
             --if the Discount is more than 0, or the cost supplied is less than the
             --current value
             where   inserted.Discount > 0
                or   inserted.Cost < Product.Cost
                          -- if it was the same or greater, that is good!
                          -- this keeps us from logging if the cost didn't actually
                          -- change
       END TRY
       BEGIN CATCH
                   IF @@trancount > 0
                         ROLLBACK TRANSACTION

                  --or this will not get rolled back
                  --EXECUTE dbo.errorLog$insert

                  DECLARE @ERROR_MESSAGE varchar(8000)
                  SET @ERROR_MESSAGE = ERROR_MESSAGE()
                  RAISERROR (@ERROR_MESSAGE,16,1)

         END CATCH
    END
    GO


    INSERT INTO Inventory.Product(name, Description,Cost)
    VALUES ('Duck Picture','Picture on the wall in my hotelRoom',200.00),
           ('Cow Picture','Picture on the other wall in my hotelRoom',150.00)

    GO

    INSERT INTO Sales.Invoice(InvoiceNumber, CustomerName, InvoiceDate)
    VALUES ('IE00000001','The Hotel Picture Company','1/1/2005')
    GO

    INSERT INTO Sales.InvoiceLineItem(InvoiceId, ProductId, Quantity,
                                      Cost, Discount, DiscountExplanation)
    SELECT  (SELECT InvoiceId
             FROM   Sales.Invoice
             WHERE  InvoiceNumber = 'IE00000001'),
            (SELECT ProductId
             FROM   Inventory.Product
             WHERE  Name = 'Duck Picture'),  1,200,0,''
    GO

    SELECT * FROM Sales.InvoiceLineItemDiscountAudit
    GO

    INSERT INTO Sales.InvoiceLineItem(InvoiceId, ProductId, Quantity,
                                      Cost, Discount, DiscountExplanation)
    SELECT  (SELECT InvoiceId
             FROM Sales.Invoice
             WHERE InvoiceNumber = 'IE00000001'),
            (SELECT ProductId
             FROM Inventory.Product
             WHERE name = 'Cow Picture'),
            1,150,.45,'Customer purchased two, so I gave 45% off'

    SELECT * FROM Sales.InvoiceLineItemDiscountAudit

    --------------------------------------------------------------------------------------
    -- Monitoring and Auditing; DDL Triggers; Preventing a DDL Action
    --------------------------------------------------------------------------------------
    GO
    CREATE TRIGGER tr_server$allTableDDL_prevent --note, not a schema owned object
    ON DATABASE
    AFTER CREATE_TABLE, DROP_TABLE, ALTER_TABLE
    AS
     BEGIN
       BEGIN TRY  --note the following line will not wrap
            RAISERROR ('The trigger: tr_server$allTableDDL_prevent must be disabled
                        before making any table modifications',16,1)
       END TRY
       --using the same old error handling
       BEGIN CATCH
                  IF @@trancount > 0
                        ROLLBACK TRANSACTION

                  --commented out, build from Chapter 6 if desired
                  --EXECUTE dbo.errorLog$insert

                  DECLARE @ERROR_MESSAGE varchar(8000)
                  SET @ERROR_MESSAGE = ERROR_MESSAGE()
                  RAISERROR (@ERROR_MESSAGE,16,1)

         END CATCH
    END
    GO

    CREATE TABLE dbo.test  --dbo for simplicity of example
    (
        testId int identity CONSTRAINT PKtest PRIMARY KEY
    )

    --------------------------------------------------------------------------------------
    -- Monitoring and Auditing; DDL Triggers; Recording a DDL Action
    --------------------------------------------------------------------------------------
    GO
    --Note: Slight change in syntax to drop DDL trigger, requires clause indicating
    --where the objects are
    DROP TRIGGER tr_server$allTableDDL_prevent ON DATABASE
    GO

    --first create a table to log to
    CREATE TABLE dbo.TableChangeLog
    (
        TableChangeLogId int identity
            CONSTRAINT pkTableChangeLog PRIMARY KEY (TableChangeLogId),
        ChangeTime      datetime,
        UserName        sysname,
        Ddl             varchar(max)--so we can get as much of the batch as possible
    )
    GO
    --not a schema bound object
    CREATE TRIGGER tr_server$allTableDDL
    ON DATABASE
    AFTER CREATE_TABLE, DROP_TABLE, ALTER_TABLE
    AS
     BEGIN
       SET NOCOUNT ON --to avoid the rowcount messages
       SET ROWCOUNT 0 --in case the client has modified the rowcount

       BEGIN TRY

            --we get our data from the EVENT_INSTANCE XML stream
            INSERT INTO dbo.TableChangeLog (ChangeTime, userName, Ddl)
            SELECT getdate(), user,
                  EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]',
                 'nvarchar(max)')

       END TRY
       --using the same old error handling
       BEGIN CATCH
                  IF @@trancount > 0
                         ROLLBACK TRANSACTION

                  --From Ch6, get code if you want to enable
                  --EXECUTE dbo.errorLog$insert

                  DECLARE @ERROR_MESSAGE varchar(8000)
                  SET @ERROR_MESSAGE = ERROR_MESSAGE()
                  RAISERROR (@ERROR_MESSAGE,16,1)

         END CATCH
    END

    GO

    CREATE TABLE dbo.test
    (
        id int
    )
    GO
    DROP TABLE dbo.test
    GO

    SELECT * FROM dbo.TableChangeLog


    --------------------------------------------------------------------------------------
    -- Monitoring and Auditing; Logging with Profiler
    --------------------------------------------------------------------------------------


    CREATE PROCEDURE dbo.Server$Watch
    as

    --note that we have to do some things because these procedures are very picky
    --about datatypes.
    declare @traceId int, @retval int,
            @stoptime datetime, @maxfilesize bigint, @filecount int
    set @maxfilesize = 10 --MB
    set @filecount = 20

    --creates a trace, placing the file in the root of the server (clearly you should
    --change this location to something that fits your own server standards other than
    --the root of the c: drive)
    exec @retval =  sp_trace_create @traceId = @traceId output,
                         @options = 2, --rollover to a different file
                                       --once max is reached
                         @tracefile = N'c:\trace.trc',
                         @maxfilesize = @maxfilesize,
                         @stoptime = @stoptime,
                         @filecount = 20

    --this is because the fourth parameter must be a bit, and the literal 1 thinks it is
    --an integer
    declare @true bit
    set @true = 1

    --then we manually add events
    exec sp_trace_setevent @traceID, 12, 1, @true
    exec sp_trace_setevent @traceID, 12, 6, @true  --12 = sql:batchstarting
                                                   --6 = NTUserName
    exec sp_trace_setevent @traceID, 12, 7, @true  --12 = sql:batchstarting
                                                   --7=NTDomainName
    exec sp_trace_setevent @traceID, 12, 11, @true --12 = sql:batchstarting
                                                   --11=LoginName
    exec sp_trace_setevent @traceID, 12, 14, @true --12 = sql:batchstarting
                                                   --14=StartTime

    exec sp_trace_setevent @traceID, 13, 1, @true --13 = sql:batchending
                                                  -- 1 = textdata
    exec sp_trace_setevent @traceID, 13, 6, @true --13 = sql:batchending 
                                                  -- 6=NTUserName
    exec sp_trace_setevent @traceID, 13, 7, @true --13 = sql:batchending
                                                  -- 7=NTDomainName
    exec sp_trace_setevent @traceID, 13, 11, @true --13 = sql:batchending 
                                                   --11=LoginName
    exec sp_trace_setevent @traceID, 13, 14, @true --13 = sql:batchending
                                                   --14=StartTime

    --and start the trace
    exec sp_trace_setstatus @traceId = @traceId, @status = 1 --1 starts it

    --this logs that we started the trace to the event viewer
    declare @msg varchar(2000)
    set @msg = 'logging under trace:' + cast(@traceId as varchar(10)) + ' started'
    exec xp_logevent 60000, @msg, 'informational'
    GO

    exec master..sp_procoption 'dbo.Server$Watch','startup','true'
    GO

  • 相关阅读:
    没有一个计时器控制在VB6计时器功能
    检测系统范围内的鼠标事件
    c# Com
    tcpdump
    dd
    dumpe/dumpe2fs/e2fsck
    fdisk
    mkswap/swapon/swapoff/free
    mkfs/mk2fs/fsck/e2fsck/tune2fs/blkid
    parted
  • 原文地址:https://www.cnblogs.com/dushu/p/2508826.html
Copyright © 2011-2022 走看看