diff --git a/dlls/netapi32/netapi32.c b/dlls/netapi32/netapi32.c index 62c4ba138ac..44d23a602c7 100644 --- a/dlls/netapi32/netapi32.c +++ b/dlls/netapi32/netapi32.c @@ -25,14 +25,6 @@ #include "wine/port.h" #include -#include -#include -#ifdef HAVE_SYS_WAIT_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif #include "ntstatus.h" #define WIN32_NO_STATUS @@ -68,60 +60,6 @@ DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); static HINSTANCE netapi32_instance; -static CPTABLEINFO unix_cptable; -static ULONG unix_cp; - -static BOOL get_unix_codepage(void) -{ - static const WCHAR wineunixcpW[] = {'W','I','N','E','U','N','I','X','C','P',0}; - UNICODE_STRING name, value; - WCHAR value_buffer[13]; - SIZE_T size; - void *ptr; - - if (unix_cp) return TRUE; - - RtlInitUnicodeString( &name, wineunixcpW ); - value.Buffer = value_buffer; - value.MaximumLength = sizeof(value_buffer); - if (!RtlQueryEnvironmentVariable_U( NULL, &name, &value )) - RtlUnicodeStringToInteger( &value, 10, &unix_cp ); - if (NtGetNlsSectionPtr( 11, unix_cp, NULL, &ptr, &size )) - return FALSE; - RtlInitCodePageTable( ptr, &unix_cptable ); - return TRUE; -} - -static DWORD netapi_wcstoumbs( const WCHAR *src, char *dst, DWORD dstlen ) -{ - DWORD srclen = (strlenW( src ) + 1) * sizeof(WCHAR); - DWORD len; - - get_unix_codepage(); - - if (unix_cp == CP_UTF8) - { - RtlUnicodeToUTF8N( dst, dstlen, &len, src, srclen ); - return len; - } - else - { - len = (strlenW( src ) * 2) + 1; - if (dst) RtlUnicodeToCustomCPN( &unix_cptable, dst, dstlen, &len, src, srclen ); - return len; - } -} - -static char *strdup_unixcp( const WCHAR *str ) -{ - char *ret; - - int len = netapi_wcstoumbs( str, NULL, 0 ); - if ((ret = HeapAlloc( GetProcessHeap(), 0, len ))) - netapi_wcstoumbs( str, ret, len ); - return ret; -} - static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT; static const struct samba_funcs *samba_funcs; @@ -2087,101 +2025,6 @@ NET_API_STATUS WINAPI NetUserModalsGet( return NERR_Success; } -static NET_API_STATUS change_password_smb( LPCWSTR domainname, LPCWSTR username, - LPCWSTR oldpassword, LPCWSTR newpassword ) -{ -#ifdef HAVE_FORK - NET_API_STATUS ret = NERR_Success; - static char option_silent[] = "-s"; - static char option_user[] = "-U"; - static char option_remote[] = "-r"; - static char smbpasswd[] = "smbpasswd"; - int pipe_out[2]; - pid_t pid, wret; - int status; - char *server = NULL, *user, *argv[7], *old = NULL, *new = NULL; - - if (domainname && !(server = strdup_unixcp( domainname ))) return ERROR_OUTOFMEMORY; - if (!(user = strdup_unixcp( username ))) - { - ret = ERROR_OUTOFMEMORY; - goto end; - } - if (!(old = strdup_unixcp( oldpassword ))) - { - ret = ERROR_OUTOFMEMORY; - goto end; - } - if (!(new = strdup_unixcp( newpassword ))) - { - ret = ERROR_OUTOFMEMORY; - goto end; - } - argv[0] = smbpasswd; - argv[1] = option_silent; - argv[2] = option_user; - argv[3] = user; - if (server) - { - argv[4] = option_remote; - argv[5] = server; - argv[6] = NULL; - } - else argv[4] = NULL; - - if (pipe( pipe_out ) == -1) - { - ret = NERR_InternalError; - goto end; - } - fcntl( pipe_out[0], F_SETFD, FD_CLOEXEC ); - fcntl( pipe_out[1], F_SETFD, FD_CLOEXEC ); - - switch ((pid = fork())) - { - case -1: - close( pipe_out[0] ); - close( pipe_out[1] ); - ret = NERR_InternalError; - goto end; - case 0: - dup2( pipe_out[0], 0 ); - close( pipe_out[0] ); - close( pipe_out[1] ); - execvp( "smbpasswd", argv ); - ERR( "can't execute smbpasswd, is it installed?\n" ); - _exit(1); - default: - close( pipe_out[0] ); - break; - } - write( pipe_out[1], old, strlen( old ) ); - write( pipe_out[1], "\n", 1 ); - write( pipe_out[1], new, strlen( new ) ); - write( pipe_out[1], "\n", 1 ); - write( pipe_out[1], new, strlen( new ) ); - write( pipe_out[1], "\n", 1 ); - close( pipe_out[1] ); - - do { - wret = waitpid(pid, &status, 0); - } while (wret < 0 && errno == EINTR); - - if (ret == NERR_Success && (wret < 0 || !WIFEXITED(status) || WEXITSTATUS(status))) - ret = NERR_InternalError; - -end: - HeapFree( GetProcessHeap(), 0, server ); - HeapFree( GetProcessHeap(), 0, user ); - HeapFree( GetProcessHeap(), 0, old ); - HeapFree( GetProcessHeap(), 0, new ); - return ret; -#else - ERR( "no fork support on this platform\n" ); - return NERR_InternalError; -#endif -} - /****************************************************************************** * NetUserChangePassword (NETAPI32.@) * PARAMS @@ -2204,7 +2047,9 @@ NET_API_STATUS WINAPI NetUserChangePassword(LPCWSTR domainname, LPCWSTR username TRACE("(%s, %s, ..., ...)\n", debugstr_w(domainname), debugstr_w(username)); - if (!change_password_smb( domainname, username, oldpassword, newpassword )) + if (!samba_init()) return ERROR_DLL_INIT_FAILED; + + if (!samba_funcs->change_password( domainname, username, oldpassword, newpassword )) return NERR_Success; if(domainname) diff --git a/dlls/netapi32/unixlib.c b/dlls/netapi32/unixlib.c index 3610abe2bde..1506e616c06 100644 --- a/dlls/netapi32/unixlib.c +++ b/dlls/netapi32/unixlib.c @@ -27,6 +27,14 @@ #include "wine/port.h" #include +#include +#include +#ifdef HAVE_SYS_WAIT_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif #include "ntstatus.h" #define WIN32_NO_STATUS @@ -949,12 +957,103 @@ static void libnetapi_init(void) #endif /* SONAME_LIBNETAPI */ +static NET_API_STATUS WINAPI change_password( const WCHAR *domainname, const WCHAR *username, + const WCHAR *oldpassword, const WCHAR *newpassword ) +{ + NET_API_STATUS ret = NERR_Success; + static char option_silent[] = "-s"; + static char option_user[] = "-U"; + static char option_remote[] = "-r"; + static char smbpasswd[] = "smbpasswd"; + int pipe_out[2]; + pid_t pid, wret; + int status; + char *server = NULL, *user, *argv[7], *old = NULL, *new = NULL; + + if (domainname && !(server = strdup_unixcp( domainname ))) return ERROR_OUTOFMEMORY; + if (!(user = strdup_unixcp( username ))) + { + ret = ERROR_OUTOFMEMORY; + goto end; + } + if (!(old = strdup_unixcp( oldpassword ))) + { + ret = ERROR_OUTOFMEMORY; + goto end; + } + if (!(new = strdup_unixcp( newpassword ))) + { + ret = ERROR_OUTOFMEMORY; + goto end; + } + argv[0] = smbpasswd; + argv[1] = option_silent; + argv[2] = option_user; + argv[3] = user; + if (server) + { + argv[4] = option_remote; + argv[5] = server; + argv[6] = NULL; + } + else argv[4] = NULL; + + if (pipe( pipe_out ) == -1) + { + ret = NERR_InternalError; + goto end; + } + fcntl( pipe_out[0], F_SETFD, FD_CLOEXEC ); + fcntl( pipe_out[1], F_SETFD, FD_CLOEXEC ); + + switch ((pid = fork())) + { + case -1: + close( pipe_out[0] ); + close( pipe_out[1] ); + ret = NERR_InternalError; + goto end; + case 0: + dup2( pipe_out[0], 0 ); + close( pipe_out[0] ); + close( pipe_out[1] ); + execvp( "smbpasswd", argv ); + ERR( "can't execute smbpasswd, is it installed?\n" ); + _exit(1); + default: + close( pipe_out[0] ); + break; + } + write( pipe_out[1], old, strlen( old ) ); + write( pipe_out[1], "\n", 1 ); + write( pipe_out[1], new, strlen( new ) ); + write( pipe_out[1], "\n", 1 ); + write( pipe_out[1], new, strlen( new ) ); + write( pipe_out[1], "\n", 1 ); + close( pipe_out[1] ); + + do { + wret = waitpid(pid, &status, 0); + } while (wret < 0 && errno == EINTR); + + if (ret == NERR_Success && (wret < 0 || !WIFEXITED(status) || WEXITSTATUS(status))) + ret = NERR_InternalError; + +end: + RtlFreeHeap( GetProcessHeap(), 0, server ); + RtlFreeHeap( GetProcessHeap(), 0, user ); + RtlFreeHeap( GetProcessHeap(), 0, old ); + RtlFreeHeap( GetProcessHeap(), 0, new ); + return ret; +} + static const struct samba_funcs samba_funcs = { server_getinfo, share_add, share_del, wksta_getinfo, + change_password, }; NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out ) diff --git a/dlls/netapi32/unixlib.h b/dlls/netapi32/unixlib.h index 9e84c035965..d5f18044bb5 100644 --- a/dlls/netapi32/unixlib.h +++ b/dlls/netapi32/unixlib.h @@ -24,4 +24,6 @@ struct samba_funcs NET_API_STATUS (WINAPI *share_add)( const WCHAR *server, DWORD level, const BYTE *buffer, DWORD *err ); NET_API_STATUS (WINAPI *share_del)( const WCHAR *server, const WCHAR *share, DWORD reserved ); NET_API_STATUS (WINAPI *wksta_getinfo)( const WCHAR *server, DWORD level, BYTE **buffer ); + NET_API_STATUS (WINAPI *change_password)( const WCHAR *domain, const WCHAR *user, + const WCHAR *old, const WCHAR *new ); };