Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2015.04.19;
Скачать: CL | DM;

Вниз

Где собака порылась?   Найти похожие ветки 

 
Dimka Maslov ©   (2014-09-02 17:21) [0]

Дано:
имеются сервер с общей папкой и два компьютера. На одном компе залогинен доменный пользователь, имеющий на сервере права локального админа. На втором компе - имеющий на сервере права пользователя. Для общей папки в настройках безопасность админу дан полный доступ, пользователю - только чтение, чтение и выполнение, запись.

Что происходит:

1) На локальном компе с админской учёткой запускается процесс, который создаёт в общей папке файл и держит его открытым. На том же локальном компе с админской учёткой запускается другой процесс, пытающийся открыть тот же самый файл. CreateFile возвращает INVALID_HANDLE_VALUE, GetLastError возвращает ERROR_SHARING_VIOLATION. Что и требовалось.

2) На локальном компе с пользовательской учёткой запускается процесс, который создаёт в общей папке файл и держит его открытым. На компе с админской учёткой запускается процесс, пытающийся открыть тот же самый файл. Результат аналогичен варианту 1.

3) На компе с админской учёткой запускается процесс... далее понятно. На компе с пользовательской учёткой производится попытка открыть файл в ВНИМАНИЕ! GetLastError возвращает ERROR_ACCESS_DENIED! О п а н ь к и !

4) Даём пользователю полный доступ к сетевому ресурсу и повторяем пункт 3. GetLastError снова возвращает ERROR_SHARING_VIOLATION.

Логика работы программы такова, что в случае ERROR_SHARING_VIOLATION надо подождать и попробовать снова заполучить доступ к файлу (простейшая форма синхронизации между компьютерами), а в случае другой ошибки - начинать на это жаловаться в вышестоящие инстанции.

Внимание вопрос:

С какого такого вообще в варианте 3 код ошибки другой? Это баг Винды или фича? Если таки фича, получается что GetLastError нужен лишь для выдачи сообщения об ошибке, а не для принятия решения о том, что делать дальше?


 
junglecat   (2014-09-02 17:39) [1]

> На компе с админской учёткой запускается процесс... далее
> понятно. На компе с пользовательской учёткой производится
> попытка открыть файл в ВНИМАНИЕ! GetLastError возвращает
> ERROR_ACCESS_DENIED!

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


 
Dimka Maslov ©   (2014-09-02 18:03) [2]


> возможно, дело в том, что пользовательская учетка бесправна
> по отношению к файлу, созданному админской. И проверка доступа
> приоритетней проверки режима разделения.


Но почему тогда если файл не открыт, а просто лежит, пользовательская учётка обладает всеми присущими ей правами?


 
Плохиш ©   (2014-09-02 18:34) [3]


> 3) На компе с админской учёткой запускается процесс... далее
> понятно. На компе с пользовательской учёткой производится
> попытка открыть файл в ВНИМАНИЕ! GetLastError возвращает
> ERROR_ACCESS_DENIED! О п а н ь к и !

Правов маловато - обломился при открытии на запись.

> 4) Даём пользователю полный доступ к сетевому ресурсу и
> повторяем пункт 3. GetLastError снова возвращает ERROR_SHARING_VIOLATION.

Прав до фига - но файл всё-равно заблокирован для записи.


 
Dimka Maslov ©   (2014-09-02 18:39) [4]

Файл и должен быть заблокирован для записи. Вопрос в том, почему если он держится "админом" то при попытке его открыть "юзверем" код ошибки не такой, нежели при попытке открыть "админом" файл, заблокированный "юзверем". По логике, если я обладаю правами записи и чтения в файл, мне должно быть безразлично, кем держится файл, учёткой с повышенными правами или без таковых. Ошибка всегда должна быть ERROR_SHARING_VIOLATION.


 
junglecat   (2014-09-02 18:42) [5]

а может, все проще, и это очередная багофича, придуманная парнями из Редмонда в пятницу вечером за пузырем вискаря


 
Плохиш ©   (2014-09-02 18:44) [6]


> Ошибка всегда должна быть ERROR_SHARING_VIOLATION.

Подай в суд на производителя, или делфи, или вынь-апи.


 
Пит   (2014-09-02 21:58) [7]


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

если всё, что ты описал верно и оба компьютера в домене - я с тобой полностью согласен. По логике.

С другой стороны, если это поведение описано в документации - это фича )

А если с практической точки зрения - как определить файл занят или нет прав для доступа - то я хз ;)


 
sniknik ©   (2014-09-03 10:04) [8]

> простейшая форма синхронизации между компьютерами
не, простейшая это файл флаг, работало еще в DOS без всяких шарингов на простейших файловых системах между прогами на разных языках некоторые из которых тоже не определяли тип блокировки (1С старый, сейчас не знаю).

> 4) Даём пользователю полный доступ к сетевому ресурсу
а до этого к ресурсу где файл доступа не было? ну так это и есть ACCESS_DENIED.


 
Dimka Maslov ©   (2014-09-03 10:42) [9]


> не, простейшая


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


> а до этого к ресурсу где файл доступа не было


Был. На чтение был, на запись был, на чтение и выполнение был. Вот только полного доступа не было.


 
sniknik ©   (2014-09-03 11:22) [10]

> Был. На чтение был, на запись был, на чтение и выполнение был. Вот только полного доступа не было.
когда "шариш" папку там есть "доступ" и "безопасность", то что ты написал это безопасность (нет в доступе пункта "чтение и выполнение").
так где доступа не было? не понятно.

+
еще не понятно почему(есть ли) разница (не в результате а в методах)  в пункте 2 и 3, должно быть (насколько знаю, было всегда когда занимался... одинаково.
как открываешь файл в локальном (2м) варианте? по сетевому протоколу (\\шара\папка\файл)? просто раз делаешь, сравниваешь для сети то и проверять должен сеть.


 
Dimka Maslov ©   (2014-09-03 11:36) [11]


> так где доступа не было? не понятно.


В "Безопасности" первой галочкой идёт "Полный доступ". Если её поставить ошибка ERROR_SHARING_VIOLATION если убрать - ERROR_ACCESS_DENIED

+

Метод открытия файла всегда одинаковый - CreateFile


 
junglecat   (2014-09-03 11:45) [12]

> Метод открытия файла всегда одинаковый - CreateFile

с какими флагами?


 
Dimka Maslov ©   (2014-09-03 12:12) [13]

FHandle := CreateFile("\\strudle\work\test.txt", GENERIC_ALL, 0, nil, OPEN_ALWAYS, 0, 0);


 
junglecat   (2014-09-03 12:17) [14]

> GENERIC_ALL

ну дык... а чего-ж ты тогда хочешь?
GENERIC_READ or GENERIC_WRITE не достаточно?


 
sniknik ©   (2014-09-03 12:26) [15]

проверил, никаких "чудес" не получил, до пункта 3 (там где ACCESS_DENIED) дошел, у меня ошибка ERROR_SHARING_VIOLATION, дальше не стал.

в доступе шары в разрешениях стоит "полный доступ", в безопасности "чтение выполнение" "список содержимого" "чтение" "запись"

Edit1.Text = \\ws131\share\test.txt

procedure TForm1.Button1Click(Sender: TObject);
begin
 with TFileStream.Create(Edit1.Text, fmCreate) do
 try
 finally
   Free;
 end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 Stream:= TFileStream.Create(Edit1.Text, fmOpenRead or fmShareDenyNone);
 Button2.Enabled:= false;
 Button3.Enabled:= true;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
 Stream.Free;
 Button2.Enabled:= true;
 Button3.Enabled:= false;
end;


 
sniknik ©   (2014-09-03 12:29) [16]

p.s. имхо, у тебя для пользовательской учетки права как-то криво/не очевидно настроены, наследования где нибудь, еще что...
у меня кстати единственная запись там, в безопасности, была для "Все". чтобы без неоднозначности.


 
Dimka Maslov ©   (2014-09-03 12:30) [17]


> GENERIC_READ or GENERIC_WRITE не достаточно?


Таки да, помогло


 
Dimka Maslov ©   (2014-09-03 12:31) [18]

Хотя и не понятно, с хренов ли такое поведение


 
KSergey ©   (2014-09-03 13:41) [19]

Скорее всего нюанс во владельце файла, как-то тут права начинают с учетом прав владельца "пересекаться" (это неправильное слово, конечно).

А далее, похоже,
Плохиш ©   (02.09.14 18:34) [3]


 
Dimka Maslov ©   (2014-09-03 14:36) [20]


> sniknik ©   (03.09.14 12:26) [15]


В свете [17] можно сказать, что  TFileStream не использует флаг GENERIC_ALL. Поэтому ошибка та же


 
sniknik ©   (2014-09-04 16:58) [21]

> не использует флаг GENERIC_ALL.
скопировал модуль (используется точно он, судя по работающей точке останова) изменил на, т.е. стал использовать флаг -
function FileCreate(const FileName: string): Integer;
{$IFDEF MSWINDOWS}
begin
 Result := Integer(CreateFile(PChar(FileName), GENERIC_ALL {GENERIC_READ or GENERIC_WRITE},
   0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0));
end;
{$ENDIF}
{$IFDEF LINUX}
begin
 Result := FileCreate(FileName, FileAccessRights);
end;
{$ENDIF}


ошибка не поменялась, на всех этапах -
Cannot create file "\\ws131\share\test.txt". Процесс не может получить доступ к файлу, так как этот файл занят другим процессом.

p.s. не всегда если что-то исправляет ошибку исправляет и причину тоже.


 
Dimka Maslov ©   (2014-09-04 17:37) [22]


> sniknik ©   (04.09.14 16:58) [21]


CREATE_ALWAYS и OPEN_ALWAYS всё же разные вещи



Страницы: 1 вся ветка

Текущий архив: 2015.04.19;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.005 c
1-1330092651
dead_appendix
2012-02-24 18:10
2015.04.19
Application Hide и InputBox


15-1409917492
Вопрошающий
2014-09-05 15:44
2015.04.19
Бесплатный хостинг с ftp


2-1392023445
Novicer
2014-02-10 13:10
2015.04.19
Печать DbGrid в QuickReport


15-1410069709
SKIPtr
2014-09-07 10:01
2015.04.19
посмотреть результат DOS команды


2-1392037072
Неважно
2014-02-10 16:57
2015.04.19
Как при открытии формы модально, задать фокус некоторого элемента