VBScript运行时错误'800a000d'

时间:2015-11-10 10:16:15

标签: sql-server vbscript asp-classic

在我们的业务中,我们使用安全向导来控制和管理活动目录安全性,并对更改进行审计跟踪。这是一个带有ASP前端的SQL数据库,它也可以与我们的Active Directory进行通信。

自从我们的网站为公司的另一部分工作以来,编写该向导的人已经开始工作了,而我正试图让某些工作破碎。

系统的简单概述是:

  1. 用户向授权人提交请求,然后授权人接受或拒绝对相关用户的请求授予对文件夹/资源的访问权
  2. 如果授权人接受了请求,则他会打开向导并对其进行授权 - 向IT发送电子邮件以便我们授予访问权限
  3. 在我们授予访问权限后,我们会在向导中勾选一个框,通过电子邮件向用户和授权人发送电子邮件通知他们授予访问权限
  4. 此系统的一部分为文件夹/资源的授权者检查哪些用户有权访问其授权文件夹。这一直运作良好,直到我们更改了文件夹的命名标准:

    旧命名标准 - “BusinessFolderPurpose”,例如“BakerHumanResources” 新的命名标准 - “业务 - 站点 - 服务器位置 - 文件夹目的”,例如“贝克 - 英格兰 - Server123 - 人力资源”

    当用户尝试使用向导中显示他们有权访问的部分时,他们现在正在收到以下错误消息:

      

    Microsoft VBScript运行时错误'800a000d'

         

    类型不匹配:'ubound'

         

    /Saw/list_grp_mem.asp,第18行

    我怀疑问题是新的文件夹命名约定在其中大肆宣传导致了一个问题 - 但是不成功我无法解决这个问题,因此无数次尝试查看它并进行了大量的Google搜索。

    第18行是:

    iRowNumber = ubound(GroupArray,2)
    

    list_grp_mem.asp页面的完整代码是:

    <!--#include file = "database/database.asp"-->
    <%
    
    WriteHTMLHeader("Security Access Wizard")
    VarUser = Request.ServerVariables("AUTH_USER")
    VarUser =(Right(VarUser,(len(VarUser)-instr(VarUser,"\")))) 
    StrGroupName = Request.Form("SecurityGroup")
    
    '-----------------------------------------------------------------------------
    'Generate Group Membership Listing From Group Passed via StrGroupName
    '-----------------------------------------------------------------------------
    If Not IsEmpty(StrGroupName) Then
    
        GroupArray = QueryADGroup("distinguishedName",strGroupName)
        If IsEmpty(GroupArray) Then
            Response.Write "No Group Found"
            Else
                iRowNumber = ubound(GroupArray,2)
                if iRowNumber = 0 Then
                GroupDN =  GroupArray(0,0)
    
                Set RsGroupName = Server.CreateObject("ADODB.RecordSet")
                StrSql = "SELECT Company.Description AS Comp_Desc, SecurityGroups.Description AS Sec_Desc, SecurityGroups.SecurityGroup " & _
                         "FROM Company INNER JOIN SecurityGroups ON Company.Company = SecurityGroups.Company " & _
                         "WHERE SecurityGroups.SecurityGroup = '" & StrGroupName & "'"
                RsGroupName.open StrSql,objConn
                Do While NOT RsGroupName.EOF
                    Response.Write "<h2>Group Membership For: " & RsGroupName("Comp_Desc") & " - " & RsGroupName("Sec_Desc") & "</h2>" & vbcrlf
                    RsGroupName.MoveNext
                Loop
                RsGroupName.Close
                Else
                    Response.Write "No Group Found"
                End If
        End If
    
        arrGrpMem = QueryADUsers("GroupsMembers",GroupDN)
        If IsEmpty(arrGrpMem) Then
            Response.Write "Error Group Not Found"
        Else
            iRowNumber = ubound(arrGrpMem,2)
            If iRowNumber = 0 Then
                Response.Write "Group Currently Has No Members"
            Else
                Response.Write "<table class=" & chr(34) & "Req" & Chr(34) & ">" & vbcrlf
                Response.Write "    <tr>"  & vbcrlf
                Response.Write "        <td class=" & chr(34) & "ReqHead" & Chr(34) & "> Name  </td>" & vbcrlf
                Response.Write "        <td class=" & chr(34) & "ReqHead" & Chr(34) & "> E-Mail </td>" & vbcrlf
                Response.Write "    </tr>"  & vbcrlf
                For iCounter = 0 To iRowNumber
                    If Not IsNull(arrGrpMem(3,iCounter)) Then
                        If Instr(arrGrpMem(3,iCounter),"ZZ") = 0  Then
                            Response.Write "    <tr>"  & vbcrlf
                            Response.Write "        <td class=" & chr(34) & "ReqLeft" & Chr(34) & "> " & arrGrpMem(3,iCounter) & " " & arrGrpMem(4,iCounter) & " </td>" & vbcrlf
                            Response.Write "        <td class=" & chr(34) & "ReqLeft" & Chr(34) & ">(" & arrGrpMem(6,iCounter) & ") </td>" & vbcrlf
                            Response.Write "    </tr>"  & vbcrlf
                        End If
                    End If
                Next
                    Response.Write "</table>" & vbcrlf
            End If
        End If
    End IF
    
    '-----------------------------------------------------------------------------
    'Generate Option Box For Groups For Which User Is A Designated Authoriser
    '-----------------------------------------------------------------------------
    If IsEmpty(StrGroupName) Then   
        Response.Write "<h2> Group Membership Report</h2>" & vbcrlf
        Response.Write "<p><b> Please select the area you require a membership report for</b>" & vbcrlf
        Response.Write "<form action=" & chr(34) & "list_grp_mem.asp" & chr(34) & " method=" & chr(34) & "post" & chr(34) & ">" & vbcrlf
        Response.Write "<select name=" & chr(34) & "SecurityGroup" & Chr(34) & ">"
        Set RsAuthGroups = Server.CreateObject("ADODB.RecordSet")
            StrSql = "SELECT DISTINCT SecurityGroups.SecurityGroup, SecurityGroups.Description AS Sec_Desc ,Authorisation.NTAccount, Company.Type, Company.Description AS Comp_Desc " & _
            "FROM  Company INNER JOIN SecurityGroups ON Company.Company = SecurityGroups.Company INNER JOIN " & _
            "Authorisation ON SecurityGroups.SecurityGroup = dbo.Authorisation.SecurityGroup " & _
            "WHERE     (Company.Type ='1' AND Authorisation.NTAccount = '" & VarUser & "') AND SecurityGroups.Active = 1"
        RsAuthGroups.open StrSql,objConn
        Do While NOT RsAuthGroups.EOF 'Loop through groups and generate form options.
            Response.Write "        <option value=" & chr(34) &  Replace(RsAuthGroups("SecurityGroup")," ","") & chr(34) & "> " & RsAuthGroups("Comp_Desc") & " - " & RsAuthGroups("Sec_Desc") & " </option>"& vbcrlf
            RsAuthGroups.MoveNext
        Loop
        RsAuthGroups.Close
        Response.Write "</select>" & vbcrlf
        Response.Write "<br/><br/>Once you have selected an area please press <b>" & chr(34) & "Next" & chr(34) & "</b></p>" & vbcrlf
        Response.Write "<input type =" & chr(34) & "submit" & chr(34) & "value =" & chr(34) & " Next " & chr(34) & "/>" & vbcrlf
        Response.Write "</p>" & vbcrlf
        Response.Write "</form>" & vbcrlf
    End If
    
    '-----------------------------------------------------------------------------
    ' Display Link Back To Homepage
    '-----------------------------------------------------------------------------
    Response.Write "<hr class=" & Chr(34) & "grey" & chr(34) & "/>" & vbcrlf
    Response.Write "<p>" & vbcrlf
    Response.Write "    <a href=" & chr(34) & "default.asp" & chr(34) & "> Back To Security Access Wizard</a></br>" & vbcrlf
    Response.Write "</p>" & vbcrlf
    
    %>
    
    <%WriteHTMLFooter()%>
    

    编辑:这是一份副本&amp;从Database.asp粘贴QueryADGroup:

    '-----------------------------------------------------------------------------
    ' QueryADGroup Returns An Array 
    '-----------------------------------------------------------------------------
    
    Function QueryADGroup(StrQryType,StrQryValue)
        Set oRootDSE        = GetObject("LDAP://RootDSE")
        sDomainADsPath      = "LDAP://" & oRootDSE.Get("defaultNamingContext")
        Set oRootDSE        = Nothing
        Set oCon            = Server.CreateObject("ADODB.Connection")
        sUser               = "removed"
        sPassword           = "removed"
        oCon.Provider       = "ADsDSOObject"
        oCon.Open "ADProvider", sUser, sPassword
        Set oCmd            = Server.CreateObject("ADODB.Command")
        Set oCmd.ActiveConnection = oCon
        sProperties     = "distinguishedName"
        select case StrQryType
          case "distinguishedName,cn"
            oCmd.CommandText    = "<" & sDomainADsPath & ">;(&(objectCategory=group)(SAMAccountName=" & StrQryValue & "));" & sProperties '& ";subtree"
          case else
            oCmd.CommandText    = "<" & sDomainADsPath & ">;(&(objectCategory=group)(SAMAccountName=" & StrQryValue & "));" & sProperties '& ";subtree"
        end select
        oCmd.Properties("Page Size") = 100
        Set oRecordSet = oCmd.Execute
        If oRecordSet.BOF = True Then
        QueryADGroup = Null
        Else
        QueryADGroup = oRecordSet.GetRows() 
        End If
        oRecordSet.Close
        oCon.Close
    End Function
    

    是否有人能够帮助/协助我尝试找出问题所在?

    我非常感谢任何指针!

    进一步的错误

    No Group Found
    
      

    提供商错误'8007203e'

         

    无法识别搜索过滤器。

         

    /Saw/database/database.asp,第173行

    实施@Lankymart的建议后

    第173行是:

    If oRecordSet.BOF = True Then
    

    这是database.asp的一部分,它试图从AD获取用户:

     '-----------------------------------------------------------------------------
    ' Get Users From Query
    '
    ' Returns 2D Array with user infomation in following format
    '       0,x - User Principle Name
    '       1,x - SAMAccount Name(NTAccount)
    '       2,x - Display Name
    '       3,x - Given Name
    '       4,x - Surname
    '       5,x - Description (For Some Reason Its returned as an array)
    '       6,x - Email
    '       7,x - SID (Binary)
    '       9,x - Distinguised Name
    '       10,x - Job Title
    '       11,x - Company
    '-----------------------------------------------------------------------------'
    Function QueryADUsers(StrQryType,StrQryValue)
    
        Set oRootDSE        = GetObject("LDAP://RootDSE")
        sDomainADsPath      = "LDAP://" & oRootDSE.Get("defaultNamingContext")
        Set oRootDSE        = Nothing
        Set oCon        = Server.CreateObject("ADODB.Connection")
        sUser               = "removed"
        sPassword           = "removed"
        oCon.Provider       = "ADsDSOObject"
        oCon.Open "ADProvider", sUser, sPassword
        Set oCmd        = Server.CreateObject("ADODB.Command")
        Set oCmd.ActiveConnection = oCon
        sProperties     = "userPrincipalName,SAMAccountname,name,givenName,sn,description,mail,objectsid,memberof,distinguishedName,title,company"
        select case StrQryType
          case "Surname"
            oCmd.CommandText    = "<" & sDomainADsPath & ">;(&(objectCategory=user)(sn=" & StrQryValue & "*));" & sProperties '& ";subtree"
          case "SAMAccountName"
            oCmd.CommandText    = "<" & sDomainADsPath & ">;(&(objectCategory=user)(SAMAccountName=" & StrQryValue & "));" & sProperties '& ";subtree"
          case "GroupsMembers"
            oCmd.CommandText    = "<" & sDomainADsPath & ">;(&(objectCategory=user)(MemberOf= " & StrQryValue & " ));" & sProperties '& ";subtree"
          case else
            oCmd.CommandText    = "<" & sDomainADsPath & ">;(&(objectCategory=user)(userPrincipalName=" & StrQryValue & "*));" & sProperties '& ";subtree"
        end select
    
        oCmd.Properties("Page Size") = 100
        Set oRecordSet = oCmd.Execute
        If oRecordSet.BOF = True Then
        QueryADUser = Null
        Else
        'oRecordset.Sort "sn,givenName"
        QueryADUsers = oRecordSet.GetRows() 
        End If
        oRecordSet.Close
        oCon.Close
    End Function
    

1 个答案:

答案 0 :(得分:0)

问题是什么?

当您从IsEmpty()函数返回GroupArray时,问题是使用QueryADGroup()作为验证检查。

这是因为IsEmpty()设计为在满足以下两个条件之一的情况下返回True;

  1. 尚未初始化变量(未分配值)
  2. 变量已明确设置为vbEmpty
  3. 其他任何内容都会返回False甚至分配给Null的变量。

      

    来自MSDN - IsEmpty Function

    的摘录      

    IsEmpty 如果变量未初始化或显式设置为Empty,则返回 True ;否则,它返回 False 。如果表达式包含多个变量,则始终返回 False 。   以下示例使用 IsEmpty 函数来确定变量是否已初始化:

         
    Dim MyVar, MyCheck
    MyCheck = IsEmpty(MyVar)   ' Returns True.
    MyVar = Null               ' Assign Null.
    MyCheck = IsEmpty(MyVar)   ' Returns False.
    MyVar = Empty              ' Assign Empty.
    MyCheck = IsEmpty(MyVar)   ' Returns True.
    

    导致Type mismatch错误的原因是什么?

    通过在QueryADGroup = Null功能中设置QueryADGroup(),您可以绕过IsEmpty()检查,因为它始终为False。这意味着当行

    iRowNumber = ubound(GroupArray,2)
    

    尝试检查Null的上限失败并显示错误

      

    Microsoft VBScript运行时错误'800a000d'

         

    类型不匹配:'ubound'

         

    /Saw/list_grp_mem.asp,第18行

    因为它需要Array而不是Null

    建议的解决方案

    相反,你可以做两件事。

    1. QueryADGroup = Null更改为QueryADGroup = Empty IsEmpty()True现在Empty已明确设置。{/ p>

      QueryADGroup = Empty
      
    2. 使用IsArray()代替IsEmpty()来检查有效的返回值。因为结果始终是Array,这似乎是更好的选择,因为它将捕获任何非有效数组的返回值。

      If Not IsArray(GroupArray) Then
      
    3. 有用的链接