We rise up for the things we believe in over and over again

Казалось бы, ситуация с принтерами уже давно отлажена. Ну иногда переезжают они, но какого-то прям ада в этом уже нет. Скрипты работают на полную мощность, снимая изрядную часть нагрузки с сотрудников по отслеживанию и актуализации данных на инфраструктурных серверах. Но идилия не вечна.

Повадились сотрудники печатать на чужих принтерах. Как именно - я не понимаю, учитывая, что сами они принтеры не подключают (я даже не в курсе, знают ли они, как это вообще делается), все выполняется автоматом через политики. И высокому начальству это стало не по нраву.

В общем, спустили задачу. Из всех принтеров в настройках безопасности нужно убрать запись Everyone - Allow Print, а вместо нее подставить группу, в которую входят сотрудники, имеющие право на этом принтере печатать. Группы эти уже давно есть, хоть что-то не придется в авральном порядке создавать.

То есть имеем ситуацию: есть принтер prn-hp1235. В недрах AD есть группа с таким же именем, в ней сидит кучка пользователей, которым этот принтер через политики и подключается. Порядок действий:
- Открыть настройки безопасности принтера,
- вынести оттуда запись с группой Everyone,
- добавить группу prn-hp1235, отметив галкой разрешение Allow Print и только его,
- закрыть настройки принтера.

И так, порядка 600 штук. Весело, правда? :) Вот и я думаю, что весело. Начнем ковыряться.

В свойствах принтера есть такой параметр как PermissionSDDL. Собственно, это и есть запись того, кто и что может делать с объектом, просто записано это в формате SDDL - не самая удобная вещь для понимания. Выглядит она вот так:

Да-да, именно так. И вот эту строку (а это именно одна строка) надо как-то распарсить, изменить, измененное утрамбовать обратно в такую же строку и поменять свойства принтера.

Отправной точкой в исследованиях стала вот эта статья, за которую автору огромное спасибо. Для разбора SDDL-строки она использует объект класса Security.AccessControl.CommonSecurityDescriptor - туда заносится SDDL, там формируется нормальный список объектов и их прав, там же меняется состав этих объектов, а затем при промощи метода GetSDDLForm() формируется новая строка SDDL, которая и заносится в свойства принтера.

В теории все просто. На практике... На практике получаем, что на выходе в разрешениях принтера теряются сущности CREATOR OWNER и APPLICATION PACKAGES. И если с пакетами еще куда ни шло, то потеря CREATOR OWNER может привести к невозможности печати (в сети есть упоминания таких случаев). Что же делать? Искать, на каком этапе теряется информация об этих объектах. Выяснилось, что исчезают они как раз в момент парсинга SDDL в объект CommonSecurityDescriptor. Не умеет он, видимо, с ними работать (хотя почему?).

Пришлось искать замену. И она нашлась в лице System.Security.AccessControl.RawSecurityDescriptor. Конечно, работать с Raw немного муторнее, чем с Common (формирование записи с группой сотрудников с нуля доставило), но результат получился тот, что и заказывали.

Итак, исходная информация:
- имя принт-сервера: ps1
- маска имен принтеров: либо prn*, либо mfd* (multifunctional device)
- SID группы Everyone: S-1-1-0 (константа, не меняется нигде и никогда)

Поехали :)


Пожалуй, за всю мою практику еще не приходилось настолько плотно работать с DACL. Хорошо, что хотя бы SACL тут не участвовал :)

@музыка: Земля Ветров - Город под пеплом

@темы: PowerShell, Scripting

Комментарии
17.04.2018 в 12:00

Frozen flame
> Выглядит она вот так

Шёл 2018 год… (^  ^)'
17.04.2018 в 12:12

We rise up for the things we believe in over and over again
Tenno Seremel, увы, чего-то более удобного для машин пока еще не придумали. А для людей... для них как раз и создали кучку объектов для парсинга подобных строк. Правда, неясно, зачем их так много. Неужели одним обойтись нельзя?
17.04.2018 в 12:17

Frozen flame
Hikedaya,
> чего-то более удобного для машин пока еще не придумали.

Управлять этой байдой всё равно человеку, даже если кодом. Чем это удобнее XML или JSON для машины (экранирование всё равно нужно, если что)? Да хоть ini-файлы. А так одно неверное движение и у тебя всё уехало к чертям. Нафиг нафиг такое удобство.
17.04.2018 в 12:53

We rise up for the things we believe in over and over again
Tenno Seremel, ну, на практике разбирать SDDL непосредственно мне приходилось только один раз (не этот). Во всех остальных случаях всегда находилось что-то, способное его читать и править в нормальном удобоваримом виде, а не в этой мешанине символов :)
17.04.2018 в 12:54

Frozen flame
Hikedaya, а было бы что-то нормальное, ты бы просто поменял что надо)
17.04.2018 в 14:03

We rise up for the things we believe in over and over again
Tenno Seremel, самому бы хотелось. Но за неимением горничной, как говорится... :)
17.04.2018 в 15:38

Frozen flame
Hikedaya, 2 горничных и одного батлера, пожалуйста! :D
17.04.2018 в 17:59

We rise up for the things we believe in over and over again
Tenno Seremel, горничных я еще пойму, даже двух, а батлер на кой черт? )
17.04.2018 в 18:38

Frozen flame
Hikedaya, для антуража, а уж если ещё и боевой…)
18.04.2018 в 01:05

Тотальная неудачница и убийца жёстких дисков.
У меня расширение для Проводника стоит FilePermsBox, которое добавляет настройку прав в Homeko XP. Ну, чтобы через WinFile постоянно не соваться, тем более, что там настройка сильно упрощена, ибо из четвёрки программа. Так вот, редактор она показывает в отдельном окне, а не во вкладке (не знаю почему так), но на вкладке окна свойств файла показывается как раз вот такая байда.



читать дальше
18.04.2018 в 06:33

We rise up for the things we believe in over and over again
как раз вот такая байда.
Ничего удивительного. SDDL - универсальная вещь, и используется для записи ACL любых объектов в виндах :)
20.04.2018 в 09:08

Тотальная неудачница и убийца жёстких дисков.
Лучше бы они и правда XML использовали, а то внутрях оно всё равно в двоичном виде содержится.

/* Но так уж исторически сложилось. */
20.04.2018 в 09:29

Frozen flame
Легаси — страшная штука!