Следующие примеры показывают интерфейс командной строки, позволяющий серверу предлагать дисковый ресурс, а клиенту соединяться и использовать этот ресурс.
a) NET SHARE
Команда NET SHARE при выполнении на сервере определяет имя каталога, который будет сделан доступным для клиентов в сети. Должно быть задано общее имя, которое предоставляется клиентам, желающим получить доступ к каталогу.
Примеры:
NET SHARE docs=c:\dirl\
Делает общедоступными все файлы в каталоге C:\DIR1 и его подкаталогах с общим именем docs в качестве имени, используемого для соединения с этим ресурсом.
b) NET USE
Клиенты могут получить доступ к одному или нескольким предлагаемым каталогам с помощью команды NET USE. Когда посылается команда NET USE, пользователь может свободно получить доступ к файлам без дополнительных специальных требований.
Примеры:
NET USE: d: \\SERVERl\DOCS отображает диск d: в общедоступный каталог DOCS на сервере Serverl. Пользователь может теперь обращаться к файлам на SERVER1 C:\DIR1, используя d:. Например, dir d: *.* выдаст список всех файлов на SERVER1 c:\dirl.
NET USE * \\SERVERl\DOCS mycoolpwd отображает следующий доступный диск, который использует DOCS на server 1, защищенный паролем mycoolpwd.
Для серверов уровня пользователя клиент обычно не должен предоставлять пароль с помощью команды NET USE. Если пользователю предлагается ввести пароль, обычно это указывает на сетевую проблему (например, он не может контактировать с контроллером домена, чтобы проверить полномочия). Этот сценарий предоставляет хорошую возможность проверить инструменты сетевого мониторинга (см. часть IV). Сейчас можно попробовать проверить, существует ли проблема безопасности:
NET USE * \\SERVERl\DOCS/USER:domainname\username password
Клиентское программное обеспечение должно помнить идентификатор диска, поставляемый вместе с запросом NET USE, и связать его со значением идентификатора дерева (TID), возвращаемого сервером в заголовке SMB. Последующие запросы, использующие этот TID, должны включать только имя пути доступа относительно присоединенного поддерева, так как сервер интерпретирует поддерево как корневой каталог (виртуальный корень). Когда пользователь ссылается на один из удаленных дисков, клиентское программное обеспечение просматривает свой список дисков для этого узла и включает идентификатор дерева, связываемый с этим диском в поле TID каждого запроса.
Отметим, что когда каталог объявляется общедоступным, будут затронуты все файлы, лежащие под этим каталогом. Если определенный файл находится внутри области нескольких общих ресурсов, то соединение с любой из областей общих ресурсов получает доступ к файлу с полномочиями, определенными для предложения, поименованного в NET USE. Сервер не будет проверять вложенные каталоги с более ограничительными полномочиями.
Сервер CIFS хранит зашифрованную форму пароля клиента. Чтобы получить аутентифицированный доступ к серверным ресурсам, сервер посылает вызов клиенту, на который клиент отвечает подтверждением, что он знает пароль клиента.
Аутентификация использует шифрование DES в блочном режиме. Функция шифрования DES, обозначенная как Е(К, D), получает семибайтный ключ (К) и восьмибайтный блок данных (D) и создает восьмибайтный зашифрованный блок данных в качестве своего значения. Если данные для шифрования длиннее восьми байтов, функция шифрования применяется к каждому блоку из восьми последующих байтов и результаты соединяются вместе. Если ключ длиннее семи байтов, то данные сначала полностью шифруются с помощью первых семи байтов ключа, затем следующие семь байтов и т.д., соединяя каждый раз результаты. Другими словами, чтобы зашифровать 16-байтовую величину D0D1 с помощью 14-байтового ключа К0К1:
Е(К0К1, D0D1) = Е(К0, D0)E(K0,D1)E(K1, D0)E(K1, Dl)
Поле EnayptionKey (Ключ Шифрования) в ответе SMB_COM_NEGPROT содержит восьмибайтный вызов, обозначенный ниже как "С8", выбираемый уникальным, чтобы предотвратить атаки повторного воспроизведения. Клиент отвечает 24-байтовым ответом, обозначенным "Р24" и вычисляемым, как описано ниже. (Примечание. Имя "EneryptionKef является историческим — оно на самом деле не содержит ключа шифрования.)
Клиент посылает ответ на вызов в запросе SMB_COM_TREE_CONNECT, SMB_COM_TREE_CONNECT_ANDX и/или SMB_COM_SESSION_SETUP_ANDX, который следует за обменом сообщением SMB_COM_NEGPROT. Сервер должен проверить ответ, выполняя те же вычисления, которые делает клиент при его создании, и проверить, что строки совпадают.
Если строки не совпадают, то, возможно, клиентская система неспособна шифровать; если это так, то строка может быть паролем пользователя открытым текстом. Сервер должен попробовать проверить строку, как если бы это был незашифрованный пароль.
Поле SMB, используемое для хранения ответа, зависит от ответа:
Password в SMB_COM_TREE_CONNECT
Password в SMB_COM_TREE_CONNECT_ANDX-
Account Password в SMB_COM_SESSION_SETUP_ANDX
(Примечание. Здесь имена также являются историческими и не отражают это использование.)
Содержимое ответа на вызов зависит от диалекта CIFS, как показано в следующих разделах.
Диалекты протокола NT LM 0.12 и более поздние версии поддерживают операции распределенной файловой системы (DFS — Distributed File System). DFS предоставляет для этого протокола способ использования единственной согласованной схемы именования файлов, которая может охватывать совокупность различных серверов и ресурсов общего доступа. Модель DFS использует модель на основе направлений. Этот протокол определяет способ, которым клиенты получают направления.
Клиент может установить в заголовке запроса SMB флаг, указывающий, что клиент хочет, чтобы сервер разрешил в DFS пути доступа SMB, которые известны серверу. Сервер пытается разрешить запрошенное имя в файл, содержащийся внутри локального дерева каталогов, указанного TID запроса, и затем нормально продолжить. Если путь доступа запроса разрешается в файл на другой системе, то сервер возвращает следующую ошибку.
STATUS_DFS_PATH_NOT_COVERED - сервер не поддерживает часть пространства DFS, требуемую для разрешения пути доступа в запросе. Клиент должен запросить на этом сервере направление для дополнительной информации.
Клиент запрашивает направление с помощью запроса TRANS2-DFS-GETREFERRAL, содержащего интересующий путь доступа DFS. Ответ с сервера указывает, как клиент должен продолжить.
Метод, с помощью которого топологическое представление DFS хранится и поддерживается серверами, не определен этим протоколом.
Заголовок SMB
Хотя каждая команда SMB имеет определенное кодирование, в заголовке SMB есть несколько полей, которые имеют значение для всех SMB. Как можно увидеть в распечатке ниже, протокол SMB выполняется поверх NetBIOS, который переносится поверх TCP, реализованный поверх IP, который реализован поверх метода доступ к среде Ethernet. Эти поля описаны в последующих разделах.
Идентификатор процесса (РШ) уникальным образом определяет процесс клиента. Клиенты информируют серверы о создании нового процесса, просто вводя новое значение РШ в диалог о новых процессах.
В базовом протоколе использовалось сообщение SMB SMB_COM_ PROCESS_EXIT для указания катастрофического завершения процесса на клиенте. В однозадачной системе DOS было возможно возникновение тяжелых ошибок, вызываемых разрушением процесса, с остающимися открытыми файлами. Поэтому в таком случае посылается сообщение SMB SMB_COM_PROCESS_EXIT, чтобы позволить серверу закрыть все файлы, открытые этим процессом.
В LANMAN 1.0 и более новых диалектах не посылается никаких сообщений SMB SMB_COM_PROCESS_EXIT. Операционная система клиента должна гарантировать, что будет послано соответствующее сообщение SMB закрытия и очистки, когда последний процесс, обращающийся к файлу, его закроет. С точки зрения сервера не существует понятия идентификатора файла (FID), принадлежащего процессу. FID, возвращаемый сервером одному процессу, может использоваться любым другим процессом, использующим то же транспортное соединение и TID. Не существует SMB создания процесса, посылаемого серверу; клиент должен гарантировать, что только допустимые клиентские процессы получают доступ к FID (и TID). При получении SMB_COM_TREE_DISCONNECT (или когда сеанс сервера и клиента прекращается) сервер будет делать недействительными все файлы, открытые процессом на этом клиенте.
Поле MID
Клиенты, использующие LANMAN 1.0 и более новые диалекты, обычно являются мультизадачными и допускают несколько асинхронных запросов ввода/вывода на задачу. Поэтому вместе с PID используется мультиплексный идентификатор (MID), чтобы разрешить мультиплексирование одного соединения клиента и сервера среди нескольких клиентских процессов, потоков управления и запросов потоков управления.
Несмотря на согласованный диалект, сервер отвечает за обеспечение того, что каждый ответ содержит те же самые значения MID и PID, которые они запрашивают. Клиент может затем использовать значения MID и PID для связывания запросов и ответов и иметь в любое время согласованное количество ожидающих запросов для определенного сервера.
LANMAN 1. 0 и более поздние диалекты протокола CIFS допускают передачу на сервер нескольких запросов SMB в одном сообщении. Сообщения этого типа называются AndX SMB, они подчиняются следующим правилам:
• Вложенные команды не повторяют информацию заголовка SMB. Вместо этого следующее сообщение SMB начинается на поле WordCount.
• Все множественные (сцепленные) запросы должны соответствовать согласованному размеру передачи. Например, если было послано сообщение SMB_COM_TREE_CONNECT_ANDX, включающее SMB_COM_OPEN_ANDX, которое включает SMB_COM_WRITE, то все они должны соответствовать согласованному размеру буфера. Это будет ограничивать размер записи.
• Существует одно посылаемое сообщение, содержащее сцепленные запросы, и одно сообщение ответа на сцепленные запросы. Сервер может НЕ посылать отдельные ответы на каждый из сцепленных запросов.
• Все сцепленные ответы должны соответствовать согласованному размеру передачи. Это ограничивает, например, максимальное значение вложенного SMB_COM_READ. Клиент не должен запрашивать больше байтов, чем может поместиться во множественном ответе.
• Сервер неявно будет использовать результат первой команды в команде "X". Например, TID, полученный через SMB_COM_TREE_ CONNECT_ANDX, мог бы использоваться во вложенном SMB_COM_ OPEN.ANDX, a FID, полученный в SMB_COM_OPEN_ANDX, мог бы использоваться во вложенном SMB_COM_READ.
• Каждый сцепленный запрос может ссылаться только на тот же FID и TID, что и другие команды в комбинированном запросе. Сцепленные запросы могут рассматриваться как выполняющие одну (из нескольких частей) операцию на одном ресурсе.
• Первая КОМАНДА, встретившая ошибку, будет останавливать всю дальнейшую обработку встроенных команд. Сервер не будет возвращать команды, которые выполнились успешно. Поэтому, если сцепленный запрос содержал SMB_COM_OPEN_ANDX и SMB_COM_READ, и сервер смог успешно открыть файл, но чтение встретило ошибку, то после этого файл остался бы открытым. Это в точности то же самое, как если бы запросы были посланы раздельно.
Если при обработке сцепленных запросов возникает ошибка, то последним (из сцепленных запросов в буфере) будет запрос, встретивший ошибку. Другие необработанные сцепленные запросы будет проигнорированы, когда сервер встретит ошибку, и не будут представлены в сцепленном ответе. В действительности последняя допустимая команда ANDXCOMMAND (если существует) будет представлять SMB, на котором встретилась ошибка. Если нет действительной команды ANDXCOMMAND, то возникшая при первом запросе/ответе ошибка и COMMAND содержат отказавшую команду. Во всех случаях информация об ошибке возвращается в заголовке SMB в начале буфера ответа.
Каждый сцепленный запрос и ответ содержит смещение (с начала заголовка SMB) к следующему сцепленному запросу/ответу (в поле AndXOffset в различных протоколах "and X", например, SMB_COM_OPEN_ANDX). Это позволяет создавать запросы распакованными. Между концом предыдущего запроса (как определено WordCount и ByteCount) и началом следующего сцепленного запроса может быть пробел. Это упрощает создание сцепленных запросов протокола. Отметим, что так как клиент должен знать размер возвращаемых данных, чтобы послать правильное число получений (например, SMB_COM_TRANSACTION, SMB_COM_READ_MPX), данные в каждом ответе SMP ожидаются обрезанными до максимального числа 512-байтных блоков (секторов), которые будут соответствовать (начиная с 32-битной границы) согласованному размеру буфера с нечетным числом байтов, остающихся (если остаются) в конечном буфере.
