Hans Leidekker : msv1_0: Implement SpAcquireCredentialsHandle and SpFreeCredentialsHandle.

Alexandre Julliard julliard at winehq.org
Thu Apr 29 16:38:31 CDT 2021


Module: wine
Branch: master
Commit: e73932e08d0d587329ec15abca9a3d6f89070200
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=e73932e08d0d587329ec15abca9a3d6f89070200

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Thu Apr 29 12:47:32 2021 +0200

msv1_0: Implement SpAcquireCredentialsHandle and SpFreeCredentialsHandle.

Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msv1_0/main.c | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 168 insertions(+), 2 deletions(-)

diff --git a/dlls/msv1_0/main.c b/dlls/msv1_0/main.c
index 1b143ebf3bd..7dabd8e2ff5 100644
--- a/dlls/msv1_0/main.c
+++ b/dlls/msv1_0/main.c
@@ -18,6 +18,7 @@
  */
 
 #include <stdarg.h>
+#include <stdlib.h>
 #include "ntstatus.h"
 #define WIN32_NO_STATUS
 #include "windef.h"
@@ -29,6 +30,7 @@
 #include "rpc.h"
 
 #include "wine/debug.h"
+#include "unixlib.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ntlm);
 
@@ -68,6 +70,12 @@ static inline const char *debugstr_as( const STRING *str )
     return debugstr_an( str->Buffer, str->Length );
 }
 
+static inline const char *debugstr_us( const UNICODE_STRING *str )
+{
+    if (!str) return "<null>";
+    return debugstr_wn( str->Buffer, str->Length / sizeof(WCHAR) );
+}
+
 static NTSTATUS NTAPI ntlm_LsaApInitializePackage( ULONG package_id, LSA_DISPATCH_TABLE *dispatch,
                                                    LSA_STRING *database, LSA_STRING *confidentiality,
                                                    LSA_STRING **package_name )
@@ -116,6 +124,164 @@ static NTSTATUS NTAPI ntlm_SpGetInfo( SecPkgInfoW *info )
     return STATUS_SUCCESS;
 }
 
+static char *get_username_arg( const WCHAR *user, int user_len )
+{
+    static const char arg[] = "--username=";
+    int len = sizeof(arg);
+    char *ret;
+
+    len += WideCharToMultiByte( CP_UNIXCP, WC_NO_BEST_FIT_CHARS, user, user_len, NULL, 0, NULL, NULL );
+    if (!(ret = malloc( len ))) return NULL;
+    memcpy( ret, arg, sizeof(arg) - 1 );
+    WideCharToMultiByte( CP_UNIXCP, WC_NO_BEST_FIT_CHARS, user, user_len, ret + sizeof(arg) - 1,
+                         len - sizeof(arg) + 1, NULL, NULL );
+    ret[len - 1] = 0;
+    return ret;
+}
+
+static char *get_domain_arg( const WCHAR *domain, int domain_len )
+{
+    static const char arg[] = "--domain=";
+    int len = sizeof(arg);
+    char *ret;
+
+    len += WideCharToMultiByte( CP_UNIXCP, WC_NO_BEST_FIT_CHARS, domain, domain_len, NULL, 0, NULL, NULL );
+    if (!(ret = malloc( len ))) return NULL;
+    memcpy( ret, arg, sizeof(arg) - 1 );
+    WideCharToMultiByte( CP_UNIXCP, WC_NO_BEST_FIT_CHARS, domain, domain_len, ret + sizeof(arg) - 1,
+                         len - sizeof(arg) + 1, NULL, NULL );
+    ret[len - 1] = 0;
+    return ret;
+}
+
+static NTSTATUS NTAPI ntlm_SpAcquireCredentialsHandle( UNICODE_STRING *principal, ULONG cred_use, LUID *logon_id,
+                                                       void *auth_data, void *get_key_fn, void *get_key_arg,
+                                                       LSA_SEC_HANDLE *handle, TimeStamp *expiry )
+{
+    SECURITY_STATUS status = SEC_E_INSUFFICIENT_MEMORY;
+    struct ntlm_cred *cred = NULL;
+    WCHAR *domain = NULL, *user = NULL, *password = NULL;
+    SEC_WINNT_AUTH_IDENTITY_W *id = NULL;
+
+    TRACE( "%s, 0x%08x, %p, %p, %p, %p, %p, %p\n", debugstr_us(principal), cred_use, logon_id, auth_data,
+           get_key_fn, get_key_arg, cred, expiry );
+
+    switch (cred_use)
+    {
+    case SECPKG_CRED_INBOUND:
+        if (!(cred = malloc( sizeof(*cred) ))) return SEC_E_INSUFFICIENT_MEMORY;
+        cred->mode         = MODE_SERVER;
+        cred->username_arg = NULL;
+        cred->domain_arg   = NULL;
+        cred->password     = NULL;
+        cred->password_len = 0;
+        cred->no_cached_credentials = 0;
+
+        *handle = (LSA_SEC_HANDLE)cred;
+        status = SEC_E_OK;
+        break;
+
+    case SECPKG_CRED_OUTBOUND:
+        if (!(cred = malloc( sizeof(*cred) ))) return SEC_E_INSUFFICIENT_MEMORY;
+
+        cred->mode         = MODE_CLIENT;
+        cred->username_arg = NULL;
+        cred->domain_arg   = NULL;
+        cred->password     = NULL;
+        cred->password_len = 0;
+        cred->no_cached_credentials = 0;
+
+        if ((id = auth_data))
+        {
+            int domain_len = 0, user_len = 0, password_len = 0;
+            if (id->Flags & SEC_WINNT_AUTH_IDENTITY_ANSI)
+            {
+                if (id->DomainLength)
+                {
+                    domain_len = MultiByteToWideChar( CP_ACP, 0, (char *)id->Domain, id->DomainLength, NULL, 0 );
+                    if (!(domain = malloc( sizeof(WCHAR) * domain_len ))) goto done;
+                    MultiByteToWideChar( CP_ACP, 0, (char *)id->Domain, id->DomainLength, domain, domain_len );
+                }
+                if (id->UserLength)
+               {
+                    user_len = MultiByteToWideChar( CP_ACP, 0, (char *)id->User, id->UserLength, NULL, 0 );
+                    if (!(user = malloc( sizeof(WCHAR) * user_len ))) goto done;
+                    MultiByteToWideChar( CP_ACP, 0, (char *)id->User, id->UserLength, user, user_len );
+                }
+                if (id->PasswordLength)
+                {
+                    password_len = MultiByteToWideChar( CP_ACP, 0,(char *)id->Password, id->PasswordLength, NULL, 0 );
+                    if (!(password = malloc( sizeof(WCHAR) * password_len ))) goto done;
+                    MultiByteToWideChar( CP_ACP, 0, (char *)id->Password, id->PasswordLength, password, password_len );
+                }
+            }
+            else
+            {
+                domain = id->Domain;
+                domain_len = id->DomainLength;
+                user = id->User;
+                user_len = id->UserLength;
+                password = id->Password;
+                password_len = id->PasswordLength;
+            }
+
+            TRACE( "username is %s\n", debugstr_wn(user, user_len) );
+            TRACE( "domain name is %s\n", debugstr_wn(domain, domain_len) );
+
+            cred->username_arg = get_username_arg( user, user_len );
+            cred->domain_arg   = get_domain_arg( domain, domain_len );
+            if (password_len)
+            {
+                cred->password_len = WideCharToMultiByte( CP_UNIXCP, WC_NO_BEST_FIT_CHARS, password, password_len,
+                                                          NULL, 0, NULL, NULL );
+                if (!(cred->password = malloc( cred->password_len ))) goto done;
+                WideCharToMultiByte( CP_UNIXCP, WC_NO_BEST_FIT_CHARS, password, password_len, cred->password,
+                                     cred->password_len, NULL, NULL );
+            }
+        }
+
+        *handle = (LSA_SEC_HANDLE)cred;
+        status = SEC_E_OK;
+        break;
+
+    case SECPKG_CRED_BOTH:
+        FIXME( "SECPKG_CRED_BOTH not supported\n" );
+        status = SEC_E_UNSUPPORTED_FUNCTION;
+        break;
+
+    default:
+        status = SEC_E_UNKNOWN_CREDENTIALS;
+        break;
+    }
+
+done:
+    if (id && (id->Flags & SEC_WINNT_AUTH_IDENTITY_ANSI))
+    {
+        free( domain );
+        free( user );
+        free( password );
+    }
+    if (status != SEC_E_OK) free( cred );
+    return status;
+}
+
+static NTSTATUS NTAPI ntlm_SpFreeCredentialsHandle( LSA_SEC_HANDLE handle )
+{
+    struct ntlm_cred *cred = (struct ntlm_cred *)handle;
+
+    TRACE( "%lx\n", handle );
+
+    if (!cred) return SEC_E_OK;
+
+    cred->mode = MODE_INVALID;
+    if (cred->password) memset( cred->password, 0, cred->password_len );
+    free( cred->password );
+    free( cred->username_arg );
+    free( cred->domain_arg );
+    free( cred );
+    return SEC_E_OK;
+}
+
 static SECPKG_FUNCTION_TABLE ntlm_table =
 {
     ntlm_LsaApInitializePackage,
@@ -130,9 +296,9 @@ static SECPKG_FUNCTION_TABLE ntlm_table =
     NULL, /* SpShutdown */
     ntlm_SpGetInfo,
     NULL, /* AcceptCredentials */
-    NULL, /* SpAcquireCredentialsHandle */
+    ntlm_SpAcquireCredentialsHandle,
     NULL, /* SpQueryCredentialsAttributes */
-    NULL, /* SpFreeCredentialsHandle */
+    ntlm_SpFreeCredentialsHandle,
     NULL, /* SaveCredentials */
     NULL, /* GetCredentials */
     NULL, /* DeleteCredentials */




More information about the wine-cvs mailing list