
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.175] |
![]() |
|
Сообщ.
#1
,
|
|
|
Пользуюсь NetShareAdd из NETAPI32.DLL. В структуре SHARE_INFO_2 описано поле shi2_permissions, но как я понял его значение для всех систем семейства NT игнорируется:
Цитата shi2_permissions Specifies a DWORD value that indicates the shared resource's permissions for servers running with share-level security. A server running user-level security ignores this member. This member can be one or more of the following values. Calls to the NetShareSetInfo function ignore this member. Note that the Windows Server 2003 family, Windows XP, Windows 2000, and Windows NT do not support share-level security. На практике так и есть, ставя любое другое разрешение помимо ACCESS_ALL папка все равно становится расшаренной на полный доступ. Вот в этом и состоит мой вопрос: как расшарить папку для доступа только для чтения из сети? Explorer ведь может. |
Сообщ.
#2
,
|
|
|
Расшарить папку (только для чтения)
Тут vbs скрипт. |
Сообщ.
#3
,
|
|
|
Цитата P.O.D @ Расшарить папку (только для чтения) Тут vbs скрипт. Спасибо, но... Я тоже так считаю. Неужели это единственный способ? |
Сообщ.
#4
,
|
|
|
Сам нашел ответ на вопрос, привожу код, portions copyright Rouse_ (его код из NetMon я взял за основу) and Smike (до остального уже сам дошел, порывшись в MSDN и гугле). Кое-какие функции и константы распорошены по разным юнитам, в частности отсутствующих в дефолтной поставке - JclSysInfo (там только IsWinNT) и JclWin32 (некоторые константы).
![]() ![]() uses Windows, SysUtils, JclSysInfo, AclApi, JclWin32; type TShareInfo502 = packed record shi502_netname : PWChar; shi502_type: DWORD; shi502_remark :PWChar; shi502_permissions: DWORD; shi502_max_uses : DWORD; shi502_current_uses : DWORD; shi502_path : PWChar; shi502_passwd : PWChar; shi502_reserved: DWORD; shi502_security_descriptor: PSECURITY_DESCRIPTOR; end; TShareInfo50 = packed record shi50_netname : array [0..12] of Char; shi50_type : Byte; shi50_flags : Word; shi50_remark : PChar; shi50_path : PChar; shi50_rw_password : array [0..8] of Char; shi50_ro_password : array [0..8] of Char; end; procedure ShareDirectory(const Directory: string); const STYPE_DISKTREE = 0; ACCESS_READ = $1; SHI50F_RDONLY = $1; ACL_REVISION = 2; var FLibHandle : THandle; Share9x : TShareInfo50; ShareNT : TShareInfo502; TmpDir, TmpName: string; TmpDirNT, TmpNameNT: PWChar; TmpLength: Integer; NetShareAddNT: function(servername: PWideChar; level: DWORD; buf: Pointer; parm_err: LPDWORD): DWORD; stdcall; NetShareAdd: function (pszServer:Pchar; sLevel:Cardinal; pbBuffer:PChar; cbBuffer:Word):DWORD; stdcall; pSd: PSECURITY_DESCRIPTOR; pDacl: PACL; EveryoneSid, AdminSid: Pointer; begin TmpDir := ExcludeTrailingPathDelimiter(Directory); TmpName := ExtractFileName(TmpDir); if IsWinNT then begin //Код для NT FLibHandle := LoadLibrary('NETAPI32.DLL'); if FLibHandle = 0 then Exit; NetShareAddNT := GetProcAddress(FLibHandle,'NetShareAdd'); if not Assigned(NetShareAddNT) then begin FreeLibrary(FLibHandle); Exit; end; TmpLength := SizeOF(WideChar)*256; //Определяем необходимый размер GetMem(TmpNameNT, TmpLength); //Конвертируем в PWChar StringToWideChar(TmpName, TmpNameNT, TmpLength); ShareNT.shi502_netname := TmpNameNT; //Имя ShareNT.shi502_type := STYPE_DISKTREE; //Тип ресурса ShareNT.shi502_remark := ''; //Комментарий ShareNT.shi502_permissions := ACCESS_READ; //Доступ ShareNT.shi502_max_uses := DWORD(-1); //Кол-во максим. подключ. ShareNT.shi502_current_uses := 0; //Кол-во тек подкл. GetMem(TmpDirNT, TmpLength); StringToWideChar(TmpDir, TmpDirNT, TmpLength); ShareNT.shi502_path := TmpDirNT; //Путь к ресурсу ShareNT.shi502_passwd := ''; //Пароль ShareNT.shi502_reserved := 0; // Здесь начинается самое интересное - задаем разрешения :) GetMem(pDacl, 256); InitializeAcl(pDacl^, 256, ACL_REVISION); EveryoneSid := nil; AdminSid := nil; AllocateAndInitializeSid(SECURITY_WORLD_SID_AUTHORITY, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, EveryoneSid); AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, AdminSid); AddAccessAllowedAce(pDacl^, ACL_REVISION, GENERIC_ALL, AdminSid); AddAccessAllowedAce(pDacl^, ACL_REVISION, (GENERIC_READ or GENERIC_EXECUTE or READ_CONTROL or STANDARD_RIGHTS_READ), EveryoneSid); GetMem(pSd, SECURITY_DESCRIPTOR_MIN_LENGTH); InitializeSecurityDescriptor(pSd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(pSd, TRUE, pDacl, FALSE); ShareNT.shi502_security_descriptor := pSd; NetShareAddNT(nil, 502, @ShareNT, nil); //Добавляем ресурс if Assigned(EveryoneSid) then FreeSid(EveryoneSid); if Assigned(AdminSid) then FreeSid(EveryoneSid); FreeMem (pDacl); FreeMem (pSd); FreeMem (TmpNameNT); //освобождаем память FreeMem (TmpDirNT); end else begin FLibHandle := LoadLibrary('SVRAPI.DLL'); if FLibHandle = 0 then Exit; NetShareAdd := GetProcAddress(FLibHandle,'NetShareAdd'); if not Assigned(NetShareAdd) then begin FreeLibrary(FLibHandle); Exit; end; FillChar(Share9x.shi50_netname, SizeOf(Share9x.shi50_netname), #0); move(TmpName[1],Share9x.shi50_netname[0],Length(TmpName)); //Имя Share9x.shi50_type := STYPE_DISKTREE; //Тип ресурса Share9x.shi50_flags := SHI50F_RDONLY; //Доступ FillChar(Share9x.shi50_remark, SizeOf(Share9x.shi50_remark), #0); //Комментарий FillChar(Share9x.shi50_path, SizeOf(Share9x.shi50_path), #0); Share9x.shi50_path := PAnsiChar(TmpDir); //Путь к ресурсу FillChar(Share9x.shi50_rw_password, SizeOf(Share9x.shi50_rw_password), #0); //Пароль полного доступа FillChar(Share9x.shi50_ro_password, SizeOf(Share9x.shi50_ro_password), #0); //Пароль для чтения NetShareAdd(nil,50,@Share9x,SizeOf(Share9x)); end; FreeLibrary(FLibHandle); end; |
Сообщ.
#5
,
|
|
|
Smike Круто
![]() |
Сообщ.
#6
,
|
|
|
![]() ![]() if Assigned(AdminSid) then FreeSid(EveryoneSid); Конечно же FreeSid(AdminSid), copy-paste и спешка, блин. |
Сообщ.
#7
,
|
|
|
Так должно быть совсем нормально
![]() ![]() ![]() {*******************************************************} { } { Добавление и удаление общих сетевых ресурсов } { } { Copyright (c) } { 1998-2002 Rouse_ } { (базовый код, взят из примера NetMon) } { 2006 Smike } { (- доработка для возможности создания } { ресурсов, открытых только для чтения } { под NT/2000/XP/2003, } { - небольшой рефакторинг ;) ) } { } {*******************************************************} unit Shares; interface uses Windows, SysUtils, AclApi; function ShareDirectory(const Directory: string): DWORD; function UnShareDirectory(const Directory: string): DWORD; implementation const STYPE_DISKTREE = 0; function ShareDirectoryNT(const Directory, ShareName: string): DWORD; type TShareInfo502 = packed record shi502_netname : PWChar; shi502_type: DWORD; shi502_remark :PWChar; shi502_permissions: DWORD; shi502_max_uses : DWORD; shi502_current_uses : DWORD; shi502_path : PWChar; shi502_passwd : PWChar; shi502_reserved: DWORD; shi502_security_descriptor: PSECURITY_DESCRIPTOR; end; const ACL_REVISION = 2; SECURITY_WORLD_SID_AUTHORITY: TSidIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 1)); SECURITY_WORLD_RID = ($00000000); SECURITY_NT_AUTHORITY: TSidIdentifierAuthority = (Value: (0, 0, 0, 0, 0, 5)); SECURITY_BUILTIN_DOMAIN_RID = ($00000020); DOMAIN_ALIAS_RID_ADMINS = ($00000220); var NetShareAddNT: function(servername: PWideChar; level: DWORD; buf: Pointer; parm_err: LPDWORD): DWORD; stdcall; ShareNT : TShareInfo502; FLibHandle: THandle; TmpDirNT, TmpNameNT: PWChar; TmpLength: Integer; pSd: PSECURITY_DESCRIPTOR; pDacl: PACL; EveryoneSid, AdminSid: Pointer; begin Result := DWORD(-1); FLibHandle := LoadLibrary('NETAPI32.DLL'); if FLibHandle = 0 then Exit; try NetShareAddNT := GetProcAddress(FLibHandle,'NetShareAdd'); if not Assigned(NetShareAddNT) then Exit; TmpLength := SizeOf(WideChar) * 256; //Определяем необходимый размер GetMem(TmpNameNT, TmpLength); //Конвертируем в PWChar StringToWideChar(ShareName, TmpNameNT, TmpLength); ShareNT.shi502_netname := TmpNameNT; //Имя ShareNT.shi502_type := STYPE_DISKTREE; //Тип ресурса ShareNT.shi502_remark := ''; //Комментарий // В NT, 2000, XP, 2003 разрешения на уровне расшаренной папки не поддерживается // Для этого задаем ниже атрибуты доступа на уровне групп ShareNT.shi502_permissions := 0; ShareNT.shi502_max_uses := DWORD(-1); //Кол-во максим. подключ. ShareNT.shi502_current_uses := 0; //Кол-во тек подкл. GetMem(TmpDirNT, TmpLength); StringToWideChar(Directory, TmpDirNT, TmpLength); ShareNT.shi502_path := TmpDirNT; //Путь к ресурсу ShareNT.shi502_passwd := ''; //Пароль ShareNT.shi502_reserved := 0; // Здесь начинается самое интересное - задаем разрешения :) GetMem(pDacl, 256); InitializeAcl(pDacl^, 256, ACL_REVISION); EveryoneSid := nil; AdminSid := nil; AllocateAndInitializeSid(SECURITY_WORLD_SID_AUTHORITY, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, EveryoneSid); AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, AdminSid); AddAccessAllowedAce(pDacl^, ACL_REVISION, GENERIC_ALL, AdminSid); AddAccessAllowedAce(pDacl^, ACL_REVISION, (GENERIC_READ or GENERIC_EXECUTE or READ_CONTROL or STANDARD_RIGHTS_READ), EveryoneSid); GetMem(pSd, SECURITY_DESCRIPTOR_MIN_LENGTH); InitializeSecurityDescriptor(pSd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(pSd, TRUE, pDacl, FALSE); ShareNT.shi502_security_descriptor := pSd; Result := NetShareAddNT(nil, 502, @ShareNT, nil); //Добавляем ресурс if Assigned(EveryoneSid) then FreeSid(EveryoneSid); if Assigned(AdminSid) then FreeSid(AdminSid); //освобождаем память FreeMem(pDacl); FreeMem(pSd); FreeMem(TmpNameNT); FreeMem(TmpDirNT); finally FreeLibrary(FLibHandle); end; end; function ShareDirectory9x(const Directory, ShareName: string): DWORD; type TShareInfo50 = packed record shi50_netname : array [0..12] of Char; shi50_type : Byte; shi50_flags : Word; shi50_remark : PChar; shi50_path : PChar; shi50_rw_password : array [0..8] of Char; shi50_ro_password : array [0..8] of Char; end; const SHI50F_RDONLY = $1; var NetShareAdd: function(pszServer: PAnsiChar; sLevel: Cardinal; pbBuffer: PAnsiChar; cbBuffer: Word):DWORD; stdcall; Share9x : TShareInfo50; FLibHandle : THandle; begin Result := DWORD(-1); FLibHandle := LoadLibrary('SVRAPI.DLL'); if FLibHandle = 0 then Exit; try NetShareAdd := GetProcAddress(FLibHandle,'NetShareAdd'); if not Assigned(NetShareAdd) then Exit; FillChar(Share9x.shi50_netname, SizeOf(Share9x.shi50_netname), #0); Move(ShareName[1], Share9x.shi50_netname[0], Length(ShareName)); //Имя Share9x.shi50_type := STYPE_DISKTREE; //Тип ресурса Share9x.shi50_flags := SHI50F_RDONLY; //Доступ FillChar(Share9x.shi50_remark, SizeOf(Share9x.shi50_remark), #0); //Комментарий FillChar(Share9x.shi50_path, SizeOf(Share9x.shi50_path), #0); Share9x.shi50_path := PAnsiChar(Directory); //Путь к ресурсу FillChar(Share9x.shi50_rw_password, SizeOf(Share9x.shi50_rw_password), #0); //Пароль полного доступа FillChar(Share9x.shi50_ro_password, SizeOf(Share9x.shi50_ro_password), #0); //Пароль для чтения Result := NetShareAdd(nil, 50, @Share9x, SizeOf(Share9x)); finally FreeLibrary(FLibHandle); end; end; function ShareDirectory(const Directory: string): DWORD; var ShareDir, ShareName: string; begin ShareDir := ExcludeTrailingPathDelimiter(Directory); ShareName := ExtractFileName(ShareDir); if Win32Platform = VER_PLATFORM_WIN32_NT then Result := ShareDirectoryNT(ShareDir, ShareName) else Result := ShareDirectory9x(ShareDir, ShareName); end; function UnShareDirectoryNT(const ShareName: string): DWORD; var FLibHandle : THandle; NameNT: PWChar; NetShareDelNT: function(servername: PWideChar; netname: PWideChar; reserved: DWORD): LongInt; stdcall; Size: Integer; begin Result := DWORD(-1); FLibHandle := LoadLibrary('NETAPI32.DLL'); if FLibHandle = 0 then Exit; try NetShareDelNT := GetProcAddress(FLibHandle, 'NetShareDel'); if not Assigned(NetShareDelNT) then //Проверка begin FreeLibrary(FLibHandle); Exit; end; Size := SizeOf(WideChar) * 256; GetMem(NameNT, Size); //Выделяем память под переменную StringToWideChar(ShareName, NameNT, Size); //Преобразуем в PWideChar NetShareDelNT(nil, NameNT, 0); //Удаляем ресурс FreeMem(NameNT); //Освобождаем память finally FreeLibrary(FLibHandle); end; end; function UnShareDirectory9x(const ShareName: string): DWORD; var FLibHandle: THandle; Name9x: array [0..12] of Char; NetShareDel: function(pszServer, pszNetName: PChar; usReserved: Word): DWORD; stdcall; begin Result := DWORD(-1); FLibHandle := LoadLibrary('SVRAPI.DLL'); if FLibHandle = 0 then Exit; try NetShareDel := GetProcAddress(FLibHandle,'NetShareDel'); if not Assigned(NetShareDel) then Exit; FillChar(Name9x, SizeOf(Name9x), #0); //Очищаем массив Move(ShareName[1], Name9x[0], Length(ShareName)); //Заполняем массив Result := NetShareDel(nil, @Name9x, 0); //Удаляем ресурс finally FreeLibrary(FLibHandle); end; end; function UnShareDirectory(const Directory: string): DWORD; var ShareName: string; begin ShareName := ExtractFileName(ExcludeTrailingPathDelimiter(Directory)); if Win32Platform = VER_PLATFORM_WIN32_NT then //Код для NT Result := UnShareDirectoryNT(ShareName) else //Код для 9х-Ме Result := UnShareDirectory9x(ShareName); end; end. |
![]() |
Сообщ.
#8
,
|
|
Угу, все хорошо, только я очень много раз говорил что все это делается через выставление дескрипторов безопасности, странно что не нашел мои сообщения
![]() ![]() |
Сообщ.
#9
,
|
|
|
Я забыл, что в 98-ой разрешений как таковых не существует. Есть только фйлажок "разрешить изменение файлов по сети".
|