Локальные сети персональных компьютеров. Работа с сервером Novell NetWare© Александр Фролов, Григорий ФроловТом 9, М.: Диалог-МИФИ, 1993, 168 стр. 6.2. Просмотр базы объектовВ этом разделе мы рассмотрим задачу сканирования базы данных Bindery с целью получения списка имеющихся в ней объектов. Например, вам может потребоваться список активных серверов в сети, список пользователей или список рабочих групп. Для получения списка объектов, сведения о которых хранятся в базе данных Bindery, предназначена функция ScanBinderyObject(): int ScanBinderyObject(char *SearchObjectName, WORD SearchObjectType, long *ObjectID, char *ObjectName, WORD *ObjectType, char *ObjectHasProperties, char *ObjectFlag, char *ObjectSecurity); Эта функция должна использоваться в цикле. При первом вызове в переменную, на которую указывает параметр ObjectID, необходимо записать значение -1. В дальнейшем в эту переменную будет записываться идентификатор найденного объекта. Для поиска следует указать имя объекта (параметр SearchObjectName) и тип объекта (параметр SearchObjectType). В качестве имени объекта можно использовать шаблон с символами "*" и "?". Тип объекта может быть задан конкретно, либо можно указать значение -1. В последнем случае функция будет искать объекты всех типов. Для того чтобы найти все объекты всех типов, в качестве имени надо указать строку "*", в качестве типа задать значение -1. Для найденных объектов в соответствующие переменные, указанные параметрами функции, будут записаны имя объекта (параметр ObjectName), тип объекта (параметр ObjectType), флаг (параметр ObjectFlag), байт доступа (параметр ObjectSecurity). Кроме того, в переменную, на которую указывает параметр ObjectHasProperties, записывается значение 0xFF, если объект имеет дополнительную связанную с ним информацию (Properties), которую можно извлечь специально предназначенными для этого функциями. Функция возвращает 0 при успешном завершении или код ошибки:
Ваша программа должна вызывать функцию ScanBinderyObject() в цикле до тех пор, пока она не возвратит код ошибки, отличный от нуля. Вместо функции ScanBinderyObject() можно использовать функцию E3h прерывания INT 21h:
Буфер запроса имеет следующий формат: struct REQUEST { WORD PacketLength; // размер пакета запроса BYTE Function; // должно быть равно 55 BYTE ObjectID; // идентификатор объекта WORD SearchObjectType; // тип объекта BYTE NameLength; // длина имени образца для // поиска объекта BYTE SearchObjectName[NameLength]; // имя образца для // поиска объекта }; Буфер ответа имеет следующий формат: struct REPLAY { WORD PacketLength; // размер пакета long ObjectID; // идентификатор объекта WORD ObjectType; // тип объекта BYTE ObjectName[48]; // имя объекта BYTE ObjectFlag; // флаг объекта BYTE SecurityAccessLevel; // уровень доступа BYTE ObjectHasProperties; // есть записи }; В базе данных объектов Bindery с каждым объектом может быть связано несколько дополнительных записей, содержащих данные (property). Каждая такая запись имеет свое имя, флаг и байт доступа. Если объект имеет записи, вы можете получить список их имен и других атрибутов при помощи функции ScanProperty(): int ScanProperty(char *ObjectName, WORD ObjectType, char *SearchPropertyName, long *SequenceNumber, char *PropertyName, char *PropertyFlag, char char *PropertySecurity, char *PropertyHasValue, char *MoreProperties); Функция должна вызываться в цикле. При первом вызове переменная, на которую указывает параметр SequenceNumber, должна содержать значение -1. При последующих вызовах содержимое этой переменной будет изменяться автоматически. Для считывания полей функции необходимо указать имя сканируемого объекта (параметр ObjectName), тип объекта (параметр ObjectType), а также имя записи или шаблон имени записи (параметр SearchPropertyName). В шаблоне можно использовать символы "*" и "?". Для найденных записей в соответствующие переменные, указанные параметрами функции, будут записаны имя записи (параметр PropertyName), флаг записи (параметр PropertyFlag), байт доступа (параметр PropertySecurity), признак того, что запись имеет значения (параметр PropertyHasValue), признак того, что в объекте есть еще и другие записи (MoreProperties). Функция возвращает 0 при успешном завершении или код ошибки:
В Novell NetWare для каждого типа объекта существует определенный набор записей, которые могут быть связаны с этим объектом. Например, с объектом типа 1 (обычный пользователь) связаны такие записи, как PASSWORD (пароль) и SECURITY_EQUALS (эквивалентность прав доступа). Содержимое записей можно считать при помощи функции ReadPropertyValue(), которая описана в документации по библиотеке NetWare C Interface. Для этого пользователь, запустивший программу, должен обладать достаточным уровнем доступа. Приведем некоторые имена полей, определенных в NetWare:
Полный список полей и подробное их описание вы найдете в документации по библиотеке NetWare C Interface. 6.2.1. Программа BSCANПриведем исходный текст программы BSCAN (листинг 27), которая просматривает базу данных объектов. Для каждого найденного объекта программа выводит имя и расшифрованный тип объекта, флаг и уровень доступа. Если объект имеет дополнительные записи (properties), вызывается функция, которая выводит имена найденных записей. // =================================================== // Листинг 27. Программа для просмотра содержимого // базы данных объектов // Файл bscan\bscan.cpp // // (C) A. Frolov, 1993 // =================================================== #include <stdlib.h> #include <stdio.h> #include <string.h> #define WORD unsigned int #define BYTE unsigned char extern "C" int GetNetWareShellVersion(char *,char *, char *); extern "C" int ScanBinderyObject(char *, WORD, long *, char *, WORD *, char *, char *, char *); extern "C" int ScanProperty(char *, WORD, char *, long *, char *, char *, char *, char *, char *); void Property(char *ObjectName, WORD ObjectType); void main(void) { char MajorVersion=0; char MinorVersion=0; char Revision=0; int ccode; BYTE ObjectSecurity; long ObjectID; char SearchObjectName[48]; char ObjectName[48]; WORD SearchObjectType; WORD ObjectType; char ObjectHasProperties; char ObjectFlag; printf("\n*BSCAN* (C) Frolov A., 1993\n"); // Проверяем присутствие сетевой оболочки asm push si GetNetWareShellVersion(&MajorVersion, &MinorVersion, &Revision); asm pop si if(MajorVersion == 0) { printf("\nОболочка NetWare не загружена\n"); return; } // Просматриваем в цикле содержимое базы объектов, // ищем объекты всех типов SearchObjectType = -1; // Маска для поиска всех объектов strcpy(SearchObjectName, "*"); for(ObjectID = -1;;) { // Получаем очередной объект ccode = ScanBinderyObject(SearchObjectName, SearchObjectType, &ObjectID, ObjectName, &ObjectType, &ObjectHasProperties, &ObjectFlag, &ObjectSecurity); // Если больше нет объектов или произошла ошибка, завершаем цикл if(ccode) break; // Выводим имя и тип объекта printf("\n%-18s\t", ObjectName); switch(ObjectType) { case 0: printf("??? "); break; case 1: printf("Пользователь "); break; case 2: printf("Группа "); break; case 3: printf("Очередь на печать "); break; case 4: printf("Файл-сервер "); break; case 5: printf("Сервер заданий "); break; case 6: printf("Шлюз "); break; case 7: printf("Сервер печати "); break; case 8: printf("Очередь архивирования "); break; case 9: printf("Сервер для архивирования"); break; case 0xA: printf("Очередь заданий "); break; case 0xb: printf("Администратор "); break; case 0x26: printf("Сервер удаленного моста "); break; default: printf("Объект 0x%04.4X ", ObjectType); break; } // Выводим флаг объекта, который может иметь два значения: // 0 для постоянных объектов и 1 для временных if(ObjectFlag) printf("Временный "); else printf("Постоянный"); // Выводим байт прав, необходимых для получения доступа к объекту printf(" Доступ %02.2X", ObjectSecurity); // Если для объекта имеются дополнительные записи, // выводим их названия if(ObjectHasProperties) Property(ObjectName, ObjectType); } } // ================================================================= // Функция Property выводит названия дополнительных записей объектов // ================================================================= void Property(char *ObjectName, WORD ObjectType) { int ccode; BYTE PropertySecurity; long ObjectID; char SearchPropertyName[16]; char PropertyName[16]; WORD SearchObjectType; char PropertyFlag; long SequenceNumber; char PropertyHasValue; char MoreProperties; // Маска для поиска всех записей strcpy(SearchPropertyName, "*"); for(SequenceNumber=-1;;) { // Получаем запись ccode = ScanProperty(ObjectName, ObjectType, SearchPropertyName, &SequenceNumber, PropertyName, &PropertyFlag, &PropertySecurity, &PropertyHasValue, &MoreProperties); // Если записей больше нет, завершаем цикл if(ccode) break; // Выводим название записи printf("\n\tProperty %s", PropertyName); } } |