Tuesday, July 31, 2007

OK, I'm not normally the one to blog a lot of personal stuff but there's definitely a reason for a lot of my silence over the past couple of months....... I was planning a wedding. OK, Paul helped out more than you would expect - he met with the officiant (Annemarie of Annemarie Juhlian), the photographer (John Mitchell of John Mark Photography), the ceremony/reception venue (the Woodmark Hotel), the florist (Nathan of Fena Flowers), the amazing baker (Mike's Amazing Cakes) and Paul did so much more too! So, I can't say it was all me but that's the excuse I'm using (for my lack of blogging :) and I'm sticking to it! It was a crazy amount of work in general and now I can truly understand why people hire wedding coordinators!!

Anyway, the weekend could NOT have gone better. So many of our friends and family were able to make it - even our one remaining Grandmother (Doris McDonnell, my Father's Mother - who is 84) made the journey out here. Which, btw, was no small feat for her... it was a train to my Mother's house to spend the night, then together they took a train to Chicago's grand central station where they then caught a cab to O'Hare to catch a 4 hour flight to Seattle. And, that was a fairly short flight compared to Goksin Bakir's flight(s) from Istanbul, Gunther Beersaerts' flight(s) from Belgium, Olga Londer's flights from London, Paul's entire family from Glasgow, Scotland, the Tripp/Fussell/Bostick clan's flight(s) from Tampa, Carl Franklin's flight(s) from Connecticut and Richard Campbell's drive down from Vancouver (ok, that was short compared to Peter Bennett's drive from Racine, Wisconsin). And, of course, we had many of the usual suspects: Bob Beauchemin, Brian Randell, Clemens Vasters, Euan Garden, Gert Drapers, Gunther Beersaerts, Juval Lowy, Liz Vitt, Matt Nunn, Michele Leroux Bustamante, and last, but not least, Timmie Huckaby. And, those were only a few of the more public geeks :) :). Speaking of public... I'm *very* afraid of the recorder that Carl (of the infamous DNR) had running during the late night hours of the BBQ on Friday night.

Speaking of the BBQ, here's our favorite photo (so far!) from the BBQ on Friday.

Paul already blogged our favorite (so far!) from the wedding. Oh, and why only "so far?"... John took over 40GB of photos from the weekend (the BBQ was on the 27th and the wedding was on the 29th). We cannot wait to see all of what he's done. There are photos that we've seen now that show us that we never even knew he/they (John/Katie/Boon) were there...capturing moments rather than just posed shots. With how fun, professional, timely and creative they were - it's obvious that they all love what they do. In fact, John feels more like a friend than a vendor. It was truly a pleasure having them attend the wedding...and not just for the photos!

So, I thought I'd blog a tad of the personal stuff today and let you know about the best SQL union of which I'm aware <g>... we look forward to all of the exciting things that SQLskills will be doing as we move forward with Paul coming over from the Microsoft mothership as "Managing Director" starting on September 1st. Stay tuned with us as I know good things are still yet to come.

Cheers,
kt

Tuesday, July 31, 2007 10:24:19 AM (Pacific Standard Time, UTC-08:00)  #    Comments [7]  | 
Thursday, July 26, 2007

I had a customer ask me about the debate of skipping SQL Server 2005 entirely and just moving straight to SQL Server 2008... I haven't thought much about this as most of my direct customers have moved already BUT, I know there are a few out there that have not yet moved.

So, I definitely need to spend some time on SQL Server 2008 upgrade requirements, restrictions, etc. - and that's my plan in the not-too-distant-future BUT, I haven't thought much about it so far.

Your thoughts???

Cheers,
kt

Thursday, July 26, 2007 9:21:43 PM (Pacific Standard Time, UTC-08:00)  #    Comments [9]  | 
Tuesday, July 24, 2007

DDL Triggers were a new feature of SQL Server 2005 and while seemingly simple, they are very powerful. DDL Triggers allow you to trap an attempted DDL operation to audit it, prevent it, or do anything you want to validate/verify/”authorize”/etc – you write the code. And, since a trigger fires as part of the transaction, you can roll it back.

In many conference demos/webcasts, etc., I have provided a sample script that prevents ddl within a [production] database. That script has been really helpful/useful but recently I thought about an update to it…

SQL Server 2005 has another new feature "execute as". While I definitely see many benefits, I’m also a bit concerned. To a certain extent, I feel that the potential for SQL Injection is actually higher. If a developer creates a poorly written/tested stored procedure (ok, therein lies the problem, really!) that includes dynamic string execution AND then uses "execute as" to essentially elevate a user with minimal privileges to a higher level (so that they don’t need to give the base object rights to the user), a malicious user could “inject” code in and actually succeed if the “execute as” user has rights to the injected code. In prior releases, and with the default behavior (execute as caller), this is not possible (which is good for security but bad for dynamically executed strings within stored procedures as base object rights are necessary).

Having said that, and since security is always a concern, my DDL Trigger only audited for the login of the user who executed the statement, not for the actual user that’s logged in. In other words, if EXECUTE AS is used (or SETUSER is used), then the context of the user executing is actually different then the logged in user. To see this shift in context, SQL Server 2005 added a new function: ORIGINAL_LOGIN().

(reading between the lines is even more frightening in that prior to SQL Server 2005, the original user could not be tracked from SETUSER. The good news is that SETUSER is ONLY allowed to be used by DBOs so it’s not as widespread as the potential for “execute as”).

OK, so how can we put all of this together? We’ll want to add the ORIGINAL_LOGIN function into our audit table in our DDL Trigger. Even if you choose NOT to rollback, at least you’ll know who performed the operation (even if from a dynamically executed string!).

USE AdventureWorks;

go

--Create a login/user - just for this exercise

CREATE LOGIN Paul WITH PASSWORD = 'PxKoJ29!07';

go

CREATE USER Paul FOR LOGIN Paul;

go

sp_addrolemember 'db_ddladmin', 'Paul'

go

 

CREATE SCHEMA SecurityAdministration

go

CREATE TABLE SecurityAdministration.AuditDDLOperations

(

            OpID                            int                                NOT NULL identity    

                                                                                    CONSTRAINT AuditDDLOperationsPK

                                                                                                PRIMARY KEY CLUSTERED,

            OriginalLoginName    sysname                     NOT NULL,

            LoginName                 sysname                     NOT NULL,

            UserName                   sysname                     NOT NULL,

            PostTime                     datetime                     NOT NULL,

            EventType                   nvarchar(100)            NOT NULL,

            DDLOp                        nvarchar(2000)          NOT NULL

);

go

GRANT INSERT ON SecurityAdministration.AuditDDLOperations TO public;

go

 

CREATE TRIGGER PreventAllDDL

ON DATABASE

WITH ENCRYPTION

FOR DDL_DATABASE_LEVEL_EVENTS

AS

DECLARE @data XML

SET @data = EVENTDATA()

RAISERROR ('DDL Operations are prohibited on this production database. Please contact ITOperations for proper policies and change control procedures.', 16, -1)

ROLLBACK

INSERT SecurityAdministration.AuditDDLOperations

                        (OriginalLoginName,

                         LoginName,

                         UserName,

                         PostTime,

                         EventType,

                         DDLOp)

VALUES   (ORIGINAL_LOGIN(), SYSTEM_USER, CURRENT_USER, GETDATE(),

   @data.value('(/EVENT_INSTANCE/EventType)[1]', 'nvarchar(100)'),

   @data.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'nvarchar(2000)') )

RETURN;

go

 

--Test the trigger.

CREATE TABLE TestTable (col1 int);

go

DROP TABLE SecurityAdministration.AuditDDLOperations;

go

EXECUTE AS LOGIN = 'Paul' -- note: Remember, Paul is a DDL_admin

go

DROP TABLE SecurityAdministration.AuditDDLOperations;

go

REVERT;

go

 

SELECT * FROM SecurityAdministration.AuditDDLOperations;

go

DROP TRIGGER PreventAllDDL ON DATABASE;

go

DROP TABLE SecurityAdministration.AuditDDLOperations;

go

DROP SCHEMA SecurityAdministration;

go

DROP USER Paul;

go
DROP LOGIN Paul;
go

 

So, have fun testing with this one.

 

Thanks for reading!

kt

Tuesday, July 24, 2007 5:31:20 AM (Pacific Standard Time, UTC-08:00)  #    Comments [4]  | 

Theme design by Jelle Druyts

Pick a theme: