2010-05-07 17:45:23 +04:00
/*
Unix SMB / CIFS implementation .
test suite for RAP sam operations
2011-03-18 00:18:43 +03:00
Copyright ( C ) Guenther Deschner 2010 - 2011
2010-05-07 17:45:23 +04:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include "libcli/libcli.h"
# include "torture/torture.h"
# include "torture/util.h"
# include "torture/smbtorture.h"
# include "torture/util.h"
2011-03-15 19:28:51 +03:00
# include "libcli/rap/rap.h"
2010-05-07 17:45:23 +04:00
# include "torture/rap/proto.h"
# include "../lib/crypto/crypto.h"
# include "../libcli/auth/libcli_auth.h"
2010-05-12 02:18:42 +04:00
# include "torture/rpc/torture_rpc.h"
2010-05-07 17:45:23 +04:00
2010-05-12 02:18:42 +04:00
# define TEST_RAP_USER "torture_rap_user"
static char * samr_rand_pass ( TALLOC_CTX * mem_ctx , int min_len )
{
size_t len = MAX ( 8 , min_len ) ;
char * s = generate_random_password ( mem_ctx , len , len + 6 ) ;
printf ( " Generated password '%s' \n " , s ) ;
return s ;
}
static bool test_userpasswordset2_args ( struct torture_context * tctx ,
struct smbcli_state * cli ,
const char * username ,
const char * * password )
2010-05-07 17:45:23 +04:00
{
struct rap_NetUserPasswordSet2 r ;
2010-05-12 02:18:42 +04:00
char * newpass = samr_rand_pass ( tctx , 8 ) ;
2010-05-07 17:45:23 +04:00
2010-05-21 20:05:48 +04:00
ZERO_STRUCT ( r ) ;
2010-05-12 02:18:42 +04:00
r . in . UserName = username ;
2010-05-21 20:05:48 +04:00
memcpy ( r . in . OldPassword , * password , MIN ( strlen ( * password ) , 16 ) ) ;
memcpy ( r . in . NewPassword , newpass , MIN ( strlen ( newpass ) , 16 ) ) ;
2010-05-07 17:45:23 +04:00
r . in . EncryptedPassword = 0 ;
2010-05-21 20:05:48 +04:00
r . in . RealPasswordLength = strlen ( newpass ) ;
torture_comment ( tctx , " Testing rap_NetUserPasswordSet2(%s) \n " , r . in . UserName ) ;
torture_assert_ntstatus_ok ( tctx ,
2011-03-15 19:40:39 +03:00
smbcli_rap_netuserpasswordset2 ( cli - > tree , tctx , & r ) ,
2010-05-21 20:05:48 +04:00
" smbcli_rap_netuserpasswordset2 failed " ) ;
if ( ! W_ERROR_IS_OK ( W_ERROR ( r . out . status ) ) ) {
torture_warning ( tctx , " RAP NetUserPasswordSet2 gave: %s \n " ,
win_errstr ( W_ERROR ( r . out . status ) ) ) ;
} else {
* password = newpass ;
}
return true ;
}
static bool test_userpasswordset2_crypt_args ( struct torture_context * tctx ,
struct smbcli_state * cli ,
const char * username ,
const char * * password )
{
struct rap_NetUserPasswordSet2 r ;
char * newpass = samr_rand_pass ( tctx , 8 ) ;
r . in . UserName = username ;
E_deshash ( * password , r . in . OldPassword ) ;
E_deshash ( newpass , r . in . NewPassword ) ;
r . in . RealPasswordLength = strlen ( newpass ) ;
r . in . EncryptedPassword = 1 ;
2010-05-07 17:45:23 +04:00
torture_comment ( tctx , " Testing rap_NetUserPasswordSet2(%s) \n " , r . in . UserName ) ;
torture_assert_ntstatus_ok ( tctx ,
2011-03-15 19:40:39 +03:00
smbcli_rap_netuserpasswordset2 ( cli - > tree , tctx , & r ) ,
2010-05-07 17:45:23 +04:00
" smbcli_rap_netuserpasswordset2 failed " ) ;
2010-05-12 02:18:42 +04:00
if ( ! W_ERROR_IS_OK ( W_ERROR ( r . out . status ) ) ) {
torture_warning ( tctx , " RAP NetUserPasswordSet2 gave: %s \n " ,
win_errstr ( W_ERROR ( r . out . status ) ) ) ;
} else {
* password = newpass ;
}
2010-05-07 17:45:23 +04:00
return true ;
}
2010-05-12 02:18:42 +04:00
static bool test_userpasswordset2 ( struct torture_context * tctx ,
struct smbcli_state * cli )
{
struct test_join * join_ctx ;
const char * password ;
2010-05-21 20:05:48 +04:00
bool ret = true ;
2010-05-12 02:18:42 +04:00
join_ctx = torture_create_testuser_max_pwlen ( tctx , TEST_RAP_USER ,
torture_setting_string ( tctx , " workgroup " , NULL ) ,
ACB_NORMAL ,
& password , 14 ) ;
if ( join_ctx = = NULL ) {
torture_fail ( tctx , " failed to create user \n " ) ;
}
2010-05-21 20:05:48 +04:00
ret & = test_userpasswordset2_args ( tctx , cli , TEST_RAP_USER , & password ) ;
ret & = test_userpasswordset2_crypt_args ( tctx , cli , TEST_RAP_USER , & password ) ;
2010-05-12 02:18:42 +04:00
torture_leave_domain ( tctx , join_ctx ) ;
return ret ;
}
static bool test_oemchangepassword_args ( struct torture_context * tctx ,
struct smbcli_state * cli ,
const char * username ,
const char * * password )
2010-05-08 00:58:42 +04:00
{
struct rap_NetOEMChangePassword r ;
2010-05-12 02:18:42 +04:00
const char * oldpass = * password ;
char * newpass = samr_rand_pass ( tctx , 9 ) ;
2010-05-08 00:58:42 +04:00
uint8_t old_pw_hash [ 16 ] ;
uint8_t new_pw_hash [ 16 ] ;
2010-05-12 02:18:42 +04:00
r . in . UserName = username ;
2010-05-08 00:58:42 +04:00
E_deshash ( oldpass , old_pw_hash ) ;
E_deshash ( newpass , new_pw_hash ) ;
encode_pw_buffer ( r . in . crypt_password , newpass , STR_ASCII ) ;
arcfour_crypt ( r . in . crypt_password , old_pw_hash , 516 ) ;
E_old_pw_hash ( new_pw_hash , old_pw_hash , r . in . password_hash ) ;
torture_comment ( tctx , " Testing rap_NetOEMChangePassword(%s) \n " , r . in . UserName ) ;
torture_assert_ntstatus_ok ( tctx ,
2011-03-15 19:40:39 +03:00
smbcli_rap_netoemchangepassword ( cli - > tree , tctx , & r ) ,
2010-05-08 00:58:42 +04:00
" smbcli_rap_netoemchangepassword failed " ) ;
2010-05-12 02:18:42 +04:00
if ( ! W_ERROR_IS_OK ( W_ERROR ( r . out . status ) ) ) {
torture_warning ( tctx , " RAP NetOEMChangePassword gave: %s \n " ,
win_errstr ( W_ERROR ( r . out . status ) ) ) ;
} else {
* password = newpass ;
}
2010-05-08 00:58:42 +04:00
return true ;
}
2010-05-12 02:18:42 +04:00
static bool test_oemchangepassword ( struct torture_context * tctx ,
struct smbcli_state * cli )
{
struct test_join * join_ctx ;
const char * password ;
bool ret ;
join_ctx = torture_create_testuser_max_pwlen ( tctx , TEST_RAP_USER ,
torture_setting_string ( tctx , " workgroup " , NULL ) ,
ACB_NORMAL ,
& password , 14 ) ;
if ( join_ctx = = NULL ) {
torture_fail ( tctx , " failed to create user \n " ) ;
}
ret = test_oemchangepassword_args ( tctx , cli , TEST_RAP_USER , & password ) ;
torture_leave_domain ( tctx , join_ctx ) ;
return ret ;
}
2010-05-27 15:25:31 +04:00
static bool test_usergetinfo_byname ( struct torture_context * tctx ,
struct smbcli_state * cli ,
const char * UserName )
2010-05-26 23:22:13 +04:00
{
struct rap_NetUserGetInfo r ;
int i ;
2010-05-27 18:10:10 +04:00
uint16_t levels [ ] = { 0 , 1 , 2 , 10 , 11 } ;
2010-05-26 23:22:13 +04:00
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
2010-05-27 15:25:31 +04:00
r . in . UserName = UserName ;
2010-05-26 23:22:13 +04:00
r . in . level = levels [ i ] ;
r . in . bufsize = 8192 ;
torture_comment ( tctx ,
" Testing rap_NetUserGetInfo(%s) level %d \n " , r . in . UserName , r . in . level ) ;
torture_assert_ntstatus_ok ( tctx ,
smbcli_rap_netusergetinfo ( cli - > tree , tctx , & r ) ,
" smbcli_rap_netusergetinfo failed " ) ;
2010-06-04 21:05:24 +04:00
torture_assert_werr_ok ( tctx , W_ERROR ( r . out . status ) ,
" smbcli_rap_netusergetinfo failed " ) ;
2010-05-26 23:22:13 +04:00
}
return true ;
}
2010-05-27 15:25:31 +04:00
static bool test_usergetinfo ( struct torture_context * tctx ,
struct smbcli_state * cli )
{
struct test_join * join_ctx ;
const char * password ;
bool ret ;
join_ctx = torture_create_testuser_max_pwlen ( tctx , TEST_RAP_USER ,
torture_setting_string ( tctx , " workgroup " , NULL ) ,
ACB_NORMAL ,
& password , 14 ) ;
if ( join_ctx = = NULL ) {
torture_fail ( tctx , " failed to create user \n " ) ;
}
ret = test_usergetinfo_byname ( tctx , cli , TEST_RAP_USER ) ;
torture_leave_domain ( tctx , join_ctx ) ;
return ret ;
}
2011-03-18 00:18:43 +03:00
static bool test_useradd ( struct torture_context * tctx ,
struct smbcli_state * cli )
{
struct rap_NetUserAdd r ;
struct rap_NetUserInfo1 info1 ;
int i ;
uint16_t levels [ ] = { 1 } ;
const char * username = TEST_RAP_USER ;
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
const char * pwd ;
pwd = generate_random_password ( tctx , 9 , 16 ) ;
r . in . level = levels [ i ] ;
r . in . bufsize = 0xffff ;
r . in . pwdlength = strlen ( pwd ) ;
r . in . unknown = 0 ;
switch ( r . in . level ) {
case 1 :
ZERO_STRUCT ( info1 ) ;
info1 . Name = username ;
memcpy ( info1 . Password , pwd , MIN ( strlen ( pwd ) , 16 ) ) ;
info1 . Priv = USER_PRIV_USER ;
info1 . Flags = 0x21 ;
info1 . HomeDir = " home_dir " ;
info1 . Comment = " comment " ;
info1 . ScriptPath = " logon_script " ;
r . in . info . info1 = info1 ;
break ;
}
torture_comment ( tctx ,
" Testing rap_NetUserAdd(%s) level %d \n " , username , r . in . level ) ;
torture_assert_ntstatus_ok ( tctx ,
smbcli_rap_netuseradd ( cli - > tree , tctx , & r ) ,
" smbcli_rap_netuseradd failed " ) ;
torture_assert_werr_ok ( tctx , W_ERROR ( r . out . status ) ,
" smbcli_rap_netuseradd failed " ) ;
torture_assert_ntstatus_ok ( tctx ,
smbcli_rap_netuseradd ( cli - > tree , tctx , & r ) ,
" 2nd smbcli_rap_netuseradd failed " ) ;
2015-12-03 17:24:34 +03:00
torture_assert_werr_equal ( tctx , W_ERROR ( r . out . status ) , WERR_NERR_USEREXISTS ,
2011-03-18 00:18:43 +03:00
" 2nd smbcli_rap_netuseradd failed " ) ;
{
struct rap_NetUserDelete d ;
d . in . UserName = username ;
smbcli_rap_netuserdelete ( cli - > tree , tctx , & d ) ;
}
}
return true ;
}
2011-03-18 02:12:11 +03:00
static bool test_userdelete ( struct torture_context * tctx ,
struct smbcli_state * cli )
{
struct rap_NetUserDelete r ;
{
struct rap_NetUserAdd a ;
const char * pwd ;
ZERO_STRUCT ( a . in . info . info1 ) ;
pwd = generate_random_password ( tctx , 9 , 16 ) ;
a . in . level = 1 ;
a . in . bufsize = 0xffff ;
a . in . pwdlength = strlen ( pwd ) ;
a . in . unknown = 0 ;
a . in . info . info1 . Name = TEST_RAP_USER ;
a . in . info . info1 . Priv = USER_PRIV_USER ;
memcpy ( a . in . info . info1 . Password , pwd , MIN ( strlen ( pwd ) , 16 ) ) ;
torture_assert_ntstatus_ok ( tctx ,
smbcli_rap_netuseradd ( cli - > tree , tctx , & a ) ,
" smbcli_rap_netuseradd failed " ) ;
}
r . in . UserName = TEST_RAP_USER ;
torture_comment ( tctx ,
" Testing rap_NetUserDelete(%s) \n " , r . in . UserName ) ;
torture_assert_ntstatus_ok ( tctx ,
smbcli_rap_netuserdelete ( cli - > tree , tctx , & r ) ,
" smbcli_rap_netuserdelete failed " ) ;
torture_assert_werr_ok ( tctx , W_ERROR ( r . out . status ) ,
" smbcli_rap_netuserdelete failed " ) ;
torture_assert_ntstatus_ok ( tctx ,
smbcli_rap_netuserdelete ( cli - > tree , tctx , & r ) ,
" 2nd smbcli_rap_netuserdelete failed " ) ;
2015-12-03 17:24:33 +03:00
torture_assert_werr_equal ( tctx , W_ERROR ( r . out . status ) , WERR_NERR_USERNOTFOUND ,
2011-03-18 02:12:11 +03:00
" 2nd smbcli_rap_netuserdelete failed " ) ;
return true ;
}
2010-05-07 17:45:23 +04:00
struct torture_suite * torture_rap_sam ( TALLOC_CTX * mem_ctx )
{
2010-12-11 05:26:31 +03:00
struct torture_suite * suite = torture_suite_create ( mem_ctx , " sam " ) ;
2010-05-07 17:45:23 +04:00
torture_suite_add_1smb_test ( suite , " userpasswordset2 " , test_userpasswordset2 ) ;
2010-05-08 00:58:42 +04:00
torture_suite_add_1smb_test ( suite , " oemchangepassword " , test_oemchangepassword ) ;
2010-05-26 23:22:13 +04:00
torture_suite_add_1smb_test ( suite , " usergetinfo " , test_usergetinfo ) ;
2011-03-18 00:18:43 +03:00
torture_suite_add_1smb_test ( suite , " useradd " , test_useradd ) ;
2011-03-18 02:12:11 +03:00
torture_suite_add_1smb_test ( suite , " userdelete " , test_userdelete ) ;
2010-05-07 17:45:23 +04:00
return suite ;
}