c# - Windows 与 VCE 上的 LDAP 绑定(bind)

标签 c# c++ ldap windows-embedded-compact

我得到了一个简单的任务,即在 C# 应用程序中从 Windows Compact 7 设备对 AD 进行 Windows 身份验证。现在 - 14 天后我仍然在挣扎,所以任何帮助将不胜感激。

无论如何 - 到目前为止我设法想出的是使用 wldap32.dll 在我的 PC 上进行 Windows 身份验证。我远不是 C++ 专家,使用 Visual C++ 更不是,所以请多多包涵。 这是我的 C++ 代码:

EXPORT_METHOD unsigned long Authenticate(char *userName, char *password, char *domain)
{
    unsigned long result = 0;

    unsigned short *uUserName = (unsigned short *)userName;
    unsigned short *uPassword = (unsigned short *)password;
    unsigned short *uDomain = (unsigned short *)domain;

    PWCHAR hostName = NULL;
    LDAP* pLdapConnection = NULL;
    ULONG version = LDAP_VERSION3;

    size_t origsize = strlen("ELLAB.COM") + 1;
    size_t convertedChars = 0;
    wchar_t wcstring[100];
    mbstowcs_s(&convertedChars, wcstring, origsize, "ELLAB.COM", _TRUNCATE);
    wcscat_s(wcstring, L" (wchar_t *)");
    hostName = wcstring;

    //  Initialize a session. LDAP_PORT is the default port, 389.
    pLdapConnection = ldap_init(hostName, LDAP_PORT);

    if (pLdapConnection == NULL)
    {
        #ifdef DEBUG
        AfxMessageBox(_T("Unable to Init"));
        #endif // DEBUG
        result = 0xff;
    }
    else
    {
        //  Set the version to 3.0 (default is 2.0).
        result = ldap_set_option(pLdapConnection, LDAP_OPT_PROTOCOL_VERSION, (void*)&version);
        if (result != LDAP_SUCCESS)
        {
            #ifdef DEBUG
            AfxMessageBox(_T("Unable to Set Optins"));
            #endif // DEBUG
        }
        else
        {
            // Connect to the server.
            result = ldap_connect(pLdapConnection, NULL);
            if (result != LDAP_SUCCESS)
            {
                #ifdef DEBUG
                AfxMessageBox(_T("Unable to Connect"));
                #endif // DEBUG
            }
            else
            {
                //  Be aware that the password itself is never sent over the network, and encryption is not used.
                SEC_WINNT_AUTH_IDENTITY NtAuthIdentity;
                ZeroMemory(&NtAuthIdentity, sizeof(NtAuthIdentity));
                NtAuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;

                NtAuthIdentity.Domain = uDomain;
                NtAuthIdentity.DomainLength = sizeof(uDomain);
                NtAuthIdentity.User = uUserName;
                NtAuthIdentity.UserLength = sizeof(uUserName);
                NtAuthIdentity.Password = uPassword;
                NtAuthIdentity.PasswordLength = sizeof(uPassword);

                //if (ldap_bind_s(pLdapConnection, NULL, NULL, LDAP_AUTH_NEGOTIATE) == LDAP_SUCCESS)
                result = ldap_bind_s(pLdapConnection, NULL, (PWCHAR)&NtAuthIdentity, LDAP_AUTH_NTLM);
                //if (result != LDAP_SUCCESS)
                {
                    #ifdef DEBUG
                    AfxMessageBox(_T("Unable to Bind using ldap_bind_s"));
                    #endif // DEBUG
                    result = ldap_bind(pLdapConnection, NULL, (PWCHAR)&NtAuthIdentity, LDAP_AUTH_NTLM);
                    if (result != LDAP_SUCCESS)
                    {
                        #ifdef DEBUG
                        AfxMessageBox(_T("Unable to Bind using ldap_bind"));
                        #endif // DEBUG
                    }
                }
            }

        }
        //  Normal cleanup and exit.
        ldap_unbind(pLdapConnection);
    }

    return result;
}

还有我的 C# 示例包装器:

[DllImport(@"C:\Users\ckbn.ELLAB\Documents\Visual Studio 2015\Projects\WCE7_LDAP\Debug\LDAPHandler.dll", CharSet = CharSet.Unicode)]
    public static extern int Authenticate(string userName, string password, string domain);

    private void buttonAuthenticate_Click(object sender, EventArgs e)
    {
        try
        {
            textBoxResult.Text = "";
            LDAPReturns result = (LDAPReturns)Authenticate(textBoxUserName.Text, textBoxPassword.Text, textBoxDomain.Text);
            switch (result)
            {
                case LDAPReturns.LDAP_SUCCESS:
                    textBoxResult.Text = "User '" + textBoxUserName.Text + "' is authenticated";
                    break;
                default:
                    textBoxResult.Text = result.ToString();
                    break;
            }
        }
        catch (Exception ex) { textBoxResult.Text = "Failed: " + ex.ToString(); }
    }

所以 - 使用上面的代码,我可以在我的 PC 上使用我自己的凭据进行身份验证。在 WCE 设备上运行相同的代码,我可以连接到 AD 服务器,但是当我尝试 ldap_bind_s 时,它返回 LDAP_AUTH_METHOD_NOT_SUPPORTED。所以我认为 wldap32.dll 的 ARM 版本与 x86 版本不同。

然后我尝试使用 ldap_bind(不带‘_s’)方法。这在我的 PC 和 WCE 设备上都无法正常工作,并且总是返回 0xFFFF_FFFF。

所以基本上我的问题是:

LDAP_AUTH_METHOD_NOT_SUPPORTED 是什么意思,我在 WCE7 设备上还有哪些其他方法?和

ldap_bind 返回 0xFFFF_FFFF 是什么意思?

但是,我们将不胜感激任何意见或建议。提前致谢!

最佳答案

您的 WEC7 设备供应商是否在操作系统构建中包含 LDAP 功能?

或者,如果供应商是您,您是否在 Platform Builder 项目中指定了 SYSGEN_LDAP?

如果您有权访问该文件,请尝试检查设备的\Windows 目录中的 ceconfig.h 文件。

关于c# - Windows 与 VCE 上的 LDAP 绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43113502/

相关文章:

c# - MVC 5 : How Does Application_PostAuthenticateRequest() get called in Global. asax?

c++ - 为什么要考虑缓冲区而不是行? fgets() 可以一次读取多行吗?

python - 如何使用 Python 将用户添加到 LDAP 组?

c# - 在父类(super class)列表中查找子类成员。 C#

c# - 重定向到另一个页面时 session 始终为空? C#

c++ - C++ reference_wrapper vector 使用错误的值填充

c++ - GCC 共享库问题

c - ldap_search_ext 返回额外结果

ruby-on-rails - 使用具有两个 Devise 用户模型和不同身份验证方法的登录表单

c# - 将 Twilio 的字符串转换为 "URL Safe"字符串