RCMD(3)

ИМЯ
rcmd, rresvport, iruserok, ruserok, rcmd_af, rresvport_af, iruserok_af, ruserok_af - процедуры возврата потока в удалённую команду

ОБЗОР
#include <netdb.h>   /* или <unistd.h> в некоторых системах */

int rcmd(char **ahost, unsigned short inport, const char *locuser,
         const char *remuser, const char *cmd, int *fd2p);

int rresvport(int *port);

int iruserok(uint32_t raddr, int superuser,
             const char *ruser, const char *luser);

int ruserok(const char *rhost, int superuser,
            const char *ruser, const char *luser);

int rcmd_af(char **ahost, unsigned short inport, const char *locuser,
            const char *remuser, const char *cmd, int *fd2p,
            sa_family_t af);

int rresvport_af(int *port, sa_family_t af);

int iruserok_af(const void *raddr, int superuser,
                const char *ruser, const char *luser, sa_family_t af);

int ruserok_af(const char *rhost, int superuser,
               const char *ruser, const char *luser, sa_family_t af);

Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

rcmd(), rcmd_af(), rresvport(), rresvport_af(), iruserok(), iruserok_af(), ruserok(), ruserok_af(): _BSD_SOURCE

ОПИСАНИЕ
Функция rcmd() применяется суперпользователем для исполнения команды на удалённой машине при помощи схемы аутентификации, основанной на зарезервированных номерах портов. Функция rresvport() возвращает дескриптор сокета с адресом в привилегированном пространстве портов. Функции iruserok() и ruserok() используются серверами для аутентификации клиентов, запрашивающих сервис rcmd(). Все четыре функции используются сервером rshd(8) (среди прочих).

  rcmd()

Функция rcmd() ищет узел *ahost, используя gethostbyname(3) и возвращает -1, если узел не существует. Иначе *ahost устанавливается равным стандартному имени узла, при этом создаётся соединение с сервером на хорошо известном порту Интернет inport.

Если соединение успешно установлено, то вызывающему возвращается сокет в домене Интернет типа SOCK_STREAM, который для удалённой команды считается stdin и stdout. Если fd2p не равно нулю, то устанавливается вспомогательный канал до управляющего процесса, а его дескриптор будет помещён в *fd2p. Управляющий процесс возвращает диагностический вывод из команды (устройства 2) в этот канал, а также принимает байты из этого канала, считая их номерами сигналов UNIX, для их пересылки группе процессов команды. Если fd2p равно 0, то stderr (устройство 2 удалённой команды) будет работать аналогично stdout и для отправки произвольных сигналов в удалённый процесс не будет создано никаких ходов, хотя вы сможете привлечь к себе внимание, используя внеполосную передачу данных.

Протокол подробно описан в rshd(8).

  rresvport()

Функция rresvport() используется для получения сокета с привязанным привилегированным портом. Этот сокет подходит для использования функцией rcmd() и некоторыми другими. Привилегированные порты Интернет — это порты с номерами от 0 до 1023. Только привилегированный процесс (CAP_NET_BIND_SERVICE) может привязаться к привилегированному порту. В реализации glibc эта функция ограничена в использовании портов номерами с 512 по 1023. Аргумент port является значением-результатом: передаваемое в вызов значение используется в качестве начальной точки кругового поиска в диапазоне портов; при (успешном) возврате, он содержит номер порта, к которому была осуществлена привязка.

  iruserok() и ruserok()

Параметрами функций iruserok() и ruserok() являются, соответственно, IP-адрес или имя удалённого узла, два имени пользователя и флаг, указывающий, является ли имя локального пользователя именем суперпользователя. Далее, если пользователь не является суперпользователем, они проверяют файл /etc/hosts.equiv. Если ничего не находится или завершается с ошибкой, то проверяется .rhosts в домашнем каталоге пользователя (для получения информации о том, разрешены ли запросы к службе).

Если этот файл не существует, не является обычным файлом, если его владельцем является не текущий пользователь или не суперпользователь, или если он доступен для записи кому-то помимо владельца, то проверка завершается с ошибкой. Если имя машины указано в файле hosts.equiv, или если узел и имя пользователя для удалённого доступа найдены в файле .rhosts, то возвращается 0; иначе iruserok() и ruserok() возвращают -1. Если имя локального домена (полученное вызовом gethostname(2)) совпадает с именем удалённого домена, то может указываться только имя машины.

Если IP-адрес удалённого узла известен, то должна использоваться iruserok() вместо ruserok(), так как при этом не требуется доверия к DNS-серверу для домена удалённого узла.

  Варианты *_af()
Все описанные ранее функции работают с сокетами IPv4 (AF_INET). Варианты «_af» имеют дополнительный аргумент, который позволяет указать адресное семейство сокета. Для этих функций значением аргумента af может быть AF_INET или AF_INET6. Также rcmd_af() поддерживает использование AF_UNSPEC.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Функция rcmd() при успешном выполнении возвращает корректный номер дескриптора сокета. При ошибках возвращается -1 и в стандартный поток ошибок выводится диагностическое сообщение.

Функция rresvport() при успешном выполнении возвращает корректный привязанный дескриптор сокета. При ошибках возвращается -1 и в глобальную переменную errno записывается код ошибки. Код ошибки EAGAIN означает «Все сетевые порты заняты». Информацию о результатах ruserok() и iruserok() смотрите выше.

ВЕРСИИ
Функции iruserok_af(), rcmd_af(), rresvport_af() и ruserok_af() появились в glibc начиная с версии 2.2.

СООТВЕТСТВИЕ СТАНДАРТАМ
Отсутствуют в POSIX.1-2001. Есть в BSD, Solaris и многих других системах. Данные функции впервые появились в 4.2BSD. Варианты «_af» были добавлены позднее и распространены не так широко.

ДЕФЕКТЫ
Функции iruserok() и iruserok_af() объявляются в заголовках glibc только начиная с версии 2.12.

СМОТРИТЕ ТАКЖЕ
rlogin(1), rsh(1), intro(2), rexec(3), rexecd(8), rlogind(8), rshd(8)