2008-04-09 14:38:22 +04:00
/*
* Unix SMB / CIFS implementation .
* NetApi User Support
* Copyright ( C ) Guenther Deschner 2008
*
* 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 "librpc/gen_ndr/libnetapi.h"
# include "lib/netapi/netapi.h"
2008-04-10 23:52:03 +04:00
# include "lib/netapi/netapi_private.h"
2008-04-09 14:38:22 +04:00
# include "lib/netapi/libnetapi.h"
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void convert_USER_INFO_1_to_samr_user_info25 ( struct USER_INFO_1 * info1 ,
DATA_BLOB * user_session_key ,
struct samr_UserInfo25 * info25 )
{
uint32_t fields_present = SAMR_FIELD_ACCT_FLAGS ;
struct samr_LogonHours zero_logon_hours ;
struct lsa_BinaryString zero_parameters ;
uint32_t acct_flags = 0 ;
NTTIME password_age ;
ZERO_STRUCTP ( info25 ) ;
ZERO_STRUCT ( zero_logon_hours ) ;
ZERO_STRUCT ( zero_parameters ) ;
if ( info1 - > usri1_name ) {
fields_present | = SAMR_FIELD_FULL_NAME ;
}
if ( info1 - > usri1_password ) {
fields_present | = SAMR_FIELD_PASSWORD ;
}
if ( info1 - > usri1_flags ) {
fields_present | = SAMR_FIELD_ACCT_FLAGS ;
}
if ( info1 - > usri1_name ) {
fields_present | = SAMR_FIELD_FULL_NAME ;
}
if ( info1 - > usri1_home_dir ) {
fields_present | = SAMR_FIELD_HOME_DIRECTORY ;
}
if ( info1 - > usri1_script_path ) {
fields_present | = SAMR_FIELD_LOGON_SCRIPT ;
}
if ( info1 - > usri1_comment ) {
fields_present | = SAMR_FIELD_DESCRIPTION ;
}
if ( info1 - > usri1_password_age ) {
fields_present | = SAMR_FIELD_FORCE_PWD_CHANGE ;
}
acct_flags | = info1 - > usri1_flags | ACB_NORMAL ;
unix_to_nt_time_abs ( & password_age , info1 - > usri1_password_age ) ;
/* TODO: info1->usri1_priv */
init_samr_user_info21 ( & info25 - > info ,
0 ,
0 ,
0 ,
0 ,
0 ,
password_age ,
NULL ,
info1 - > usri1_name ,
info1 - > usri1_home_dir ,
NULL ,
info1 - > usri1_script_path ,
NULL ,
info1 - > usri1_comment ,
NULL ,
NULL ,
& zero_parameters ,
0 ,
0 ,
acct_flags ,
fields_present ,
zero_logon_hours ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ,
0 ) ;
if ( info1 - > usri1_password ) {
uchar pwbuf [ 532 ] ;
struct MD5Context ctx ;
uint8_t confounder [ 16 ] ;
DATA_BLOB confounded_session_key = data_blob ( NULL , 16 ) ;
encode_pw_buffer ( pwbuf , info1 - > usri1_password , STR_UNICODE ) ;
generate_random_buffer ( ( uint8_t * ) confounder , 16 ) ;
MD5Init ( & ctx ) ;
MD5Update ( & ctx , confounder , 16 ) ;
MD5Update ( & ctx , user_session_key - > data ,
user_session_key - > length ) ;
MD5Final ( confounded_session_key . data , & ctx ) ;
SamOEMhashBlob ( pwbuf , 516 , & confounded_session_key ) ;
memcpy ( & pwbuf [ 516 ] , confounder , 16 ) ;
memcpy ( info25 - > password . data , pwbuf , sizeof ( pwbuf ) ) ;
data_blob_free ( & confounded_session_key ) ;
}
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetUserAdd_r ( struct libnetapi_ctx * ctx ,
struct NetUserAdd * r )
{
struct cli_state * cli = NULL ;
struct rpc_pipe_client * pipe_cli = NULL ;
NTSTATUS status ;
WERROR werr ;
POLICY_HND connect_handle , domain_handle , user_handle ;
2008-06-02 19:31:00 +04:00
struct lsa_String lsa_account_name ;
2008-04-09 14:38:22 +04:00
struct dom_sid2 * domain_sid = NULL ;
struct samr_UserInfo25 info25 ;
union samr_UserInfo * user_info = NULL ;
struct samr_PwInfo pw_info ;
uint32_t access_granted = 0 ;
uint32_t rid = 0 ;
struct USER_INFO_1 * info1 ;
ZERO_STRUCT ( connect_handle ) ;
ZERO_STRUCT ( domain_handle ) ;
ZERO_STRUCT ( user_handle ) ;
if ( ! r - > in . buffer ) {
return WERR_INVALID_PARAM ;
}
switch ( r - > in . level ) {
case 1 :
info1 = ( struct USER_INFO_1 * ) r - > in . buffer ;
break ;
case 2 :
case 3 :
case 4 :
default :
werr = WERR_NOT_SUPPORTED ;
goto done ;
}
2008-04-11 00:04:04 +04:00
werr = libnetapi_open_ipc_connection ( ctx , r - > in . server_name , & cli ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
2008-04-09 14:38:22 +04:00
goto done ;
}
2008-04-11 00:44:00 +04:00
werr = libnetapi_open_pipe ( ctx , cli , PI_SAMR , & pipe_cli ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
2008-04-09 14:38:22 +04:00
goto done ;
}
2008-06-03 01:55:45 +04:00
werr = libnetapi_samr_open_domain ( ctx , pipe_cli ,
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_OPEN_DOMAIN ,
SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
SAMR_DOMAIN_ACCESS_CREATE_USER |
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT ,
& connect_handle ,
& domain_handle ,
& domain_sid ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
2008-04-09 14:38:22 +04:00
goto done ;
}
init_lsa_String ( & lsa_account_name , info1 - > usri1_name ) ;
status = rpccli_samr_CreateUser2 ( pipe_cli , ctx ,
& domain_handle ,
& lsa_account_name ,
ACB_NORMAL ,
SEC_STD_WRITE_DAC |
SEC_STD_DELETE |
SAMR_USER_ACCESS_SET_PASSWORD |
SAMR_USER_ACCESS_SET_ATTRIBUTES |
SAMR_USER_ACCESS_GET_ATTRIBUTES ,
& user_handle ,
& access_granted ,
& rid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
status = rpccli_samr_QueryUserInfo ( pipe_cli , ctx ,
& user_handle ,
16 ,
& user_info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
if ( ! ( user_info - > info16 . acct_flags & ACB_NORMAL ) ) {
werr = WERR_INVALID_PARAM ;
goto done ;
}
status = rpccli_samr_GetUserPwInfo ( pipe_cli , ctx ,
& user_handle ,
& pw_info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
ZERO_STRUCTP ( user_info ) ;
convert_USER_INFO_1_to_samr_user_info25 ( info1 ,
& cli - > user_session_key ,
& info25 ) ;
if ( info1 - > usri1_password ) {
user_info - > info25 = info25 ;
status = rpccli_samr_SetUserInfo2 ( pipe_cli , ctx ,
& user_handle ,
25 ,
user_info ) ;
2008-07-18 03:10:31 +04:00
if ( NT_STATUS_EQUAL ( status , NT_STATUS ( DCERPC_FAULT_INVALID_TAG ) ) ) {
user_info - > info23 . info = info25 . info ;
encode_pw_buffer ( user_info - > info23 . password . data ,
info1 - > usri1_password , STR_UNICODE ) ;
SamOEMhashBlob ( user_info - > info23 . password . data , 516 ,
& cli - > user_session_key ) ;
status = rpccli_samr_SetUserInfo2 ( pipe_cli , ctx ,
& user_handle ,
23 ,
user_info ) ;
}
2008-04-09 14:38:22 +04:00
} else {
user_info - > info21 = info25 . info ;
status = rpccli_samr_SetUserInfo ( pipe_cli , ctx ,
& user_handle ,
21 ,
user_info ) ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto failed ;
}
werr = WERR_OK ;
goto done ;
failed :
2008-04-13 21:11:01 +04:00
rpccli_samr_DeleteUser ( pipe_cli , ctx ,
& user_handle ) ;
2008-04-09 14:38:22 +04:00
done :
if ( ! cli ) {
return werr ;
}
if ( is_valid_policy_hnd ( & user_handle ) ) {
rpccli_samr_Close ( pipe_cli , ctx , & user_handle ) ;
}
if ( is_valid_policy_hnd ( & domain_handle ) ) {
rpccli_samr_Close ( pipe_cli , ctx , & domain_handle ) ;
}
if ( is_valid_policy_hnd ( & connect_handle ) ) {
rpccli_samr_Close ( pipe_cli , ctx , & connect_handle ) ;
}
return werr ;
}
2008-04-09 15:35:49 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-04-16 04:38:13 +04:00
WERROR NetUserAdd_l ( struct libnetapi_ctx * ctx ,
struct NetUserAdd * r )
{
/* for now just talk to local RPC server */
if ( ! r - > in . server_name ) {
r - > in . server_name = " localhost " ;
}
return NetUserAdd_r ( ctx , r ) ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-04-09 15:35:49 +04:00
WERROR NetUserDel_r ( struct libnetapi_ctx * ctx ,
struct NetUserDel * r )
{
struct cli_state * cli = NULL ;
struct rpc_pipe_client * pipe_cli = NULL ;
NTSTATUS status ;
WERROR werr ;
POLICY_HND connect_handle , builtin_handle , domain_handle , user_handle ;
2008-06-02 19:31:00 +04:00
struct lsa_String lsa_account_name ;
2008-04-09 15:35:49 +04:00
struct samr_Ids user_rids , name_types ;
struct dom_sid2 * domain_sid = NULL ;
struct dom_sid2 user_sid ;
ZERO_STRUCT ( connect_handle ) ;
ZERO_STRUCT ( builtin_handle ) ;
ZERO_STRUCT ( domain_handle ) ;
ZERO_STRUCT ( user_handle ) ;
2008-04-11 00:04:04 +04:00
werr = libnetapi_open_ipc_connection ( ctx , r - > in . server_name , & cli ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
2008-04-09 15:35:49 +04:00
goto done ;
}
2008-04-11 00:44:00 +04:00
werr = libnetapi_open_pipe ( ctx , cli , PI_SAMR , & pipe_cli ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
2008-04-09 15:35:49 +04:00
goto done ;
}
2008-06-03 01:55:45 +04:00
werr = libnetapi_samr_open_domain ( ctx , pipe_cli ,
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_OPEN_DOMAIN ,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT ,
& connect_handle ,
& domain_handle ,
& domain_sid ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
2008-04-09 15:35:49 +04:00
goto done ;
}
status = rpccli_samr_OpenDomain ( pipe_cli , ctx ,
& connect_handle ,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT ,
CONST_DISCARD ( DOM_SID * , & global_sid_Builtin ) ,
& builtin_handle ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
init_lsa_String ( & lsa_account_name , r - > in . user_name ) ;
status = rpccli_samr_LookupNames ( pipe_cli , ctx ,
& domain_handle ,
1 ,
& lsa_account_name ,
& user_rids ,
& name_types ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
status = rpccli_samr_OpenUser ( pipe_cli , ctx ,
& domain_handle ,
STD_RIGHT_DELETE_ACCESS ,
user_rids . ids [ 0 ] ,
& user_handle ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
sid_compose ( & user_sid , domain_sid , user_rids . ids [ 0 ] ) ;
status = rpccli_samr_RemoveMemberFromForeignDomain ( pipe_cli , ctx ,
& builtin_handle ,
& user_sid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
status = rpccli_samr_DeleteUser ( pipe_cli , ctx ,
& user_handle ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
werr = WERR_OK ;
done :
if ( ! cli ) {
return werr ;
}
if ( is_valid_policy_hnd ( & user_handle ) ) {
rpccli_samr_Close ( pipe_cli , ctx , & user_handle ) ;
}
if ( is_valid_policy_hnd ( & builtin_handle ) ) {
rpccli_samr_Close ( pipe_cli , ctx , & builtin_handle ) ;
}
if ( is_valid_policy_hnd ( & domain_handle ) ) {
rpccli_samr_Close ( pipe_cli , ctx , & domain_handle ) ;
}
if ( is_valid_policy_hnd ( & connect_handle ) ) {
rpccli_samr_Close ( pipe_cli , ctx , & connect_handle ) ;
}
return werr ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetUserDel_l ( struct libnetapi_ctx * ctx ,
struct NetUserDel * r )
{
2008-04-16 04:38:13 +04:00
/* for now just talk to local RPC server */
if ( ! r - > in . server_name ) {
r - > in . server_name = " localhost " ;
}
return NetUserDel_r ( ctx , r ) ;
2008-04-09 15:35:49 +04:00
}
2008-04-09 15:47:51 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-07-01 22:19:10 +04:00
static NTSTATUS libnetapi_samr_lookup_user ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_cli ,
struct policy_handle * domain_handle ,
struct policy_handle * builtin_handle ,
const char * user_name ,
uint32_t rid ,
uint32_t level ,
struct samr_UserInfo21 * * info21 ,
struct sec_desc_buf * * sec_desc )
2008-04-09 15:47:51 +04:00
{
2008-07-01 22:19:10 +04:00
NTSTATUS status ;
struct policy_handle user_handle ;
union samr_UserInfo * user_info = NULL ;
struct samr_RidWithAttributeArray * rid_array = NULL ;
uint32_t access_mask = SEC_STD_READ_CONTROL |
SAMR_USER_ACCESS_GET_ATTRIBUTES |
SAMR_USER_ACCESS_GET_NAME_ETC ;
ZERO_STRUCT ( user_handle ) ;
switch ( level ) {
case 0 :
case 1 :
case 2 :
case 3 :
case 10 :
case 11 :
case 20 :
case 23 :
break ;
default :
return NT_STATUS_INVALID_LEVEL ;
}
if ( level = = 0 ) {
return NT_STATUS_OK ;
}
status = rpccli_samr_OpenUser ( pipe_cli , mem_ctx ,
domain_handle ,
access_mask ,
rid ,
& user_handle ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
status = rpccli_samr_QueryUserInfo ( pipe_cli , mem_ctx ,
& user_handle ,
21 ,
& user_info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
status = rpccli_samr_QuerySecurity ( pipe_cli , mem_ctx ,
& user_handle ,
SECINFO_DACL ,
sec_desc ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
if ( level = = 1 ) {
status = rpccli_samr_GetGroupsForUser ( pipe_cli , mem_ctx ,
& user_handle ,
& rid_array ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
#if 0
status = rpccli_samr_GetAliasMembership ( pipe_cli , ctx ,
& builtin_handle ,
& sids ,
& rids ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
# endif
}
* info21 = & user_info - > info21 ;
done :
if ( is_valid_policy_hnd ( & user_handle ) ) {
rpccli_samr_Close ( pipe_cli , mem_ctx , & user_handle ) ;
}
return status ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS libnetapi_samr_lookup_user_map_USER_INFO ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_cli ,
struct dom_sid * domain_sid ,
struct policy_handle * domain_handle ,
struct policy_handle * builtin_handle ,
const char * user_name ,
uint32_t rid ,
uint32_t level ,
uint8_t * * buffer ,
uint32_t * num_entries )
{
NTSTATUS status ;
struct samr_UserInfo21 * info21 = NULL ;
struct sec_desc_buf * sec_desc = NULL ;
struct dom_sid sid ;
2008-04-09 15:47:51 +04:00
struct USER_INFO_0 * info0 = NULL ;
2008-07-01 22:19:10 +04:00
struct USER_INFO_10 * info10 = NULL ;
struct USER_INFO_20 * info20 = NULL ;
struct USER_INFO_23 * info23 = NULL ;
2008-04-09 15:47:51 +04:00
switch ( level ) {
case 0 :
2008-07-01 22:19:10 +04:00
case 1 :
case 2 :
case 3 :
case 10 :
case 11 :
case 20 :
case 23 :
break ;
default :
return NT_STATUS_INVALID_LEVEL ;
}
if ( level = = 0 ) {
info0 = TALLOC_P ( mem_ctx , struct USER_INFO_0 ) ;
NT_STATUS_HAVE_NO_MEMORY ( info0 ) ;
info0 - > usri0_name = talloc_strdup ( mem_ctx , user_name ) ;
NT_STATUS_HAVE_NO_MEMORY ( info0 - > usri0_name ) ;
ADD_TO_ARRAY ( mem_ctx , struct USER_INFO_0 , * info0 ,
( struct USER_INFO_0 * * ) buffer , num_entries ) ;
return NT_STATUS_OK ;
}
status = libnetapi_samr_lookup_user ( mem_ctx , pipe_cli ,
domain_handle ,
builtin_handle ,
user_name ,
rid ,
level ,
& info21 ,
& sec_desc ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
switch ( level ) {
case 10 :
info10 = TALLOC_P ( mem_ctx , struct USER_INFO_10 ) ;
NT_STATUS_HAVE_NO_MEMORY ( info10 ) ;
info10 - > usri10_name = talloc_strdup ( mem_ctx , user_name ) ;
NT_STATUS_HAVE_NO_MEMORY ( info10 - > usri10_name ) ;
info10 - > usri10_comment = talloc_strdup ( mem_ctx ,
info21 - > description . string ) ;
info10 - > usri10_full_name = talloc_strdup ( mem_ctx ,
info21 - > full_name . string ) ;
info10 - > usri10_usr_comment = talloc_strdup ( mem_ctx ,
info21 - > comment . string ) ;
ADD_TO_ARRAY ( mem_ctx , struct USER_INFO_10 , * info10 ,
( struct USER_INFO_10 * * ) buffer , num_entries ) ;
break ;
case 20 :
info20 = TALLOC_P ( mem_ctx , struct USER_INFO_20 ) ;
NT_STATUS_HAVE_NO_MEMORY ( info20 ) ;
info20 - > usri20_name = talloc_strdup ( mem_ctx , user_name ) ;
NT_STATUS_HAVE_NO_MEMORY ( info20 - > usri20_name ) ;
info20 - > usri20_comment = talloc_strdup ( mem_ctx ,
info21 - > description . string ) ;
info20 - > usri20_flags = info21 - > acct_flags ;
info20 - > usri20_user_id = rid ;
ADD_TO_ARRAY ( mem_ctx , struct USER_INFO_20 , * info20 ,
( struct USER_INFO_20 * * ) buffer , num_entries ) ;
break ;
case 23 :
info23 = TALLOC_P ( mem_ctx , struct USER_INFO_23 ) ;
NT_STATUS_HAVE_NO_MEMORY ( info23 ) ;
info23 - > usri23_name = talloc_strdup ( mem_ctx , user_name ) ;
NT_STATUS_HAVE_NO_MEMORY ( info23 - > usri23_name ) ;
info23 - > usri23_comment = talloc_strdup ( mem_ctx ,
info21 - > description . string ) ;
info23 - > usri23_flags = info21 - > acct_flags ;
if ( ! sid_compose ( & sid , domain_sid , rid ) ) {
return NT_STATUS_NO_MEMORY ;
2008-04-09 15:47:51 +04:00
}
2008-07-01 22:19:10 +04:00
info23 - > usri23_user_sid =
( struct domsid * ) sid_dup_talloc ( mem_ctx , & sid ) ;
ADD_TO_ARRAY ( mem_ctx , struct USER_INFO_23 , * info23 ,
( struct USER_INFO_23 * * ) buffer , num_entries ) ;
2008-04-09 15:47:51 +04:00
break ;
}
2008-07-01 22:19:10 +04:00
done :
return status ;
2008-04-09 15:47:51 +04:00
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetUserEnum_r ( struct libnetapi_ctx * ctx ,
struct NetUserEnum * r )
{
struct cli_state * cli = NULL ;
struct rpc_pipe_client * pipe_cli = NULL ;
struct policy_handle connect_handle ;
struct dom_sid2 * domain_sid = NULL ;
struct policy_handle domain_handle ;
struct samr_SamArray * sam = NULL ;
2008-06-09 13:01:59 +04:00
uint32_t filter = ACB_NORMAL ;
2008-07-01 22:19:10 +04:00
int i ;
uint32_t entries_read = 0 ;
2008-04-09 15:47:51 +04:00
2008-07-01 22:19:10 +04:00
NTSTATUS status = NT_STATUS_OK ;
2008-04-09 15:47:51 +04:00
WERROR werr ;
ZERO_STRUCT ( connect_handle ) ;
ZERO_STRUCT ( domain_handle ) ;
2008-07-01 22:19:10 +04:00
if ( ! r - > out . buffer ) {
return WERR_INVALID_PARAM ;
}
* r - > out . buffer = NULL ;
* r - > out . entries_read = 0 ;
2008-04-09 15:47:51 +04:00
switch ( r - > in . level ) {
case 0 :
2008-07-01 22:19:10 +04:00
case 10 :
case 20 :
case 23 :
2008-04-09 15:47:51 +04:00
break ;
case 1 :
case 2 :
case 3 :
case 11 :
default :
return WERR_NOT_SUPPORTED ;
}
2008-04-11 00:04:04 +04:00
werr = libnetapi_open_ipc_connection ( ctx , r - > in . server_name , & cli ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
2008-04-09 15:47:51 +04:00
goto done ;
}
2008-04-11 00:44:00 +04:00
werr = libnetapi_open_pipe ( ctx , cli , PI_SAMR , & pipe_cli ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
2008-04-09 15:47:51 +04:00
goto done ;
}
2008-06-03 01:55:45 +04:00
werr = libnetapi_samr_open_domain ( ctx , pipe_cli ,
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_OPEN_DOMAIN ,
SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT ,
& connect_handle ,
& domain_handle ,
& domain_sid ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
2008-04-09 15:47:51 +04:00
goto done ;
}
2008-06-09 13:01:59 +04:00
switch ( r - > in . filter ) {
case FILTER_NORMAL_ACCOUNT :
filter = ACB_NORMAL ;
break ;
case FILTER_TEMP_DUPLICATE_ACCOUNT :
filter = ACB_TEMPDUP ;
break ;
case FILTER_INTERDOMAIN_TRUST_ACCOUNT :
filter = ACB_DOMTRUST ;
break ;
case FILTER_WORKSTATION_TRUST_ACCOUNT :
filter = ACB_WSTRUST ;
break ;
case FILTER_SERVER_TRUST_ACCOUNT :
filter = ACB_SVRTRUST ;
break ;
default :
break ;
}
2008-04-09 15:47:51 +04:00
status = rpccli_samr_EnumDomainUsers ( pipe_cli ,
ctx ,
& domain_handle ,
r - > in . resume_handle ,
2008-06-09 13:01:59 +04:00
filter ,
2008-04-09 15:47:51 +04:00
& sam ,
r - > in . prefmaxlen ,
2008-07-01 22:19:10 +04:00
& entries_read ) ;
werr = ntstatus_to_werror ( status ) ;
if ( NT_STATUS_IS_ERR ( status ) ) {
2008-04-09 15:47:51 +04:00
goto done ;
}
2008-07-01 22:19:10 +04:00
for ( i = 0 ; i < sam - > count ; i + + ) {
status = libnetapi_samr_lookup_user_map_USER_INFO ( ctx , pipe_cli ,
domain_sid ,
& domain_handle ,
NULL , /*&builtin_handle, */
sam - > entries [ i ] . name . string ,
sam - > entries [ i ] . idx ,
r - > in . level ,
r - > out . buffer ,
r - > out . entries_read ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
}
2008-04-09 15:47:51 +04:00
done :
2008-04-11 00:04:04 +04:00
if ( ! cli ) {
return werr ;
}
2008-04-09 15:47:51 +04:00
if ( is_valid_policy_hnd ( & domain_handle ) ) {
rpccli_samr_Close ( pipe_cli , ctx , & domain_handle ) ;
}
if ( is_valid_policy_hnd ( & connect_handle ) ) {
rpccli_samr_Close ( pipe_cli , ctx , & connect_handle ) ;
}
return werr ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetUserEnum_l ( struct libnetapi_ctx * ctx ,
struct NetUserEnum * r )
{
return WERR_NOT_SUPPORTED ;
}
2008-04-13 21:04:18 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-04-13 21:12:31 +04:00
static WERROR convert_samr_dispinfo_to_NET_DISPLAY_USER ( TALLOC_CTX * mem_ctx ,
struct samr_DispInfoGeneral * info ,
uint32_t * entries_read ,
void * * buffer )
{
struct NET_DISPLAY_USER * user = NULL ;
int i ;
user = TALLOC_ZERO_ARRAY ( mem_ctx ,
struct NET_DISPLAY_USER ,
info - > count ) ;
W_ERROR_HAVE_NO_MEMORY ( user ) ;
for ( i = 0 ; i < info - > count ; i + + ) {
user [ i ] . usri1_name = talloc_strdup ( mem_ctx ,
info - > entries [ i ] . account_name . string ) ;
user [ i ] . usri1_comment = talloc_strdup ( mem_ctx ,
info - > entries [ i ] . description . string ) ;
user [ i ] . usri1_flags =
info - > entries [ i ] . acct_flags ;
user [ i ] . usri1_full_name = talloc_strdup ( mem_ctx ,
info - > entries [ i ] . full_name . string ) ;
user [ i ] . usri1_user_id =
info - > entries [ i ] . rid ;
user [ i ] . usri1_next_index =
info - > entries [ i ] . idx ;
if ( ! user [ i ] . usri1_name ) {
return WERR_NOMEM ;
}
}
* buffer = talloc_memdup ( mem_ctx , user ,
sizeof ( struct NET_DISPLAY_USER ) * info - > count ) ;
W_ERROR_HAVE_NO_MEMORY ( * buffer ) ;
* entries_read = info - > count ;
return WERR_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static WERROR convert_samr_dispinfo_to_NET_DISPLAY_MACHINE ( TALLOC_CTX * mem_ctx ,
struct samr_DispInfoFull * info ,
uint32_t * entries_read ,
void * * buffer )
{
struct NET_DISPLAY_MACHINE * machine = NULL ;
int i ;
machine = TALLOC_ZERO_ARRAY ( mem_ctx ,
struct NET_DISPLAY_MACHINE ,
info - > count ) ;
W_ERROR_HAVE_NO_MEMORY ( machine ) ;
for ( i = 0 ; i < info - > count ; i + + ) {
machine [ i ] . usri2_name = talloc_strdup ( mem_ctx ,
info - > entries [ i ] . account_name . string ) ;
machine [ i ] . usri2_comment = talloc_strdup ( mem_ctx ,
info - > entries [ i ] . description . string ) ;
machine [ i ] . usri2_flags =
info - > entries [ i ] . acct_flags ;
machine [ i ] . usri2_user_id =
info - > entries [ i ] . rid ;
machine [ i ] . usri2_next_index =
info - > entries [ i ] . idx ;
if ( ! machine [ i ] . usri2_name ) {
return WERR_NOMEM ;
}
}
* buffer = talloc_memdup ( mem_ctx , machine ,
sizeof ( struct NET_DISPLAY_MACHINE ) * info - > count ) ;
W_ERROR_HAVE_NO_MEMORY ( * buffer ) ;
* entries_read = info - > count ;
return WERR_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static WERROR convert_samr_dispinfo_to_NET_DISPLAY_GROUP ( TALLOC_CTX * mem_ctx ,
struct samr_DispInfoFullGroups * info ,
uint32_t * entries_read ,
void * * buffer )
{
struct NET_DISPLAY_GROUP * group = NULL ;
int i ;
group = TALLOC_ZERO_ARRAY ( mem_ctx ,
struct NET_DISPLAY_GROUP ,
info - > count ) ;
W_ERROR_HAVE_NO_MEMORY ( group ) ;
for ( i = 0 ; i < info - > count ; i + + ) {
group [ i ] . grpi3_name = talloc_strdup ( mem_ctx ,
info - > entries [ i ] . account_name . string ) ;
group [ i ] . grpi3_comment = talloc_strdup ( mem_ctx ,
info - > entries [ i ] . description . string ) ;
group [ i ] . grpi3_group_id =
info - > entries [ i ] . rid ;
group [ i ] . grpi3_attributes =
info - > entries [ i ] . acct_flags ;
group [ i ] . grpi3_next_index =
info - > entries [ i ] . idx ;
if ( ! group [ i ] . grpi3_name ) {
return WERR_NOMEM ;
}
}
* buffer = talloc_memdup ( mem_ctx , group ,
sizeof ( struct NET_DISPLAY_GROUP ) * info - > count ) ;
W_ERROR_HAVE_NO_MEMORY ( * buffer ) ;
* entries_read = info - > count ;
return WERR_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-04-20 16:07:38 +04:00
static WERROR convert_samr_dispinfo_to_NET_DISPLAY ( TALLOC_CTX * mem_ctx ,
union samr_DispInfo * info ,
uint32_t level ,
uint32_t * entries_read ,
void * * buffer )
2008-04-13 21:12:31 +04:00
{
switch ( level ) {
case 1 :
return convert_samr_dispinfo_to_NET_DISPLAY_USER ( mem_ctx ,
& info - > info1 ,
entries_read ,
buffer ) ;
case 2 :
return convert_samr_dispinfo_to_NET_DISPLAY_MACHINE ( mem_ctx ,
& info - > info2 ,
entries_read ,
buffer ) ;
case 3 :
return convert_samr_dispinfo_to_NET_DISPLAY_GROUP ( mem_ctx ,
& info - > info3 ,
entries_read ,
buffer ) ;
default :
return WERR_UNKNOWN_LEVEL ;
}
return WERR_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-04-13 21:04:18 +04:00
WERROR NetQueryDisplayInformation_r ( struct libnetapi_ctx * ctx ,
struct NetQueryDisplayInformation * r )
{
2008-04-13 21:12:31 +04:00
struct cli_state * cli = NULL ;
struct rpc_pipe_client * pipe_cli = NULL ;
struct policy_handle connect_handle ;
struct dom_sid2 * domain_sid = NULL ;
struct policy_handle domain_handle ;
union samr_DispInfo info ;
uint32_t total_size = 0 ;
uint32_t returned_size = 0 ;
NTSTATUS status ;
WERROR werr ;
ZERO_STRUCT ( connect_handle ) ;
ZERO_STRUCT ( domain_handle ) ;
switch ( r - > in . level ) {
case 1 :
case 2 :
case 3 :
break ;
default :
return WERR_UNKNOWN_LEVEL ;
}
werr = libnetapi_open_ipc_connection ( ctx , r - > in . server_name , & cli ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
werr = libnetapi_open_pipe ( ctx , cli , PI_SAMR , & pipe_cli ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
2008-06-03 01:55:45 +04:00
werr = libnetapi_samr_open_domain ( ctx , pipe_cli ,
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_OPEN_DOMAIN ,
SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS |
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT ,
& connect_handle ,
& domain_handle ,
& domain_sid ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
2008-04-13 21:12:31 +04:00
goto done ;
}
status = rpccli_samr_QueryDisplayInfo2 ( pipe_cli ,
ctx ,
& domain_handle ,
r - > in . level ,
r - > in . idx ,
r - > in . entries_requested ,
r - > in . prefmaxlen ,
& total_size ,
& returned_size ,
& info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
werr = convert_samr_dispinfo_to_NET_DISPLAY ( ctx , & info ,
r - > in . level ,
r - > out . entries_read ,
r - > out . buffer ) ;
done :
if ( ! cli ) {
return werr ;
}
if ( is_valid_policy_hnd ( & domain_handle ) ) {
rpccli_samr_Close ( pipe_cli , ctx , & domain_handle ) ;
}
if ( is_valid_policy_hnd ( & connect_handle ) ) {
rpccli_samr_Close ( pipe_cli , ctx , & connect_handle ) ;
}
return werr ;
2008-04-13 21:04:18 +04:00
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetQueryDisplayInformation_l ( struct libnetapi_ctx * ctx ,
struct NetQueryDisplayInformation * r )
{
return WERR_NOT_SUPPORTED ;
}
2008-06-25 02:32:02 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetUserChangePassword_r ( struct libnetapi_ctx * ctx ,
struct NetUserChangePassword * r )
{
return WERR_NOT_SUPPORTED ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetUserChangePassword_l ( struct libnetapi_ctx * ctx ,
struct NetUserChangePassword * r )
{
return WERR_NOT_SUPPORTED ;
}
2008-07-16 12:47:38 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetUserGetInfo_r ( struct libnetapi_ctx * ctx ,
struct NetUserGetInfo * r )
{
2008-07-18 00:45:09 +04:00
struct cli_state * cli = NULL ;
struct rpc_pipe_client * pipe_cli = NULL ;
NTSTATUS status ;
WERROR werr ;
struct policy_handle connect_handle , domain_handle , builtin_handle , user_handle ;
struct lsa_String lsa_account_name ;
struct dom_sid2 * domain_sid = NULL ;
struct samr_Ids user_rids , name_types ;
uint32_t num_entries = 0 ;
ZERO_STRUCT ( connect_handle ) ;
ZERO_STRUCT ( domain_handle ) ;
ZERO_STRUCT ( builtin_handle ) ;
ZERO_STRUCT ( user_handle ) ;
if ( ! r - > out . buffer ) {
return WERR_INVALID_PARAM ;
}
switch ( r - > in . level ) {
case 0 :
/* case 1: */
case 10 :
case 20 :
case 23 :
break ;
default :
werr = WERR_NOT_SUPPORTED ;
goto done ;
}
werr = libnetapi_open_ipc_connection ( ctx , r - > in . server_name , & cli ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
werr = libnetapi_open_pipe ( ctx , cli , PI_SAMR , & pipe_cli ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
werr = libnetapi_samr_open_domain ( ctx , pipe_cli ,
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_OPEN_DOMAIN ,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT ,
& connect_handle ,
& domain_handle ,
& domain_sid ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
werr = libnetapi_samr_open_builtin_domain ( ctx , pipe_cli ,
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_OPEN_DOMAIN ,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS ,
& connect_handle ,
& builtin_handle ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
init_lsa_String ( & lsa_account_name , r - > in . user_name ) ;
status = rpccli_samr_LookupNames ( pipe_cli , ctx ,
& domain_handle ,
1 ,
& lsa_account_name ,
& user_rids ,
& name_types ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
status = libnetapi_samr_lookup_user_map_USER_INFO ( ctx , pipe_cli ,
domain_sid ,
& domain_handle ,
& builtin_handle ,
r - > in . user_name ,
user_rids . ids [ 0 ] ,
r - > in . level ,
r - > out . buffer ,
& num_entries ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
done :
if ( ! cli ) {
return werr ;
}
if ( is_valid_policy_hnd ( & user_handle ) ) {
rpccli_samr_Close ( pipe_cli , ctx , & user_handle ) ;
}
libnetapi_samr_close_domain_handle ( ctx , & domain_handle ) ;
libnetapi_samr_close_connect_handle ( ctx , & connect_handle ) ;
return werr ;
2008-07-16 12:47:38 +04:00
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetUserGetInfo_l ( struct libnetapi_ctx * ctx ,
struct NetUserGetInfo * r )
{
return WERR_NOT_SUPPORTED ;
}