Локальные сети персональных компьютеров. Работа с сервером 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);
}
}
|

