找回密码
 加入
搜索
查看: 12910|回复: 16

[系统综合] lsasecur.au3设置文件权限

  [复制链接]
发表于 2011-2-3 15:29:34 | 显示全部楼层 |阅读模式
本帖最后由 jd19970829 于 2011-2-4 00:37 编辑

lsasecur.au3
里面这个函数Func _SeSetFileSecurity($sFileName, $iSecurInfo, $pSecurDescr)到底是怎么用的啊?
Func _SeSetFileSecurity("c:\1", $SE_INFO_DACL, $pSecurDescr)这个$pSecurDescr 参数到底是什么?是个数组还是什么,怎么设置呢?
我想让c:\1这个目录 的权限设置成everyone可以完全控制,该怎么写这个函数?$pSecurDescr这个参数怎么设置啊?
发表于 2011-2-3 17:48:13 | 显示全部楼层
#include <lsasecur.au3>

Local $pDacl, $pSecurDescr, $pEveryoneSid, $aList[1][4]

; Everyone用户SID指针。
$pEveryoneSid = _SeLookupAccountName("Everyone")

$aList[0][0] = $pEveryoneSid                ; 授权者SID
$aList[0][1] = $SE_GENERIC_ALL                ; 完全控制
$aList[0][2] = $SE_GRANT_ACCESS                ; 访问类型(允许)
$aList[0][3] = $SE_INHERIT_FOLDER_SUBFOLDER_SUBFILE        ; 权限继承至所有子文件/文件夹

; 创建 访问控制列表(DACL)
$pDacl = _SeSetEntriesInAcl($aList)

; 初始化 安全描述符(SD)
$pSecurDescr = _SeInitSecurityDescriptor()

; 设置 安全描述符 中的 DACL
_SeSetSecurityDescriptorDacl($pSecurDescr, $pDacl)

; 设置文件权限
If _SeSetFileSecurity("C:\1", $SE_INFO_DACL, $pSecurDescr) Then
        MsgBox(48, "OK", "Done.")
Else
        MsgBox(48, "Error", _SeFormatMsg())
EndIf

; 释放资源
_SeLocalFree($pDacl)
_SeHeapFree($pSecurDescr)
_SeHeapFree($pEveryoneSid)
 楼主| 发表于 2011-2-3 23:25:23 | 显示全部楼层
提示: 该帖被管理员或版主屏蔽
??这是什么意思?难道还不能帮忙解答问题了?
发表于 2011-2-3 23:33:56 | 显示全部楼层
回复 3# jd19970829


    把你顶楼的错字改过来 你就能看到2#的回复了。
 楼主| 发表于 2011-2-3 23:41:42 | 显示全部楼层
本帖最后由 jd19970829 于 2011-2-4 00:38 编辑

我已经把所有标有下划线的都改了,怎么还是看不到2楼的回复啊?
我急需这个函数的使用帮助,希望版主能帮帮我。
发表于 2011-2-3 23:51:00 | 显示全部楼层
回复 5# jd19970829


    那个下划线貌似是论坛的自动标签功能,不是你的错别字。我说的错字是“改”,如果你急于解决问题,把顶楼的所有错误改过来,还有你5#回复中的错字。
 楼主| 发表于 2011-2-4 00:39:07 | 显示全部楼层
版主,我已经把我的错别字都改了,希望你能回复我。
 楼主| 发表于 2011-2-4 00:58:33 | 显示全部楼层
_SeTreeResetNamedSecurityInfo我主要是想使用这个函数对注册表或者整个文件目录树的权限进行修改,可是怎么设置也不成功,希望版主能给我一个具体的例题。
Dim $fileAccess[1][4] = [["everyone", $SE_GENERIC_ALL, $SE_ALLOWED_ACE_TYPE, $SE_OBJECT_INHERIT_ACE]]
_SeTreeResetNamedSecurityInfo("c:\1", $SE_FILE_OBJECT, $SE_INFO_DACL, "", "", $fileAccess, "")
这个是我自己测试的时候对这个函数的设置,我估计应该是$pDacl这个参数没有设置对,但是我不知道这个参数改怎样设置。
我需要对c:\1整个目录树的权限做修改,让everyone只有只读权限,希望版主能给我这个问题的具体示例。
发表于 2011-2-4 15:08:44 | 显示全部楼层
回复 7# jd19970829


    OK,2#已经解除屏蔽了,2#的代码是设置C:\1的权限为 允许Everyone用户的所有访问,并且权限将继承到所有子文件和子文件夹。
发表于 2011-2-4 16:39:39 | 显示全部楼层
回复 8# jd19970829


   
#include <lsasecur.au3>

Local $aFileAccess[1][4] = _
                [[_SeLookupAccountName("Everyone"), _
                $SE_GENERIC_ALL, _
                $SE_GRANT_ACCESS, _
                $SE_INHERIT_FOLDER_SUBFOLDER_SUBFILE ]]

Local $pDacl = _SeSetEntriesInAcl($aFileAccess)

$fStatus = _SeTreeResetNamedSecurityInfo("C:\1", $SE_FILE_OBJECT, $SE_INFO_DACL, 0, 0, $pDacl, 0, "_CallBack", $SE_TREE_SECUR_INVOKE_EVERY_OBJECT, 0)
If $fStatus Then
        MsgBox(48, "OK", "Done.")
Else
        MsgBox(48, "Error", _SeFormatMsg())
EndIf
_SeLocalFree($pDacl)

Func _CallBack($sObject, $iStatus, $fSecuritySet)
        ConsoleWrite("Processing " & $sObject & @CRLF)
        If $iStatus Then
                Switch MsgBox(48 + 2, "Error", $sObject & @CRLF & _SeFormatMsg("", $iStatus))
                Case 3 ; Abort
                        Return $SE_TREE_RESET_SECUR_CANCEL
                Case 4 ; Retry
                        Return $SE_TREE_RESET_SECUR_RETRY
                Case 5 ; Ignore
                        ; Need not return a value.
                EndSwitch
        EndIf
EndFunc        ;==>_CallBack


递归设置 C:\1及其子文件/文件夹的权限,允许Everyone用户的所有访问,只支持XP及以后的Windows版本。
 楼主| 发表于 2011-2-4 16:48:14 | 显示全部楼层
本帖最后由 jd19970829 于 2011-2-4 16:50 编辑

非常感谢版主的指教,我已经成功使用了你2#的那个例子。
但是我使用这个函数,设置整个目录树的时候遇到一点问题
_SeTreeResetNamedSecurityInfo("C:\1", $SE_FILE_OBJECT, $SE_INFO_DACL, "", "", $pDacl, "")
我就用你在2#里面定义的那个例子做了一点修改,我调用_SeTreeResetNamedSecurityInfo这个函数设置整个目录树,但是没有得到我想要的结果,我想要的结果是C:\1和C:\1下面的所有子目录和文件的访问权限都被替换成everyone完全控制,但是运行了以后,却是C:\1和C:\1下面的所有子目录和文件的访问权限都增加了everyone完全控制,而不是替换了。不知道是哪里没有搞对,还请版主给点指示。
还有一个问题,我仔细找了lsasecur.au3这个文件里面,没有发现能够设置文件所有者的函数,不知道是我没有找到还是确实没有。但是我在另一个UDF LocalSecurityAuthority.au3里面确发现有这样的函数_SetFileSecurityOwner,我看了关于lsasecur.au3的描述(第2版的lsasecur包括第1版LocalSecurityAuthority的所有功能,并添加了一些新特性),按道理说lsasecur.au3里面也该有能够设置文件所有者的函数,可是我怎么没有找到呢?
LocalSecurityAuthority.au3和lsasecur.au3这2个UDF都是超级版主的作品吧,这2个有什么不同呢?是lsasecur.au3包含了LocalSecurityAuthority.au3还是LocalSecurityAuthority.au3包含了lsasecur.au3,还是他们2个是有区别的,用于不同情况。
 楼主| 发表于 2011-2-4 17:57:07 | 显示全部楼层
回复 10# pusofalse

不行啊,超级版主,没有达到效果
我运行了你10#的代码,最后得到C:\1和子目录的权限是

也就是说只是把everyone这个用户增加进去了,而不是替换了原有的DACL

而运行你2#的代码得到的是

也就是说是everyone这个用户替换了原有的DACL,这个才是我想达到的效果。

是不是哪个参数没有设置对?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2011-2-4 19:31:06 | 显示全部楼层
回复 12# jd19970829

    是这样的,所有可继承的ACE 都将自动应用到子对象上,_SeTreeResetNamedSecurityInfo最终调用了AdvApi32.SetNamedSecurityInfo函数(只不过加上了递归遍历功能),看下这个函数的说明:
If you are setting the discretionary access control list (DACL) or system access control list (SACL) of an object, the system automatically propagates any inheritable access control entries (ACEs) to existing child objects, according to the rules of inheritance.


如果要递归替换ACL而不是添加,可以自己写个递归函数遍历整个目录树,每找到一个文件/文件夹,调用_SeSetFileSecurity设置它的安全权限。论坛中有遍历文件的源码。

LocalSecurityAuthority._SetFileSecurityOwner其实是调用了同一个库中的_SetFileSecurity,_SetFileSecurity和lsasecur._SeSetFileSecurity原型都一样。当初编写lsasecur.au3时,考虑到了效率方面的问题,便舍弃了_SeSetFileSecurityOwner函数,设置所有者也可以用_SeSetFileSecurity函数完成:

#include <lsasecur.au3>

; Enable RESTORE privilege for current thread.
Local $hToken = _SeOpenProcessToken(-1)
Local $aPriv[1][2] = [[$SE_RESTORE_PRIV, $SE_PRIV_ENABLED]]
_SeAdjustTokenPrivs($hToken, $aPriv)
_SeCloseHandle($hToken)

Local $pOwnerSid = _SeLookupAccountName("Everyone")
Local $pSecurDescr = _SeInitSecurityDescriptor()
_SeSetSecurityDescriptorOwner($pSecurDescr, $pOwnerSid)
If _SeSetFileSecurity("C:\1", $SE_INFO_OWNER, $pSecurDescr) Then
        MsgBox(48, "OK", "Done.")
Else
        MsgBox(48, "Error", _SeFormatMsg())
EndIf
_SeHeapFree($pOwnerSid)
_SeHeapFree($pSecurDescr)


或者另一种方法:
#include <lsasecur.au3>

; Enable RESTORE privilege for current thread.
Local $hToken = _SeOpenProcessToken(-1)
Local $aPriv[1][2] = [[$SE_RESTORE_PRIV, $SE_PRIV_ENABLED]]
_SeAdjustTokenPrivs($hToken, $aPriv)
_SeCloseHandle($hToken)

Local $pOwnerSid = _SeLookupAccountName("Everyone")
$fStatus = _SeSetNamedSecurityInfo("C:\1", $SE_FILE_OBJECT, $SE_INFO_OWNER, $pOwnerSid, 0, 0, 0)
If $fStatus Then
        MsgBox(48, "OK", "Done.")
Else
        MsgBox(48, "Error", _SeFormatMsg())
EndIf
_SeHeapFree($pOwnerSid)


必须为调用者开启RESTORE权限,否则只能设置所有者为 当前用户/用户组。

如果要递归设置所有者:
#include <lsasecur.au3>

Local $hToken = _SeOpenProcessToken(-1)
Local $aPriv[1][2] = [[$SE_RESTORE_PRIV, $SE_PRIV_ENABLED]]
_SeAdjustTokenPrivs($hToken, $aPriv)
_SeCloseHandle($hToken)

Local $pOwnerSid = _SeLookupAccountName("Everyone") ; Try to use another user account.
; Equal to _SeCreateWellKnownSid(1)

$fStatus = _SeTreeResetNamedSecurityInfo("C:\1", $SE_FILE_OBJECT, $SE_INFO_OWNER, $pOwnerSid, 0, 0, 0, _
                "", $SE_TREE_SECUR_INVOKE_NEVER) ; Never track the progress.

If $fStatus Then
        MsgBox(48, "OK", "Done.")
Else
        MsgBox(48, "Error", _SeFormatMsg())
EndIf


新版的lsasecur舍弃了_SeSet*SecurityOwner和_SeSet*SecurityDacl函数,因为都可以调用_SeSet*Security函数完成一样的功能,只不过自己写有点麻烦,但是,_SeSet*Security*函数在内部要检查参数是否合法,效率也就因此降低了许多,尤其是当多个函数都要检查同一个参数时,所以舍弃了。但也同时考虑到了如果不执行参数检查,可能会引起程序非常严重的错误,比如非法的内存访问(SID、ACL、安全描述符 都是内存指针),所以加了一个修复异常的_SeRegisterExceptionHandler函数,具体参考lsasecur原帖。
 楼主| 发表于 2011-2-4 20:45:03 | 显示全部楼层
多谢版主热心解答,感激不尽
发表于 2011-2-8 00:17:36 | 显示全部楼层
多谢版主,感激
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-11-17 19:48 , Processed in 0.082710 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表