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