Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

LINTER от 04.02.15

.pdf
Скачиваний:
44
Добавлен:
21.05.2015
Размер:
2.16 Mб
Скачать

Практическое занятие 8

 

Пример создания защищенной базы данных

51

select * from doc_info_read;

Получаем только одну запись – о только что добавленном документе. Запись о первом документе пользователь SEC2 не видит, т.к. не имеет к ней отношения.

13.Начальник Отдела 1 назначает в качестве исполнителя документа своего подчиненного U11. Входим под именем BOSS1 и подаем запрос

update doc_info_write##"НЕСЕКРЕТНО"#"НЕСЕКРЕТНО"# set R_OPERATOR##"НЕСЕКРЕТНО"#"НЕСЕКРЕТНО"#='U11' where doc_id=2;

14.Начальник Отдела 1 передает свою функцию контроля документа своему подчиненному U12. Подаем запрос

update doc_info_write##"НЕСЕКРЕТНО"#"НЕСЕКРЕТНО"# set R_REVIEWER##"НЕСЕКРЕТНО"#"НЕСЕКРЕТНО"#='U12' where doc_id=2;

Проверяем результаты:

select * from doc_info_read;

Видим, что значение поля R_REVIEWER поменялось на U12. Заметим, что BOSS1 продолжает видеть информацию о документе, т.к. является начальником отдела, к которому приписан документ.

Однако если подать запрос

select * from doc_info_write;

пользователь BOSS1 не увидит ни одной строки: он уже не является ни ответственным, ни контролером документа, поэтому не может модифицировать информацию о нем.

15.Пользователь U11 добавляет содержимое документа, имеющее гриф «ДСП». Входим под именем U11. Для добавления содержимого документа подаем запрос:

insert into doc_ins##"ДСП"#"ДСП" (r_doc##"ДСП"#"ДСП", comment##"ДСП"#"ДСП") values (2, 'Приказ 1');

Теперь можно проконтролировать добавленную запись, подав запрос

select * from doc_read;

Видим добавленную запись.

16.Пользователь U11 добавляет обновление содержимого документа, причем на этот раз оно имеет гриф «СОВ.СЕКРЕТНО». Подаем запрос:

insert into doc_ins##"СОВ.СЕКРЕТНО"# (r_doc##"СОВ.СЕКРЕТНО"#, comment##"СОВ.СЕКРЕТНО"#) values (2, 'Приказ 1 – секретная часть');

Проконтролируем добавленную запись, получив также информацию об уровне чтения записей:

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

Практическое занятие 8

 

52

Пример создания защищенной базы данных

 

 

 

select doc_read.*, security(*,’R’) from doc_read;

Видим обе записи, т.к. пользователь U11 имеет право чтения информации с грифом «СОВ.СЕКРЕТНО». Последняя колонка показывает, что вторая строка действительно добавлена с RAL равным 4 (что и соответствует «СОВ.СЕКРЕТНО»).

17.Пользователь U12 (контролер документа) смотрит содержимое документа 2. Входим под пользователем U12. Подаем запрос

select * from doc_read;

Видим только первую запись, т.к. у пользователя U12 нет прав на чтение сов. секретной информации.

8.2. Проверка выполнения ПРД по модели нарушителя

Проверим, как в нашей БД реализуются необходимые ПРД.

1. Секретарь пытается получить содержимое секретного документа.

Теоретически это можно попытаться сделать одним из запросов:

select * from docum.doc_content; select * from doc_read;

select * from doc_read where r_doc = 1;

Первый запрос отвергается по нарушению доступа. Остальные два не возвращают данных, т.к. секретарю не назначен ни один документ.

Допустим теперь, что начальник Отдела 2 (BOSS2) назначил секретаря SEC1 в качестве ответственного за Документ 1.

Для этого войдем под пользователем BOSS2, и подадим запрос

update doc_info_write##"НЕСЕКРЕТНО"#"НЕСЕКРЕТНО"# set R_OPERATOR##"НЕСЕКРЕТНО"#"НЕСЕКРЕТНО"#='SEC1' where doc_id=1;

Теперь по дискреционному принципу пользователь SEC1 должен увидеть содержимое документа. Но содержимое документа имеет уровень чтения «ДСП», а пользователь SEC1 может читать только информацию с грифом «НЕСЕКРЕТНО».

Снова войдем под пользователем SEC1 и подадим один из перечисленных выше select-запросов из doc_read. Пользователь не видит данных.

Проверим, что если бы SEC1 имел доступ хотя бы к информации грифа «ДСП», он бы увидел содержимое документа. Для этого войдем под АБ и подадим запрос

alter user SEC1 level("ДСП","НЕСЕКРЕТНО");

Теперь снова войдем под SEC1 и подадим SELECT из doc_read. Пользователь увидел данные.

2. Секретарь пытается явно назначить ответственного за документ (минуя отдел).

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

Практическое занятие 8

 

Пример создания защищенной базы данных

53

Речь идет о добавлении нового документа. Войдем под пользователем SEC1 и попытаемся подать запрос

insert into doc_info_ins(doc_id, name, r_division, r_reviewer) values(10, 'Документ 10', 2, ‘SEC2’);

Т.е. мы попытались явно задать в качестве ответственного SEC2. Запрос прошел удачно, но смотрим что получилось:

select * from doc_info_read;

Поле R_REVIEWER в добавленной записи установлено в ‘BOSS1’ вместо ‘SEC2’ – это обеспечил триггер.

3. Работник пытается получить информацию или содержимое не назначенного ему документа.

Войдем под пользователем U11. Ему был назначен документ с идентификатором 2. Для получения информации или содержимого документа с идентификатором 1 можно было бы попытаться использовать один из запросов

select * from doc_info_read;

select * from doc_info_read where doc_id = 1; select * from doc_read;

select * from doc_read where r_doc = 1;

Ни один из этих запросов не вернет записей о документе с идентификатором 1. Доступ же к таблицам напрямую (не через представления) вообще закрыт.

4. Секретный документ случайно назначен сотруднику, который не имеет доступа к секретным сведениям

Это требование уже два раза проверялось Один раз, когда при проверке жизненного цикла документа 2 мы вставили данные о документе с грифом «СОВ.СЕКРЕТНО», и контролер документа эту запись не увидел. Второй раз, когда мы проверяли первое ПРД.

5. Работник, имеющий доступ к секретному документу, пытается открыть эту информацию (понизить уровень секретности)

В нашем примере пользователь U11 не может понизить уровень чтения известной ему информации ниже «ДСП».

Первое действие могло бы быть связано с попыткой внести в таблицу содержимого документов что-нибудь с RAL ниже «ДСП»

insert into doc_ins##"НЕСЕКРЕТНО"#(r_doc##"НЕСЕКРЕТНО"#) values(2);

Результатом является ошибка 1070 – нарушение мандатного доступа. Заметим, что WAL самой таблицы DOC_CONTENT не позволяет вносить в нее записи с RAL ниже «ДСП».

Тогда представим, что пользователь U11 получает категорию DBA (дайте ему соответствующие права при помощи АБ). Попытаемся теперь создать от имени U11 несекретную таблицу:

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

Практическое занятие 8

 

54

Пример создания защищенной базы данных

 

 

 

create table notsec(c char(100) level(“НЕСЕКРЕТНО”,”НЕСЕКРЕТНО”)) level(“НЕСЕКРЕТНО”,”НЕСЕКРЕТНО”);

По-прежнему получаем ошибку доступа: WAL пользователя опять не позволяет создать такую таблицу.

Теперь представим, что в БД есть доступная U11 на запись несекретная таблица.

Можно создать ее в INL:

username SYSTEM/MANAGER

create table notsec (c char(100) level(“НЕСЕКРЕТНО”,”НЕСЕКРЕТНО”)) level(“НЕСЕКРЕТНО”,”НЕСЕКРЕТНО”);

grant all on notsec to public;

Пусть теперь U11 пытается вставить в эту таблицу данные с уровнем, ниже «ДСП»

insert into system.notsec##”НЕСЕКРЕТНО”# values(‘тест’);

Опять получаем ошибку нарушения мандатного доступа. Хотя следующий запрос проходит нормально:

insert into system.notsec##”ДСП”# values(‘тест’);

Что касается попытки раскрытия секретных данных при выгрузке информации из БД, эта проблема должна решаться на стыке со средствами защиты ОС, как говорилось в лекции.

6. Работник, не являющийся секретарем, пытается добавить новый документ

Попробуем добавить информацию о документе от имени пользователя BOSS1:

insert into doc_info_ins(doc_id, name, r_division) values(20, 'Документ 20', 2);

Получаем нарушение привилегий (1022), т.к. только пользователи роли SECRETARY имеют право вставлять записи в эту таблицу.

7. Работник, не связанный с документом, пытается добавить его содержимое

Попробуем добавить запись о содержимом документа с идентификатором 1 из-под пользователя U11:

insert into doc_ins##"ДСП"#"ДСП" (r_doc##"ДСП"#"ДСП", comment##"ДСП"#"ДСП") values (1, 'Мои данные');

Ошибок не выдается, но мы получаем сообщение о том, что добавлено ноль строк (можно это и проверить при помощи SELECT). Это ПРД реализовано при помощи триггера.

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

Практическое занятие 8

 

Пример создания защищенной базы данных

55

8. Работник пытается удалить данные о документе или его содержимом

Запросы DELETE просто запрещены по дискреционному принципу. Любой запрос на

DELETE из таблиц DOCUM.DOC_REG или DOCUM.DOC_CONTENT возвращает 1022.

9.Администратор безопасности (приложения) пытается получить информацию

одокументах

Войдем под пользователем DOCUM и попытаемся подать запросы

select * from doc_reg;

select * from doc_content;

DOCUM не видит ни одной записи, т.к. они были сделаны пользователями другой группы. Сменить себе группу (оказать доверие) DOCUM не может, т.к. не является АБ.

АБ вообще не имеет доступа к таблицам документооборота, т.к. DOCUM не назначил ему никаких прав на них.

10. Администратор безопасности (приложения) пытается модифицировать информацию о документах

Войдем под пользователем DOCUM и попытаемся подать запросы

delete from doc_reg;

delete from doc_content;

В первом случае ошибка не выдается, но ничего не удаляется, т.к. записи, сделанные пользователями другой группы, пользователю DOCUM не видны. Во втором случае выдается нарушение мандатного доступа, т.к. метки доступа DOCUM не позволяют даже в принципе модифицировать таблицу DOC_CONTENT.

Аналогично можно проверить попытки с операторами UPDATE.

АБ вообще не имеет доступа к таблицам документооборота, т.к. DOCUM не назначил ему никаких прав на них.

Таким образом, все ПРД оказались выполненными.

8.3. Протоколирование (аудит)

Протоколирование изменений данных о документах было включено с самого начала. Можно зайти под АБ (SYSTEM) и подать запрос

select * from audit_events;

 

В результате будут видны все записи о сделанных модификациях, включая время,

автора

модификации,

тип

события

и

т.д.

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

56

Практическое занятие 9 Знакомство с CALL-интерфейсом

Практика 2 часа (Лекции 7,8)

На данном занятии мы освоим основы использования CALL-интерфейса СУБД ЛИНТЕР, на примере открытия соединения, выполнения SELECT-запросов, обработки ответов и закрытия соединения. На этом примере мы получим общие навыки подключения CALL-интерфейса и использования функции inter.

9.1. Сборка программы с CALL-интерфейсом

Для сборки программы с CALL-интерфейсом необходимо:

 

определить символ

_VER_MAX=<версия ЛИНТЕР>

где <версия ЛИНТЕР> - это число, полученное <как первый номер версии>*100 + <второй номер версии>*10; например, для 5.7 это будет 570, а для 5.9 – 590;

 

прописать пути для директивы #include в директорию intlib дистрибутива

 

ЛИНТЕР;

 

 

 

 

 

 

для

Windows

надо определить еще

символ

препроцессора

 

INTER_MSWINDOWS;

 

 

 

 

 

включить в сборку библиотеку intlib:

 

 

 

 

в среде Windows это может быть статическая библиотека inter325.lib,

 

расположенная в одной из поддиректорий директории intlib (в зависимости от

 

компилятора), либо динамически подключаемая библиотека inter325.dll,

 

соответствующая библиотека импорта inter325.lib находится в директории

 

intlib/lib;

 

 

 

 

 

 

в среде Unix просто используется объектный файл intlib.o,

 

расположенный в поддиректории intlib дистрибутива;

 

 

 

либо

вместо

подключения

библиотеки

можно

подключить

непосредственно исходный текст CALL-интерфейса intlib/intlib.c.

В среде Windows в дистрибутиве ЛИНТЕР имеется файл Definition, который конфигурируется при установке системы. Он включает все необходимые определения, и может быть просто включен в make-файл.

Примеры использования CALL-интерфейса и соответствующие make-файлы имеются в директориях samples/call и samples/c дистрибутива ЛИНТЕР.

Задание: Собрать примеры простейшего использования CALL-интерфейса, поставляемые вместе с ЛИНТЕР.

Указания:

Перейдите в поддиректорию samples/c дистрибутива ЛИНТЕР.

Изучите исходный текст примера step/step.c. Он содержит вызовы команд CALLинтерфейса “OPEN”, “SLCT”, “GETN” и “CLOSE”, печатая простую выборку, сделанную оператором SELECT.

Изучите содержимое make-файла (он содержит команды для сборки всех примеров, расположенных в поддиректории samples/c).

Соберите примеры:

 

 

 

 

для Unix, подайте команду make;

 

 

 

для Windows,

подайте команду nmake /f makefile.vc

(предполагается

 

использование

Microsoft

Visual

C++).

 

 

 

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

Практическое занятие 9. Знакомство с CALL-интерфейсом

57

 

 

 

Убедитесь в том, что запущена СУБД ЛИНТЕР на демонстрационной БД, содержащей таблицу PERSON.

Запустите исполняемый файл примера step и просмотрите результаты.

9.2. Разработка собственного примера

Задание: Используя демонстрационный пример из состава СУБД ЛИНТЕР, необходимо разработать и отладить собственную программу, использующую CALLинтерфейс для выборки данных.

Все задачи связаны с таблицами PERSON, AUTO или FINANCE демонстрационной БД ЛИНТЕР.

Задача 1. Разработать программу, которая запрашивает начальные буквы имени человека (поле PERSON.NAME), и выводит данные обо всех людях, имя которых начинается с этих букв и о марке (MAKE), модели (MODEL) и серийном номере (SERIALNO) автомобилей (таблица AUTO), принадлежащих каждому человеку (таблицы PERSON и AUTO связаны по полю PERSONID). При этом данные о человеке должны выводиться одной строкой, затем несколько строк о его автомобилях, затем данные о следующем человеке и т.д.

Задача 2. Разработать программу, которая запрашивает начальные буквы марки автомобиля (AUTO.MAKE) и выполняет запрос на выборку данных, соответствующих этим маркам, после чего печатает количество ответов и запрашивает номер строки, которую надо отобразить. После ввода номера строки, программа должна отобразить данные этой строки, и снова запросить новый номер (до тех пор, пока пользователь не введет недопустимое значение номера).

Задача 3. Разработать программу, которая запрашивает название кредитной карты (первые несколько букв поля CRDITCRD таблицы FINANCE) и выводит имена всех людей (PERSON.NAME), владеющих картой данного типа (таблицы PERSON и FINANCE связаны по полю PERSONID). При этом программа должна запрашивать порядок сортировки имен при печати: по возрастанию или по убыванию. Напечатав список имен, программа снова должна запросить порядок вывода имен, после чего выводит их (возможно, уже в другом порядке) и так далее, пока пользователь не введет команду выхода.

Задача 4. Разработать программу, которая запрашивает уникальный идентификатор человека (PERSON.PERSONID). После ввода идентификатора программа выводит имя человека (PERSON.NAME) и выдает список всех автомобилей, которыми владеет данный человек (произвольный набор колонок из таблицы AUTO по желанию разработчика, таблицы AUTO и PERSON связаны по полю PERSONID). Далее программа запрашивает новый идентификатор и т.д., пока пользователь не введет –1.

Задача 5. Разработать программу, которая запрашивает величину жалованья человека (поле SALARY таблицы PERSON). После этого программа должна выдать информацию (идентификатор (PERSONID), имя (NAME), должность (JOB) и жалованье) о десяти людях, жалование которых наиболее близко к введенному значению.

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

58

Практическое занятие 10 Углубленное изучение CALL-интерфейса

Практика 6 часов (Лекция 9)

На занятии будут приведены примеры, иллюстрирующие работу с СУБД ЛИНТЕР через прикладной интерфейс низкого уровня Intlib (CALL-интерфейс).

Будут рассмотрены следующие вопросы:

 

обработка ошибок с использованием GETE;

 

использование DML/DDL запросов;

 

работа с BLOB-столбцами;

 

работа с подчиненными курсорами;

 

обработка транзакций;

 

получение структуры ответа;

 

асинхронное выполнение запроса.

10.1. Использование DML/DDL запросов, обработка ошибок

Алгоритм работы примера prac10_e1.c таков:

1.Открывается канал.

2.Удаляется таблица AUTO, и при ошибке выводится текст с помощью команды

GETE.

3.Создается таблица AUTO, и при ошибке выводится текст с помощью команды

GETE.

4.Закрывается канал.

Следует обратить внимание на то, что запросы DML/DDL (все, кроме SELECT), подаются с четырьмя пробелами в поле Command:

memcpy(Cbl.Command,"

",4); /* Non SELECT command */

inter(&Cbl,NULL,"drop table auto;",NULL,NULL);

Для получения информации о произошедшей ошибке во время компиляции или выполнения запроса, предназначена команда GETE. В примере рассматривается применение данной команды для получения текстового сообщения от ядра о произошедшей ошибке (функция PrintError).

memcpy(pCBL->Command,"GETE",4);

/* Get error text */

pCBL->RowId = pCBL->CodErr;

pCBL->LnBufRow = MAXSTRLEN;

inter(pCBL,NULL,NULL,NULL,szErrorText);

if (pCBL->CodErr != NORMAL)

printf("Ошибка обработки GETE: %ld\n", pCBL->CodErr);

else

{

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

Практическое занятие 10. Углубленное изучение CALL-интерфейса 59

realLen = (pCBL->LnBufRow < realLen - 1) ? pCBL->LnBufRow : realLen;

printf("Сообщение: %s\n", szErrorText);

}

Для получения текстового сообщения заполняется поле RowId номером ошибки ЛИНТЕР, LnBufRow длиной буфера под сообщение. Адрес буфера передается как последний параметр функции inter.

При успешном завершении функции в буфере находится текстовое сообщение об ошибке, которое в примере выводится на экран.

Для демонстрации примера необходимо, чтобы существовала таблица ERRORS с описаниями ошибок. Если данная таблица отсутствует, то сообщение об ошибках будет

выглядеть так: Linter return code: 2202.

10.2. Работа с BLOB-столбцами

Алгоритм работы примера prac10_e2.c таков:

1.Открывается канал.

2.Делается попытка создания таблицы TFILE.

3.Предлагается меню, в котором:

в таблицу добавляется запись, в BLOB-поле которой загружается указанный пользователем файл;

делается выборка из таблицы, и выгружаются данные BLOB-поля в файл из строки, указанной пользователем.

18. Закрывается канал.

Следует обратить внимание, на то, что при занесении BLOB-данных можно указать тип (целое число), передаваемое в параметре RowId.

memcpy(pCbl->Command,"AOBJ",4);

pCbl->RowId = 0; pCbl->LnBufRow = realLen; inter(pCbl,NULL,NULL,NULL,buf);

При получении BLOB-данных следует иметь в виду, что передаваемая в параметре RowId позиция начинается с единицы.

long beginPos = 1;

memcpy(pCbl->Command,"GOBJ",4); pCbl->RowId = beginPos; pCbl->LnBufRow = blobPortion; inter(pCbl,NULL,NULL,NULL,buf);

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

60 Практическое занятие 10. Углубленное изучение CALL-интерфейса

beginPos += realLen;

Работы с данными из BLOB-столбца с минимальным номером используются команды AOBJ, COBJ и GOBJ. Для работы с другими BLOB-столбцами (с указанием номера) следует использовать команды ABLB, CBLB и GBLB.

Обучаемым необходимо самостоятельно решить одну из следующих задач.

Задача 1. Модифицировать данный пример, добавив возможность очистки всей таблицы и удаления указанных записей.

Задача 2. Модифицировать данный пример, добавив возможность очистки содержимого BLOB-ячейки и добавления данных в конец существующей BLOB-ячейки.

Задача 3. Модифицировать данный пример, добавив в таблицу поле FSOURCE, в котором будет располагаться исходный текст данного исполняемого файла (если он существует в директории данного файла). Например, пользователь указывает имя файла

/home/linter/prac10/prac10_e2, тогда добавляется новая запись; в столбец FCONTENT

загружается этот файл, а в столбец FSOURCE добавляется файл

/home/linter/prac10/prac10_e2.c.

Задача 4. Модифицировать данный пример, следующим образом: если для указанного имени файла существует файл *.c (с расширением ‘c’), то он добавляется следующей строкой и ему присваивается тип 1. Если существует файл *.h, то он также добавляется новой строкой и ему присваивается тип 2.

10.3. Работа с подчиненными курсорами, обработка транзакций

Как уже известно, клиентское приложение для работы с БД должно открыть канал связи (соединение). При открытии канала приложение должно указать имя ЛИНТЕРсервера, с которым должно быть установлено соединение, а также регистрационные данные для проверки санкционированного доступа (имя пользователя и пароль, под которыми приложение будет зарегистрировано как пользователь БД).

Через соединение могут быть открыты подчиненные каналы, называемые курсорами. Для открытия курсора приложению уже не нужно указывать регистрационные данные – курсоры наследуют эту информацию от соединения, которому они подчинены. Это удобно использовать, когда приложение должно обрабатывать различные запросы, направляемые к одной и той же БД: можно не открывать несколько соединений, а использовать несколько курсоров.

Механизм соединений и курсоров используется СУБД ЛИНТЕР для управления транзакциями. Изменения данных в БД, прошедшие по некоторому курсору, могут фиксироваться (откатываться) независимо от работы по другим курсорам соединения, однако фиксация/откат по соединению вызовет фиксацию/откат по всем подчиненным курсорам.

Пример prac10_e3.c иллюстрирует работу канала и двух подчиненных курсоров. Алгоритм его работы таков:

1.Открывается канал.

2.Делается попытка создания таблицы PRAC12_T1.

3.Открываются два курсора (в оптимистичном режиме обработки транзакций).

4.Предлагается меню, в котором:

 

 

в таблицу добавляется запись по любому из курсоров;

 

 

 

 

 

 

E-mail: market@relex.ru

ЗАО НПП «РЕЛЭКС»

http://www.relex.ru

 

 

 

 

 

 

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]