Kai Blin : netapi32: Implement NetUserAdd with a dummy user database.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Mar 26 08:12:53 CDT 2007


Module: wine
Branch: master
Commit: 5934c2c9b1794f70d83ca0e7b1b6eeb485fb11b6
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=5934c2c9b1794f70d83ca0e7b1b6eeb485fb11b6

Author: Kai Blin <kai.blin at gmail.com>
Date:   Sat Mar 24 09:01:13 2007 +0100

netapi32: Implement NetUserAdd with a dummy user database.

---

 dlls/netapi32/access.c       |   94 ++++++++++++++++++++++++++++++++++++++---
 dlls/netapi32/tests/access.c |    8 ++--
 2 files changed, 91 insertions(+), 11 deletions(-)

diff --git a/dlls/netapi32/access.c b/dlls/netapi32/access.c
index ce324c7..6d84b40 100644
--- a/dlls/netapi32/access.c
+++ b/dlls/netapi32/access.c
@@ -33,13 +33,37 @@
 #include "ntsecapi.h"
 #include "wine/debug.h"
 #include "wine/unicode.h"
+#include "wine/list.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
 
+/* NOTE: So far, this is implemented to support tests that require user logins,
+ *       but not designed to handle real user databases. Those should probably
+ *       be synced with either the host's user database or with Samba.
+ *
+ * FIXME: The user database should hold all the information the USER_INFO_4 struct
+ * needs, but for the first try, I will just implement the USER_INFO_1 fields.
+ */
+
+struct sam_user
+{
+    struct list entry;
+    WCHAR user_name[LM20_UNLEN+1];
+    WCHAR user_password[PWLEN + 1];
+    DWORD sec_since_passwd_change;
+    DWORD user_priv;
+    LPWSTR home_dir;
+    LPWSTR user_comment;
+    DWORD user_flags;
+    LPWSTR user_logon_script_path;
+};
+
 static const WCHAR sAdminUserName[] = {'A','d','m','i','n','i','s','t','r','a','t',
                                 'o','r',0};
 static const WCHAR sGuestUserName[] = {'G','u','e','s','t',0};
 
+static struct list user_list = LIST_INIT( user_list );
+
 BOOL NETAPI_IsLocalComputer(LPCWSTR ServerName);
 
 /************************************************************
@@ -96,18 +120,74 @@ NET_API_STATUS WINAPI NetUserAdd(LPCWSTR servername,
                   DWORD level, LPBYTE bufptr, LPDWORD parm_err)
 {
     NET_API_STATUS status;
+    struct sam_user * su = NULL;
+
     FIXME("(%s, %d, %p, %p) stub!\n", debugstr_w(servername), level, bufptr, parm_err);
 
-    status = NETAPI_ValidateServername(servername);
-    if (status != NERR_Success)
+    if((status = NETAPI_ValidateServername(servername)) != NERR_Success)
         return status;
-    
-    if ((bufptr != NULL) && (level > 0) && (level <= 4))
+
+    switch(level)
+    {
+    /* Level 3 and 4 are identical for the purposes of NetUserAdd */
+    case 4:
+    case 3:
+        FIXME("Level 3 and 4 not implemented.\n");
+        /* Fall through */
+    case 2:
+        FIXME("Level 2 not implemented.\n");
+        /* Fall throught */
+    case 1:
     {
         PUSER_INFO_1 ui = (PUSER_INFO_1) bufptr;
-        TRACE("usri%d_name: %s\n", level, debugstr_w(ui->usri1_name));
-        TRACE("usri%d_password: %s\n", level, debugstr_w(ui->usri1_password));
-        TRACE("usri%d_comment: %s\n", level, debugstr_w(ui->usri1_comment));
+        su = HeapAlloc(GetProcessHeap(), 0, sizeof(struct sam_user));
+        if(!su)
+        {
+            status = NERR_InternalError;
+            break;
+        }
+
+        if(lstrlenW(ui->usri1_name) > LM20_UNLEN)
+        {
+            status = NERR_BadUsername;
+            break;
+        }
+
+        /*FIXME: do other checks for a valid username */
+        lstrcpyW(su->user_name, ui->usri1_name);
+
+        if(lstrlenW(ui->usri1_password) > PWLEN)
+        {
+            /* Always return PasswordTooShort on invalid passwords. */
+            status = NERR_PasswordTooShort;
+            break;
+        }
+        lstrcpyW(su->user_password, ui->usri1_password);
+
+        su->sec_since_passwd_change = ui->usri1_password_age;
+        su->user_priv = ui->usri1_priv;
+        su->user_flags = ui->usri1_flags;
+
+        /*FIXME: set the other LPWSTRs to NULL for now */
+        su->home_dir = NULL;
+        su->user_comment = NULL;
+        su->user_logon_script_path = NULL;
+
+        list_add_head(&user_list, &su->entry);
+        return NERR_Success;
+    }
+    default:
+        TRACE("Invalid level %d specified.\n", level);
+        status = ERROR_INVALID_LEVEL;
+        break;
+    }
+
+    if(su)
+    {
+        HeapFree(GetProcessHeap(), 0, su->home_dir);
+        HeapFree(GetProcessHeap(), 0, su->user_comment);
+        HeapFree(GetProcessHeap(), 0, su->user_logon_script_path);
+        HeapFree(GetProcessHeap(), 0, su);
     }
     return status;
 }
diff --git a/dlls/netapi32/tests/access.c b/dlls/netapi32/tests/access.c
index 93d7e63..226e3d6 100644
--- a/dlls/netapi32/tests/access.c
+++ b/dlls/netapi32/tests/access.c
@@ -217,26 +217,26 @@ static void run_userhandling_tests(void)
     usri.usri1_password = sTestUserOldPass;
 
     ret = pNetUserAdd(NULL, 1, (LPBYTE)&usri, NULL);
-    todo_wine ok(ret == NERR_BadUsername, "Adding user with too long username returned 0x%08x\n", ret);
+    ok(ret == NERR_BadUsername, "Adding user with too long username returned 0x%08x\n", ret);
 
     usri.usri1_name = sTestUserName;
     usri.usri1_password = sTooLongPassword;
 
     ret = pNetUserAdd(NULL, 1, (LPBYTE)&usri, NULL);
-    todo_wine ok(ret == NERR_PasswordTooShort, "Adding user with too long password returned 0x%08x\n", ret);
+    ok(ret == NERR_PasswordTooShort, "Adding user with too long password returned 0x%08x\n", ret);
 
     usri.usri1_name = sTooLongName;
     usri.usri1_password = sTooLongPassword;
 
     ret = pNetUserAdd(NULL, 1, (LPBYTE)&usri, NULL);
-    todo_wine ok(ret == NERR_BadUsername,
+    ok(ret == NERR_BadUsername,
             "Adding user with too long username/password returned 0x%08x\n", ret);
 
     usri.usri1_name = sTestUserName;
     usri.usri1_password = sTestUserOldPass;
 
     ret = pNetUserAdd(NULL, 5, (LPBYTE)&usri, NULL);
-    todo_wine ok(ret == ERROR_INVALID_LEVEL, "Adding user with level 5 returned 0x%08x\n", ret);
+    ok(ret == ERROR_INVALID_LEVEL, "Adding user with level 5 returned 0x%08x\n", ret);
 
     ret = pNetUserAdd(NULL, 1, (LPBYTE)&usri, NULL);
     if(ret == ERROR_ACCESS_DENIED)




More information about the wine-cvs mailing list