Контроллер домена на Samba 3


На главную

Содержание:

Цели и требования

Наверх

В настоящей статье я попытаюсь наиболее полно рассмотреть аспекты конфигурации, а так же методы управления контроллером домена на базе Samba 3. Последнюю версию сервера Samba вы можете взять с официального сайта Samba. Скомпилируйте и установите сервер на вашу систему. Если у вас возникли проблемы со сборкой, то рекомендую обратиться к документации на сервере Opennet. Если чтение документации не помогло, перечитайте еще раз. В крайнем случае, обратитесь к гуру, которые частенько захаживают на форум сайта Opennet - есть надежда, что кто нибудь вам поможет.

Будем исходить из того, что у вас операционная система Linux и Samba установлена в каталог /usr/local/samba, а конфигурационные файлы находятся в каталоге /etc/samba.

Совет


Устанавливайте Samba в каталог /usr/local/samba-verion, где version - версия сервера. В этом случае вы сможете легко делать апгрейд сервера, установив по такому же принципу новую версию. Просто создайте символическую ссылку samba на каталог с нужной версией Samba. Только не забывайте, что в случае апгрейда вам необходимо будет перенести содержимое подкаталога "var/locks" из прежней версии Samba. Хотя, никто не мешает вам таким же образом вынести каталог "var/locks" за пределы каталога сервера и использовать символическую ссылку. То же самое следует сделать с каталогом "private".

Для начала определимся, что же мы хотим получить. Мы хотим получить надежный контроллер домена а-ля Windows NT. В состав нашего домена будут входить рабочие станции под управлением операционной системы Windows. Основные требования к контроллеру

  • Контроллером домена можно управлять с помощью специального программного обеспечения, функционирующего в среде Windows
  • Время на компьютерах-участниках домена автоматически синхронизируется с временем контроллера домена
  • Профили пользователей не хранятся на сервере (странно что я об этом пишу, да)

Базовая конфигурация

Наверх

Нам понадобятся две службы, которые входят в состав Samba. Это два демона - nmbd и smbd. Первый занимается разрешением имен NetBIOS. Этот демон будет выполнять роль доменного обозревателя. Второй демон предоставляет доступ к объявленным общим ресурсам, а у нас будет минимум один общий ресурс - netlogon. Ниже конфигурация типового контроллера домена, который определяет параметры как smbd, так и nmbd

[global]
# Нижеследующие строки можно менять по желанию.
server string = Primary Domain Controller (Samba %v)
workgroup = MIDEARTH
netbios name = FRODO

# Далее директивы, определяющие контроллер домена.
# По умолчанию security = user, что нам собственно и нужно,
# по этому мы не определяем директиву security.
encrypt password = yes
domain master = yes
preferred master = yes
domain logons = yes
os level = 255
idmap uid = 10000-20000
idmap gid = 10000-20000
admin users = root

# То, что нужно для сервера времени
time server = yes
# Если необходимо, определите значение смещения времени.
# Смещение указывается в минутах относительно GMT
;time offset =

# Определим на всякий случай файл сопоставления имен
username map = /etc/samba/usersmap.txt

# Т.к. подключаться будут только рабочие станции по Windows, запишем просто
logon script = STARTUP.BAT
# важно перекрыть дефолтный путь к профилю
logon path =

[homes]
read only = no
browsable = no
guest ok = no

[netlogon]
# Наша единственная шара, которая требуется для логина.
comment = Network logon service
path = /etc/samba/netlogon
writable = no
browseable = no
Почему мы указываем пустое значение для директивы logon path? Потому что по умолчанию это значения указывает на определенный каталог, конкретно на "\\%N\\%U\profile". Мы решили, что не будем хранить профили на сервере. Во-первых, это жесткое ограничение мобильности. Во-вторых - лишняя путаница. По этому указываем пустой путь.

Совет


Если у вас клиенты под управлением различных операционных систем (не только Windows), то вероятно скрипт STARTUP.BAT будет работать не корректно или вообще не будет работать. Выйти из этой ситуации можно следующим образом. Напишите скрипты для каждой из используемых в сети операционных систем (на равнозначные можно создать символические ссылки). Для того, что бы назначать скрипты в соответствии со спецификой операционной системы можно воспользоваться переменной %a, которая содержит идентификатор архитектуры удаленной станции (т.е. той станции, которая выполняет вход). Определение значения для директивы logon script в данном случае может выглядеть так: logon script = %a.BAT

Убедитесь, что все необходимые каталоги и файлы созданы. Создайте пустой файл STARTUP.BAT и поместите его в каталог "/etc/samba/netlogon".

Теперь необходимо добавить пользователя root, которого мы указали в качестве администратора нашего домена. Так как в системе у нас уже есть пользователь root, то нам остается только добавить этого пользователя в базу данных сервера Samba

[root@avalon bin]# ./smbpasswd -a root
Пароль, который вам предложат ввести может не совпадать с паролем пользователя root вашей системы. Более того, я настаиваю что бы вы ввели пароль, отличный от системного. Сделать это следует из соображений безопасности.

Тестирование и запуск

Наверх

Теперь давайте с помощью программы testparm протестируем конфигурацию.

[root@avalon /]# cd /usr/local/samba/bin
[root@avalon bin]# ./testparm
Смотрите внимательно на вывод testparm. Вы можете увидеть в какой роли будет выступать ваш сервер в сети. В нашем случае это должно быть ROLE_DOMAIN_PDC. Если в конфигурации есть синтаксические ошибки, то testparm сообщит об этом. Однако, программа не проверяет наличие указанных файлов и каталогов, так что позаботьтесь об этом сами.

Теперь решим вопрос с запуском сервера. В тарболе Samba есть подкаталог packaging. В этом подкаталоге вы найдете все необходимое, что бы автоматизировать запуск сервиса Samba при загрузке системы. Для моей системы я скопировал скрипт "packaging/Mandrake/smb.init" в каталог "/etc/rc.d/init.d", активировал и запустил Samba

[root@avalon /]# cd /etc/rc.d/init.d
[root@avalon init.d]# chkconfig --add smb.init
[root@avalon init.d]# ./smb.init start
Настало время проверить работоспособность нашего сервера. Прежде всего следует убедиться, что сервер нормально запустился
[root@avalon init.d]# ps -awx | grep 'mbd'
Если кроме grep-а ничего нет, то самое время поглядеть лог-файлы Samba. В нашем случае они находятся в каталоге "/usr/local/samba/var".

Если же все нормально и запущены и smdb и nmbd, то попытаемся получить список доступных ресурсов посредством команды smbclient


[root@avalon init.d]# cd /usr/local/samba/bin
[root@avalon bin]# ./smbclient -L localhost -Uroot%password
Само-собой, password необходимо заменить на тот, который вы указали в момент создания учетной записи командой smbpasswd. Если все хорошо, то получим список шар локалхоста, а так же список всех тачек, которые доступны в рабочей группе или домене. Пробуем законнектиться к домашнему каталогу.
#./smbclient -Uroot%password '\\LOCALHOST\root'
При успешном подключении можно вводить команды, например
smb: \> ls
Получим список файлов. Выйти можно введя команду exit.

Управление контроллером домена

Наверх

Мы убедились что наш сервер работает. Теперь настало время заняться деталями. Прежде всего идем на сайт Microsoft и скачиваем пакет программ, которые позволят администрировать учетные записи пользователей, серверов и рабочих станций, а так же позволят создавать новые сетевые ресурсы и определять параметры доступа к этим ресурсам. На этой странице указано, откуда можно загрузить версии usrmgr.exe и srvmgr.exe для операционных систем Windows 9x и Windows NT. Загрузите нужный вам вариант, распакуйте в отдельный каталог и познакомтесь с этими программами.

Наш контроллер домена пока ничего не умеет, в том числе обрабатывать запросы программ srvmgr.exe и usrmgr.exe. Но в Samba предусмотрена возможность дописать необходимые действия, связанные с тем или иным административным событием. Мы можем написать для каждого такого действия отдельный скрипт и указать необходимость его выполнения в конфигурации Samba. Все скрипты будем складывать в каталог "/etc/samba/scripts", а директивы назначения скриптов будем дописывать в конец секции global нашего конфигурационного файла. Ниже перечислены директивы конфигурационного файла Samba, которые мы будем определять

Проверка карты сопоставлений групп

Наверх

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

[root@avalon /]# cd /usr/local/samba/bin
[root@avalon bin]# ./net groupmap list
В результате, вы увидете список групп домена. Каждая строка содержит название доменной группы пользователей, идентификатор группы и системную группу, сопоставленную доменной. В нашем случае каждой доменной группе сопоставлено значение -1, что означает отсутствие сопоставления с системной группой. Иначе говоря, для виртуальной доменной группы отсутствует системная группа-аналог. Прежде чем приступить к дальнейшей работе, мы должны создать в необходимые группы и указать какая системная группа какой доменной соответствует.

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

#!/usr/bin/perl -w
# checkmap.pl
# v1.01
use strict;
use vars qw/$path2net %groupmap %realmap %group/;
$path2net = '/usr/local/samba/bin/net';
%groupmap = (
   'Domain Guests' => 'Guests',
);

get_groupmap(\%realmap) or exit(1);
get_unixgroup(\%group) or exit(1);

while (my($domain_group,$unix_group) = each(%realmap)){
    $unix_group = $groupmap{$domain_group}
        if exists($groupmap{$domain_group});
    $unix_group = check_name($unix_group=~/^\-?[\d]*$/
        ? $domain_group : $unix_group);
    unless (exists($group{$unix_group})){
        system("/usr/sbin/groupadd $unix_group");
        exit(2) if $? >> 8;
        $group{$unix_group} = [];
    }

    if ($realmap{$domain_group} ne $unix_group){
        system(sprintf("%s groupmap modify ntgroup='%s' unixgroup='%s'",
            $path2net,$domain_group,$unix_group));
        exit(3) if $? >> 8;
    }
}
exit(0);
Обратите внимание на то, что происходит внутри цикла. Мы перебираем сопоставления, заданные на момент запуска программы. Если для очередной виртуальной группы в хэш-массиве определена существующая системная группа, то сопоставленная в настоящий момент группа будет заменена на указанную.

Далее, имя группы проверяется на соответствие принятому в Linux формату. Работу функции check_name мы рассмотрим несколько позже, а сейчас посмотрите на условие, определяющее значение аргумента вызова check_name. Когда виртуальной группе не сопоставлена реальная системная группа, и при этом реальная группа для сопоставления не указана в хэш-массиве %groupmap, в этом случае в переменной $unix_group будет значение -1. Иначе говоря, -1 означает отсутствие сопоставления (вы уже могли в этом убедиться, когда вызывали net groupmap list).

Когда виртуальной группе сопоставлена несуществующая системная группа, то содержимое $unix_group на момент вызова check_name будет содержать gid той группы, которая определенно существовала ранее (вы не сможете сопоставить несуществующую группу), но по каким либо причинам была удалена.

А теперь, если мы вспомним правила определения имен групп пользователей в Linux (группы не могут начинаться с цифровых символов), и связав все вышесказанное вместе, мы увидим, что посредством одного оператора мы решаем сразу две задачи. Во-первых, для тех виртуальных групп, которым сопоставлено значение -1, в свою очередь попадающее под определенное регулярное выражение, в качестве имени реальной группы будет выбрано имя виртуальной группы, подогнанное под стандарт имен групп в Linux. Во-вторых, для тех виртуальных групп, которым сопоставлено числовое (или начинающееся с цифрового символа) значение, указывающее на несуществующую группу (или некорректное имя группы) будет так же выбрано имя виртуальной группы, подогнанное под стандарт имен групп в Linux. Т.о. в арсенал к нам попадает скрипт, в некоторой мере исправляющий ошибки администратора.

Как видим в коде, у нас есть еще три функции: get_unixgroup, get_groupmap и check_name. Начнем с check_name

sub check_name{
    my ($name) = @_;
    $name =~ s#[^0-9a-zA-Z_]#_#g;
    $name =~ s#^[^a-zA-Z]*##;
    return substr($name,0,16);
}
Как уже говорилось выше, имя группы в Linux не может начинаться с цифровых символов. Удалением цифровых символов в имени группы занимается второе регулярное выражение. Кроме того, длина имени группы не может превышать 16 символов. По этому, функция возвращает не более 16 первых символов преобразованного имени.

Функция get_unixgroup заполняет хэш-массив данными о реальных (системных) группах. Эта функция работает с файлом "/etc/group". Ключами хэша становятся названия групп, а в качестве значений выступает массив полей из файла "/etc/group".

sub get_unixgroup{
    my $group_ref = shift;
    unless (open(GROUP,'/etc/group')){
        warn "Couldn't open /etc/group: $!\n";
        return 0;
    }
    my ($line,@fields);
    while ($line = <GROUP>){
        chomp($line);
        @fields = split(':',$line);
        next unless @fields;
        $group_ref->{$fields[0]} = [ @fields ];
    }
    close(GROUP);
    return 1;
}
Функция get_groupmap работает примерно так же как и get_unixgroup, но в отличии от get_unixgroup обрабатывает результат вывода программы net. Так как net groupmap list дает выдает нам сопоставления в виде пары имен, ключами хэша задаются имена вирнтуальных доменных групп, а значениями - сопоставленные имена системных групп.
sub get_groupmap{
    my $map_ref = shift;
    unless (open(NET,"$path2net groupmap list|")){
        warn "Couldn't read path2net: $!\n";
        return 0;
    }
    my @map = <NET>;
    close(NET);
    map { chomp; /(^.+?)\s\(.+?\)\s-\>\s(.*)/; $map_ref->{$1} = $2
        unless exists($map_ref{$1}) } @map;
    return 1;
}
Это последняя функция скрипта "checkmapl.pl". Мы будем вызывать этот скрипт в начале работы каждого из административных скриптов. Это несколько замедлит работу основного скрипта, но зато мы будем уверены, что с нашим доменными группам все в порядке и каждой виртуальной группе сопоставлена реальная системная группа.

Добавление машинной учетной записи

Наверх

Прежде чем мы пойдем дальше, следует отдельно сказать об именах, содержащих пробелы. Хотя все наши скрипты разработаны с учетом возможности ввода "дырявых" имен, корректно создать учетную запись с пробелами в имени посредством уже упомянутого User Manager не получится. Все дело в механизме проверки результата выполненного действия сервером. Samba не принимает во внимание код завершения скрипта, а проверяет - привело ли выполнение скрипта к ожидаемому результату. В случае со скриптом добавления пользователя результатом является появление в системе нового пользователя с известным логином. Каким образом выполняется эта проверка, можно выяснить только исследовав исходные коды сервера. Видимо, разработчики просто не учли проверку системного логина, содержащего пробельные символы. Ну и ладно, ведь необходимость "дырявых" имен под сомнением.

Итак, начнем со скрипта добавления учетной записи машины. С помощью директивы add machine script мы можем указать, какую программу необходимо вызвать, в момент создания машинного имени. Будем передавать скрипту в качестве первого аргумента значение %u. Согласно документации, %u символизирует имя пользователя (а станция - это тоже пользователь). В момент запуска программы, вместо %u Samba подставит реальное имя, то самое, которое мы укажем в поле "Computer Name" диалогового окна "Add Computer To Domain" программы Server Manager.

Учетные записи станций идентифицируются постфиксом $ в конце имени. В нашем скрипте нет необходимости заморачиваться добавлением символа $. Samba добавляет этот идентификатор автоматически и в скрипт добавления машины передается полностью сформированное имя.

#!/bin/bash
# addmachine.sh
# v1.0
RETVAL=0
MSG="success"
machinename="$1"
test -z "$machinename" && exit 1

if [ $RETVAL -eq 0 ]; then
    /etc/samba/scripts/checkmap.pl
    RETVAL=$?
    [ $RETVAL -ne 0 ] && MSG="checkmap failed [$RETVAL]"
fi

if [ $RETVAL -eq 0 ]; then
    /usr/sbin/useradd -g nogroup -d /dev/null -s /bin/false "$machinename"
    RETVAL=$?
    [ $RETVAL -ne 0 ] && MSG="useradd failed [$RETVAL]"
fi

if [ $RETVAL -eq 0 ]; then
    /usr/bin/passwd -l "$machinename"
    RETVAL=$?
    [ $RETVAL -ne 0 ] && MSG="passwd failed [$RETVAL]"
fi

echo `date`" Add machine '$machinename' account: $MSG" \
    >> /etc/samba/scripts/log
exit 0
Как видим, в конце работы наш скрипт делает запись о проделанном действии в лог-файл. Все наши скрипты, реализующие действия по управлению контроллером, в конце своей работы будут выполнять запись в лог-файл. Давайте укажем Samba на наш скрипт добавления машины
add machine script = /etc/samba/scripts/addmachine.sh "%u"
Обратите внимание, что мы ограничиваем передаваемое имя двойными кавычками. Это необходимо для того, что бы имена, содержащие пробелы, передавались корректно.

Добавление учетной записи пользователя

Наверх

Разница между скриптом добавления пользователя и скриптом добаления станции в домен заключается только в необходимости блокировать учетную запись станции. В случае с пользовательской учетной записью блокировать ее после создания не нужно, ведь от имени созданной учетной записи будет работать сервер в момент обращения определенного пользователя. Нам достаточно скопировать скрипт добавления машинной учетной записи и удалить пару строк

#!/bin/bash
# adduser.sh
# v1.02
RETVAL=0
MSG="success"
username="$1"
test -z "$username" && exit 1

if [ $RETVAL -eq 0 ]; then
    /etc/samba/scripts/checkmap.pl
    RETVAL=$?
    [ $RETVAL -ne 0 ] && MSG="checkmap failed [$RETVAL]"
fi

if [ $RETVAL -eq 0 ]; then
    /usr/sbin/useradd -g nogroup -d /dev/null -s /bin/false "$username"
    RETVAL=$?
    [ $RETVAL -ne 0 ] && MSG="useradd failed [$RETVAL]"
fi

echo `date`" Add user '$username' account: $MSG" \
    >> /etc/samba/scripts/log
exit 0
Этот скрипт немногим отличается от скрипта добавления машинной учетной записи. Первым делом, вызывается скрипт проверки карты сопоставлений групп. Если его работа завершается без ошибок, то следующим действием является создание учетной записи.

Вы спрашиваете - а почему мы выставляем группу nogroup в качестве первичной и для пользовательский учетных записей, и для машинных? Хвалю за внимательность! Если мы не укажем первичную группу, то программа useradd создаст новую группу для этого пользователя, а нам это не нужно. Для каждой добавляемой учетной записи мы указываем временную группу, так как сразу после создания учетной записи Samba вызовет наш скрипт set primary group, который мы пока еще не написали. Вот он-то и будет выполнять установку правильной первичной группы, которая во всех случаях будет соответствовать группе "Domain Users".

И еще один момент. Вы наверное заметили, что ни в "addmach.sh" ни в "adduser.sh" мы абсолютно никаким образом не проверяем и не корректируем имена. Как упоминалось выше, Samba не учитывает код завершения, а проверяет наличие ожидаемых изменений. В случае с добавлением учетных записей, это появление новой пользовательской учетной записи. Логично предположить, что Samba ожидает появления пользователя с именем, идентичным тому, что было передано в скрипт (и.г. которое было указано в в программах "User Manager" или "Server Manager"). Именно по этому нет смысла проверять или корректировать имена, т.к. малейшее изменение имени приведет к заведомо неудачному выполнению операции. Наш скрипт отработает правильно и добавит учетную запись, но вот Samba при проверке определит, что требуемая учетная запись не была создана.

Для того, чтобы включить наш скрипт в работу сервера, добавим в конец секции global нашего конфигурационного файла Samba следующую строку

add user script = /etc/samba/scripts/adduser.sh "%u"

Удаление учетной записи

Наверх

Для удаления учетных Samba записей вызывает один и тот же скрипт delete user script как для учетных записей пользователей, так и для учетных записей станций (по этой причине в Samba не предусмотрен скрипт delete machine script).

Скрипт удаления учетной записи должен удалять системную учетную запись, сопоставленную пользователю с указанным именем.

#!/bin/bash
# deluser.sh
# v1.01
RETVAL=0
MSG="success"
username="$1"
test -z "$username" && exit 1

if [ $RETVAL -eq 0 ]; then
    /etc/samba/scripts/checkmap.pl
    RETVAL=$?
    [ $RETVAL -ne 0 ] && MSG="checkmap failed [$RETVAL]"
fi

if [ $RETVAL -eq 0 ]; then
    /usr/sbin/userdel "$username"
    RETVAL=$?
    [ $RETVAL -ne 0 ] && MSG="userdel failed [$RETVAL]"
fi

echo `date`" Del user '$username' account: $MSG" \
    >> /etc/samba/scripts/log
exit 0

Разбирать в этом скрипте особо нечего. Укажем в конфигурации Samba


delete user script = /etc/samba/scripts/deluser.sh "%u"

Добавление группы

Наверх

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

#!/bin/bash
# addgroup.sh
# v1.0
RETVAL=0
MSG="success"
groupname="$1"
test -z "$groupname" && exit 1

if [ $RETVAL -eq 0 ]; then
    /etc/samba/scripts/checkmap.pl
    RETVAL=$?
    [ $RETVAL -ne 0 ] && MSG="checkmap failed [$RETVAL]"
fi

groupname=`echo "$groupname"|sed -e "s/[^0-9a-zA-Z]/_/g"`
groupname=`echo "$groupname"|sed -e "s/^[^a-zA-Z]*//"`
grplist=`grep "$groupname" /etc/group|awk -F : '{print $1}'`
if [ $RETVAL -eq 0 -a -z "$grplist" ]; then
    /usr/sbin/groupadd "$groupname"
    RETVAL=$?
    [ $RETVAL -ne 0 ] && MSG="groupadd failed [$RETVAL]"
fi

gid=`grep "$groupname" /etc/group|awk -F : '{print $3}'`
echo $gid
echo `date`" Add group '$groupname': $MSG" \
    >> /etc/samba/scripts/log
exit 0

Первым делом как и в других скриптах, проверяем карту сопоставлений групп. Далее мы изменяем полученное имя группы в соответствии с правилами именования групп в ОС Linux. Фактически выполняются те же самые действия, что и в функции check_name скрипта "checkmap.pl", но несколько другим способом. После обработки имени, мы пытаемся определить, возможно такая группа уже есть. Если группа с укаазнным именем уже есть в системе, то grplist на момент проверки будет не пустым.

Вообще, здесь вариант спорный. Нужно ли интерпретировать наличие группы, как ошибку (попытку дублирования, создание группы, с локальным именем, совпадающим с уже созданной группой, и т.п.) или же можно удовлетвориться существующей группой, пропуская процесс создания, но все-таки сопоставляя заявленному имени уже существующую и возможно уже сопоставленную другой виртуальной группе? Так как вероятность такого совпадения достаточно мала (если у вас крутой домен, то вы должны уметь решать подобные задачи и вряд-ли читаете эту статью, в противном случае наверняка вы ограничитесь небольшим списком групп, при котором возможность совпадения минимальна), мы выберем второй вариант, т.е. удовлетворимся существующей группой и укажем необходимость ее сопоставления заявленной виртуальной группе. В любом случае, мы извлекаем числовой идентификатор группы и печатаем его в STDOUT. Остается только вывести информацию в лог-файл и добавить соответстсвующую директиву в файл конфигурации

add group script = /etc/samba/scripts/addgroup.sh "%g"

Удаление группы

Наверх

В скрипт удаления группы передается имя локальной группы, т.е. имя группы, идентификатор которой был возвращен скриптом "addgroup.sh". Код предельно прост

#!/bin/bash
# delgroup.sh
# v0.1
RETVAL=0
MSG="success"
groupname="$1"
test -z "$groupname" && exit 1

if [ $RETVAL -eq 0 ]; then
    /etc/samba/scripts/checkmap.pl
    RETVAL=$?
    [ $RETVAL -ne 0 ] && MSG="checkmap failed [$RETVAL]"
fi

grplist=`grep "$groupname" /etc/group|wak -F : '{print $1}'`
if [ $RETVAL -eq 0 -a ! -z "$grplist" ]; then
    /usr/sbin/groupdel "$groupname"
    RETVAL=$?
    [ $RETVAL -ne 0 ] && MSG="groupdel failed [$RETVAL]"
fi
echo `date`" Del group '$groupname': $MSG" \
    >> /etc/samba/scripts/log
exit 0

В секцию global конфигурационного файла добавляем
delete group script = /etc/samba/scripts/delgroup.sh "%g"

Установка первичной группы пользователя

Наверх

После создания учетной записи станции или пользователя, Samba автоматически вызывает программу установки первичной группы для добавленного пользователя (если эта программа определена). В качестве аргумента передается UNIX группа, сопоставленная NT-шной группе "Domain Users". Можно сделать вывод, что на этапе создания учетных записей не стоит заморачиваться определением правильной группы (как мы в общем-то и делаем). Для того что бы вызов adduser не привел к созданию новой группы, мы указываем nogroup в качестве временного значения.

А для того, что бы каждому новому бюджету была сопоставлена правильная группа, мы напишем программу, которая посредством команды usermod с ключом -g будет выставлять указанную группу в качестве первичной для конкретного пользователя. В качестве аргументов вызова мы будем получать имя пользователя (а мы знаем, что оно у нас идентично системному) и имя системной группы (имя локальной группы, сопоставленное виртуальной - той, которую нужно сделать первичной). Как видим, здесь особых действий по преобразованию имен из виртуального в системное и наоборот, выполнять не требуется, так как Samba своевременно заботится обо всем.

Обратите внимание, что мы не выполняем никаких проверок правильности определения группы в данном скрипте. В этом нет особой необходимости, потому как если Samba попытается сослаться на несуществующую группу, то это наверняка будет числовой идентификатор, оставшийся от удаленной группы. Мы все равно не сможем создать группу, имя которой начинается с цифрового символа. Кроме того, не зря же мы вызываем скрипт "checkmap.pl". Ведь он как раз и предназначен для исправления подобных ситуаций. В итоге получится скрипт следующего содержания

#!/bin/bash
# setprimarygroup.sh
# v1.0
RETVAL=0
MSG="success"
username="$1"
groupname="$2"
test -z "$username" || test -z "$groupname" && exit 1

if [ RETVAL -eq 0 ]; then
    /etc/samba/scripts/checkmap.pl
    RETVAL=$?
    [ $RETVAL -ne 0 ] && MSG="checkmap failed [$RETVAL]"
fi

if [ $RETVAL -eq 0 ]; then
    /usr/sbin/usermod -g "$groupname" "$username"
    RETVAL=$?
    [ $RETVAL -ne 0 ] && MSG="usermod failed [$RETVAL]"
fi

echo `date`" Set '$groupname' as uses's '$username' primary group: $MSG" \
    >> /etc/samba/scripts/log
exit 0
И с помощью следующей директивы указываем Samba наш скрипт
set primary group script = /etc/samba/scripts/setprimarygroup.sh "%u" "%g"

Добавление пользователя в группу

Наверх

Основным действом в скрипте добавления пользователя в группу является процесс составления строки перечисления групп, в которые должна входить указанная учетная запись. После этого, посредством программы usermod выполняется сопоставление вхождения бюджета в определенные группы.

#!/bin/bash
# addusertogroup.sh
# v1.20
RETVAL=0
MSG="success"
username="$1"
groupname="$2"
test -z "$username" || test -z "$groupname" && exit 1

if [ $RETVAL -eq 0 ]; then
    /etc/samba/scripts/checkmap.pl
    RETVAL=$?
    [ $RETVAL -ne 0 ] && MSG="checkmap failed [$RETVAL]"
fi

groups=`cat /etc/group | grep "[,:]$username" | cut -d ':' -f 1 | tr '\n' ','`
groups="$groups$groupname"
if [ $RETVAL -eq 0 ]; then
    /usr/sbin/usermod -G "$groups" "$username"
    RETVAL=$?
    [ $RETVAL -ne 0 ] && MSG="usermod failed [$RETVAL]"
fi

echo `date`" Add '$username' user to '$groupname' group: $MSG" \
    >> /etc/samba/scripts/log
exit 0
Сложность в том, что на момент запуска программы указанная учетная запись может уже состоять в какой либо группе (помимо первичной). В этом случае, если мы просто выполним установку указанной группы, бюджет будет исключен из всех прочих групп, в которых он состоял до момента вызова программы. Естественно, что нас это не устраивает. Более приемлимым вариантом будет является последовательное определение групп, в которые входит указанный бюджет на момент запуска программы и последующая конкатенация строки, представляющей перечисление этих групп с именем новой группы, в которую нужно включить бюджет (т.е. с группой, имя которой определяется вторым аргументом командной строки, группа, в которую необходимо включить указанную учетную запись).

Не забываем добавить в конфиг Samba директиву, включающую наш скрипт в систему управления контроллером

add user to group script = /etc/samba/scripts/addusertogroup.sh "%u" "%g"

Удаление пользователя из группы

Наверх

В случае удаления пользователя из группы, ситуация прямо-противоположная процессу добавления в группу. Мепханизм аналогичен, за исключением того, что после определения строки групп, в которые входит указанная учетная запись, вместо конкатенации мы выполняем коррекцию этой строки на предмет удаления из нее группы, имя которой определяется вторым аргументом командной строки

#!/bin/bash
# deluserfrgroup.sh
# v1.20
RETVAL=0
MSG="success"
username="$1"
groupname="$2"
test -z "$username" || test -z "$groupname" && exit 1

if [ $RETVAL -eq 0 ]; then
    /etc/samba/scripts/checkmap.pl
    RETVAL=$?
    [ $RETVAL -ne 0 ] && MSG="checkmap failed [$RETVAL]"
fi

groups=`cat /etc/group | grep "[,:]$username" | cut -d ':' -f 1 | tr '\n' ','`
groups=`echo -n "$groups" | sed -e "s/$groupname,//g"`
groups=`echo -n "$groups" | sed -e 's/,$//'`
if [ $RETVAL -eq 0 ]; then
    /usr/sbin/usermod -G "$groups" "$username"
    RETVAL=$?
    [ $RETVAL -ne 0 ] && MSG="usermod failed [$RETVAL]"
fi

echo `date`" Del '$username' user from '$groupname' group: $MSG" \
    >> /etc/samba/scripts/log
exit 0

В секцию global конфигурации Samba дописываем следующее
delete user from group script = /etc/samba/scripts/deluserfrgroup.sh "%u" "%g"

Синхронизация времени

Наверх

В параграфе Цели и требования было выдвинуто требование, в соответствии с которым компьютеры-участники домена должны синхронизировать свое время с контроллером домена. Мы уже включили сервер времени директивой time server = yes. Теперь добейтесь корректной настройки времени на контроллере домена. Возможно придется указать в конфигурации значение time offset или просто откорректировать зону и системное время.

Для проверки воспользуйтесь командой net с любой рабочей станции. Вы должны увидеть корректное время.

C:\>net time
А заставить выполнять синхронизацию мы можем с помощью нашего logon-скрипта. Для нашего случая с исключительно Windows-клиентами это скрипт STARTUP.BAT, который мы уже создали. В данный момент он у нас пустует. Давайте добавим туда следующую команду
net time \\FRODO /SET /YES
Эта команда заставит каждую рабочую станцию синхронизировать время с сервером при каждом логоне. Не упустите из виду, что в вышеприведенном примере FRODO - это NetBIOS имя контроллера домера (сервера времени). Логично предположить, что в скрипте STARTUP.BAT это имя должно совпадать с именем, определенным директивой netbios name конфигурационного файла сервера Samba.

Советы и решения

Наверх

Пару слов об апгрейде. Если вы выполняете апгрейд, то не забывайте про файлы, которые лежат в каталоге "var/locks". Просто скопируйте эти файлы в "var/locks" новой Samba.

В некоторых случаях требуется протестировать как работает обозреватель сети.

#./nmblookup -B 192.168.1.255 -d 2 '*'
Естественно, броадкаст-адрес нужно указать тот, что соответствует вашей сети. Еще можно вместо '*' указать имя конкретной станции, например
#./nmblookup -B 192.168.1.255 'PROG-1'

Некоторые ссылки, которые могут помочь в решении проблем Samba:

Наверх

ред. 1.03 от 30.03.2006
ред. 1.02 от 18.05.2005


Правила использования | На главную Whirlwind © 2002 - 2010

ИЯндекс цитирования