Локальные сети персональных компьютеров. Работа с сервером Novell NetWare© Александр Фролов, Григорий ФроловТом 4, М.: Диалог-МИФИ, 1993, 168 стр. 6.1. Объекты, коды объектов и права доступаБаза данных Bindery хранит объекты, которые имеют такие атрибуты, как идентификатор, имя, тип, флаг (статический или динамический объект), байт доступа. Идентификатор объекта - число размером 4 байта, которое является уникальным для данного файл-сервера. Никакие два объекта, сведения о которых хранятся в одной базе данных на одном сервере, не могут иметь одинаковые идентификаторы. Имя объекта представляет собой текстовую строку размером не более 47 байт. В операциях поиска объектов в базе данных по имени в поле имени допускается указывать символы "*" и "?", которые интерпретируются обычным способом, как и в MS-DOS. Библиотека NetWare C Interface имеет функции, позволяющие просматривать список всех объектов базы данных, искать объекты определенного типа или по имени с использованием шаблона и символов "*" и "?". По идентификатору объекта вы можете легко получить его имя и наоборот, по имени можно узнать идентификатор объекта. Тип объекта определяет сетевой ресурс и может принимать следующие значения:
Флаг объекта характеризует время жизни объекта. Если этот флаг равен нулю, объект статический и для его уничтожения необходимо вызывать специальную функцию. Если флаг равен единице, то это динамический объект, который удаляется автоматически, как только исчезает соответствующий сетевой ресурс. Например, если в сети имеется несколько файл-серверов, в базе каждого сервера имеются объекты, описывающие все активные серверы сети. Как только один из серверов прекращает свою работу, из всех баз данных, расположенных на остальных файл-серверах, удаляются объекты, описывающие завершивший работу файл-сервер. Байт доступа используется для определения прав, необходимых для поиска, чтения, создания, редактирования или удаления объекта. Две тетрады байта отвечают за доступ на чтение и доступ на запись. Младшие четыре бита байта доступа отвечают за чтение, старшие - за запись. Для тетрад определены значения от 0 до 4 - уровни доступа. Для того чтобы пользователь или другой объект получили доступ, тетрады его собственного байта доступа должны иметь значения, равные или превышающие значения в байте доступа объекта, к которому запрашивается доступ. Приведем список возможных значений для уровней доступа:
Для определения собственного уровня доступа и идентификатора пользователя программа может воспользоваться функцией GetBinderyAccessLevel():
int GetBinderyAccessLevel(BYTE *SecurityAccessLevel,
long *ObjectID);
Первый параметр этой функции указывает на слово, в которое будет записан уровень доступа, второй - на двойное слово, в которое будет записан идентификатор пользователя. Вместо функции GetBinderyAccessLevel() можно использовать функцию E3h прерывания INT 21h:
Буфер запроса имеет следующий формат:
struct REQUEST {
WORD PacketLength; // размер пакета запроса
BYTE Function; // должно быть равно 70
};
Буфер ответа имеет следующий формат:
struct REPLAY {
WORD PacketLength; // размер пакета
BYTE SecurityAccessLevel; // уровень доступа
long ObjectID; // идентификатор объекта
};
По идентификатору объекта вы можете получить его имя и тип с помощью функции GetBinderyObjectName():
int GetBinderyObjectName(long ObjectID,
char *ObjectName, WORD *ObjectType);
Для объекта, идентификатор которого задан первым параметром, функция возвращает имя объекта и его тип, записывая их в области памяти, указанные при помощи второго и третьего параметров. Функция возвращает 0 при успешном завершении или код ошибки:
Вместо функции GetBinderyObjectName() вы также можете использовать функцию E3h прерывания INT 21h. При этом необходимо использовать форматы буфера запроса и буфера ответа, приведенные ниже. Буфер запроса:
struct REQUEST {
WORD PacketLength; // размер пакета запроса
BYTE Function; // должно быть равно 54
long ObjectID; // идентификатор объекта
};
Буфер ответа:
struct REPLAY {
WORD PacketLength; // размер пакета
long ObjectID; // идентификатор объекта
WORD ObjectType; // тип объекта
BYTE ObjectName[48]; // имя объекта
};
Для получения идентификатора объекта по его имени и типу вы можете воспользоваться функцией GetBinderyObjectID():
int GetBinderyObjectID(char *ObjectName,WORD ObjectType,
long *ObjectID);
Имя и тип объекта задаются первым и вторым параметрами, идентификатор записывается по адресу, заданному третьим параметром. Функция возвращает 0 при успешном завершении или код ошибки:
Вместо функции GetBinderyObjectID() можно использовать функцию E3h прерывания INT 21h. Приведем форматы буфера запроса и буфера ответа. Буфер запроса:
struct REQUEST {
WORD PacketLength; // размер пакета запроса
BYTE Function; // должно быть равно 53
long ObjectType; // тип объекта
BYTE ObjectNameLength; // длина имени объекта
BYTE ObjectName[ObjectNameLength]; // имя объекта
};
Буфер ответа:
struct REPLAY {
WORD PacketLength; // размер пакета
long ObjectID; // идентификатор объекта
WORD ObjectType; // тип объекта
BYTE ObjectName[48]; // имя объекта
};
6.1.1. Программа BACCESSПриведем текст программы BACCESS (листинг 26), которая определяет и выводит на экран имя, идентификатор, тип объекта, а также его уровень доступа. В программе используются описанные выше функции.
// ===================================================
// Листинг 26. Программа для просмотра уровня
// доступа рабочей станции
// Файл baccess\baccess.cpp
//
// (C) A. Frolov, 1993
// ===================================================
#include <stdlib.h>
#include <stdio.h>
#define WORD unsigned int
#define BYTE unsigned char
extern "C" int GetNetWareShellVersion(char *,char *, char *);
extern "C" int GetBinderyAccessLevel(BYTE *, long *);
extern "C" int GetBinderyObjectName(long, char*, WORD*);
void main(void) {
char MajorVersion=0;
char MinorVersion=0;
char Revision=0;
int ccode;
BYTE SecurityAccessLevel;
long ObjectID;
char ObjectName[48];
WORD ObjectType;
printf("\n*BACCESS* (C) Frolov A., 1993\n");
// Проверяем присутствие сетевой оболочки
asm push si
GetNetWareShellVersion(&MajorVersion,
&MinorVersion, &Revision);
asm pop si
if(MajorVersion == 0) {
printf("\nОболочка NetWare не загружена\n");
return;
}
// Получаем свой идентификатор и уровень доступа
GetBinderyAccessLevel(&SecurityAccessLevel, &ObjectID);
// По идентификатору определяем свое имя
ccode = GetBinderyObjectName(ObjectID, ObjectName, &ObjectType);
// Если пользователь подключился к файл-серверу,
// выводим его имя, идентификатор и тип
if(!ccode) {
printf("Пользователь %s, ID = %lX, Type = %d\n",
ObjectName, ObjectID, ObjectType);
}
// Выводим права доступа на чтение
printf("Права доступа на чтение:\t");
switch(SecurityAccessLevel & 0x0f) {
case 0:
printf("Anyone\t(не подключен к файл-серверу)\n");
break;
case 1:
printf("Logged\t(подключен к файл-серверу)\n");
break;
case 2:
printf("Object\t(подключен к файл-серверу "
"с именем и паролем)\n");
break;
case 3:
printf("Supervisor\t(права супервизора)\n");
break;
case 4:
printf("NetWare\t(права Novell NetWare)\n");
break;
}
// Выводим права доступа на запись
printf("Права доступа на запись:\t");
switch((SecurityAccessLevel >> 4) & 0x0f) {
case 0:
printf("Anyone\t(не подключен к файл-серверу)\n");
break;
case 1:
printf("Logged\t(подключен к файл-серверу)\n");
break;
case 2:
printf("Object\t(подключен к файл-серверу "
"с именем и паролем)\n");
break;
case 3:
printf("Supervisor\t(права супервизора)\n");
break;
case 4:
printf("NetWare\t(права Novell NetWare)\n");
break;
}
}
|

