Даем возможность пользователю создавать логины в SQL Server, не давая прав администратора.

добавлено: 08 апр 11
понравилось:0
просмотров: 8737
комментов: 1

теги:

Автор: DeColo®es

Очень популярный на форумах по SQL Server вопрос - "Как защититься от администратора?".
Самый популярный ответ "А не надо пущать!"
Но что делать, когда кто-то должен все-таки управлять сервером?
Например, создавать логины новых пользователей...

Рассмотрим сценарий (так теперь в Microsoft любят делать вместо просто создания красивых абстрактных технологий :) ):

Вы создали базу данных и установили заказчику.

Вы не хотите, чтобы он "ковырялся" в ней и для этого (например)

  • Доступа к таблицам нет, вся работа - только через процедуры
  • Настроили кучу джобов, которые обслуживают базу
  • Обеспечили возможность безопасного соединения по VPN на случай "если что-то слетит".
  • Дали "самый главный пароль" в запечатанном конверте директору под расписку.
  • Местному админу дали права администратора своей базы (не sysadmin и не db_owner), все возможности которого сводятся только к настройке бизнес-процессов в программе
    Но через 2 месяца Вы поняли, что каждый раз заводить логин самому уже надоело, поскольку максимум, что может сделать любой другой пользователь - это поработать в программе.

    Итак, наша задача дать простому пользователю (ну или не очень простому) не давая прав администратора, возможность создавать логины.

    В принципе, есть такое право - ALTER ANY LOGIN, но для нас этого слишком много! Ведь он же сможет менять пароли и даже удалять пользователей!
    (В моей практике был случай, когда не в меру шустрый коммерческий директор, у которого были права sysadmin как раз для раздачи прав, решил поковыряться в настройках доступа не из интерфейса программы, а из Enterprise Manager :) )

    Еще есть конструкция EXECUTE AS...
    Потратив на попытки прикрутить ее к этой задаче час-другой, разработчики обычно приходят к выводу, что все-таки создать логин не получится - impersonate для этой операции не работает и сервер явно проверяет права пользователя, подключившегося к нему.

    А еще есть вариант: пишется процедура, которая сама логин не создает, а только кладет сам логин и пароль в некую табличку, данные из которой забирает специальный job и под правами sa создает все, что нужно. Ну а job выполняется раз в час или в минуту - по желанию.
    Но например в Express редакциях нет SQL Agent-а...

    Все гораздо проще!

    Можно воспользоваться сертификатами (это совсем не больно и не надо ждать, пока job отработает):

    -- Процедура регистрации нового пользователя в системе
    create procedure dbo.___CreateLogin
          @login varchar(128),
          @password varchar(128)
    as
    begin
    declare @sql varchar(max)    
    set @sql = 'create login '
          +quotename(@login, '[')
          +' with password = '''
          +replace(@password, '''', '''''')+''''
    exec(@sql)
    end
    go
    -- И даже даем права на выполнение
    grant execute on dbo.___CreateLogin to Demo
    -- Но этого мало...
    -- Создаем сертификат
    CREATE CERTIFICATE SecurityDummyCertificate
    ENCRYPTION BY PASSWORD = 'P@ssw0rds$houldBeReally$tr0ng'
    WITH SUBJECT = 'For the very important things', 
    EXPIRY_DATE = '2015-12-31'
    -- Создаем логин из сертификата
    CREATE LOGIN VirtualSecurityOfficer
    FROM CERTIFICATE SecurityDummyCertificate;
    go
    -- Даем этому виртуальному логину нужные права
    grant alter any login to VirtualSecurityOfficer
    go
    -- Подписываем процедуру сертификатом
    ADD SIGNATURE TO dbo.___CreateLogin 
    BY CERTIFICATE SecurityDummyCertificate
    WITH PASSWORD = 'P@ssw0rds$houldBeReally$tr0ng'
    go
    -- Вот теперь все работает

    Теперь наш логин Demo может запускать процедуру ___CreateLogin, у которой есть возможность модифицировать логины, но функционально - можно только создавать.

    важный момент
    Поскольку логины существуют на уровне сервера, то данный скрипт нужно выполнять в базе данных master


    У данного решения есть и недостаток: пароль передается "открытым текстом". Но это можно "решить" либо включив шифрацию траффика, либо - передавать в процедуру пароль, шифрованный спелиально для этого созданным открытым ключем.

    Исходный материал: http://msdn.microsoft.com/en-us/library/bb283630.aspx
    То же, на русском: http://msdn.microsoft.com/ru-ru/library/bb283630.aspx
  • Комментарии


    • Прикольно, спасибо! Раньше подобные задачи решал через шедулющуюся табличку.



    Необходимо войти на сайт, чтобы оставлять комментарии