При организации работы в одноранговой локальной сети часто возникает задача ограничить права пользователей на редактирование документов задним числом. Разработчики нередко пытаются решить эту задачу вызовом серверных функций 1С, рассчитывая получить системное время с компьютера, на котором физически расположена база. Однако на практике функция возвращает локальное время рабочего места пользователя, что позволяет недобросовестным сотрудникам обходить запрет простой сменой часов в операционной системе. Разберем, почему так происходит и какие существуют надежные способы решения этой проблемы.
Проанализируем архитектуру файлового режима работы 1С:Предприятия. Когда база данных располагается в общей сетевой папке (SMB/shared folder) на компьютере бухгалтера, а менеджеры подключаются к ней по локальной сети через ярлык, клиент-серверной архитектуры в технологическом смысле не возникает.
В таком режиме весь программный код (включая процедуры с директивой &НаСервере и модули с признаком Вызов сервера) исполняется непосредственно на локальной рабочей станции пользователя. Платформа 1С эмулирует серверный контекст локально внутри клиентского процесса. Соответственно, системные функции ТекущаяДата() или ТекущаяДатаСеанса() всегда опрашивают системный таймер операционной системы того компьютера, за которым физически сидит пользователь.
Рассмотрим самый простой и надежный программный способ в рамках платформы 1С, не требующий вызова внешних системных утилит и командной строки. При записи или перезаписи файла на сетевом диске файловая система выставляет атрибуты времени изменения и создания по часам того компьютера, где физически установлен жесткий диск.
Посмотрим на практический пример реализации функции получения сетевого времени:
Функция ПолучитьВремяСетевогоКаталога(ПутьККаталогуБазы) Экспорт
ИмяФайлаМетки = ПутьККаталогуБазы + "\~time_check.tmp";
// Создаем или перезаписываем временный файл
ЗаписьТекста = Новый ЗаписьТекста(ИмяФайлаМетки, КодировкаТекста.ANSI);
ЗаписьТекста.ЗаписатьСтроку(Строка(Новый УникальныйИдентификатор));
ЗаписьТекста.Закрыть();
// Считываем время изменения файла, выставленное файловой системой хоста
ФайлМетки = Новый Файл(ИмяФайлаМетки);
ВремяХоста = ФайлМетки.ПолучитьВремяИзменения();
// Удаляем временный файл
Попытка
УдалитьФайлы(ИмяФайлаМетки);
Исключение
// Игнорируем ошибку удаления, если файл занят
КонецПопытки;
Возврат ВремяХоста;
КонецФункции
Этот метод работает полностью встроенными средствами 1С, не зависит от установленных прав на выполнение консольных команд и корректно возвращает время компьютера с базой данных.
Разберем типичную ошибку при вызове системной утилиты net time через метод ЗапуститьПриложение(). Метод платформы вызывает исполняемый файл напрямую через системное API Windows, минуя командный процессор. Поэтому символы перенаправления потоков (>) не обрабатываются и текстовый файл не формируется.
Для корректного получения сетевого времени через консоль Windows необходимо запускать команду через командный интерпретатор cmd.exe с ключом /c. Посмотрим, как это сделать программно:
Функция ПолучитьВремяУдаленногоКомпьютера(ИмяХоста) Экспорт
ВременныйФайл = КаталогВременныхФайлов() + "net_time.txt";
Команда = "cmd.exe /c net time \\" + ИмяХоста + " > """ + ВременныйФайл + """";
КодВозврата = 0;
ЗапуститьПриложение(Команда, "", Истина, КодВозврата);
Если КодВозврата = 0 Тогда
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Прочитать(ВременныйФайл, КодировкаТекста.OEM);
ТекстРезультата = ТекстовыйДокумент.ПолучитьТекст();
// Удаляем временный файл после чтения
УдалитьФайлы(ВременныйФайл);
Возврат ТекстРезультата;
КонецЕсли;
Возврат Неопределено;
КонецФункции
Обратите внимание: Для работы команды net time на целевом компьютере должна быть запущена служба времени, а сетевые порты SMB не должны блокироваться брандмауэром.
Проанализируем наиболее правильный с точки зрения архитектуры 1С способ организации совместной работы в файловом режиме. Если опубликовать информационную базу на веб-сервере (Apache или IIS), расположенном на компьютере бухгалтера, схема выполнения кода принципиально изменится:
&НаСервере начинает физически исполняться в процессе веб-сервера на компьютере бухгалтера.ТекущаяДата(), вызванная на сервере, гарантированно возвращает системное время главного компьютера, исключая возможность манипуляций со стороны клиентских ПК.Если нет возможности дорабатывать конфигурацию или разворачивать веб-сервер, рассмотрим организационно-системные меры защиты:
secpol.msc) в ветке «Локальные политики» — «Назначение прав пользователя» отберите у непривилегированных учетных записей право «Изменение системного времени» (SeSystemtimePrivilege). Пользователи без прав администратора потеряют возможность менять системные часы на своих рабочих станциях.