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"
2011-01-14 19:05:32 +03:00
# include "../librpc/gen_ndr/ndr_samr_c.h"
2010-05-18 20:59:45 +04:00
# include "rpc_client/init_samr.h"
2010-07-01 01:38:57 +04:00
# include "../libds/common/flags.h"
2010-08-20 01:15:22 +04:00
# include "rpc_client/init_lsa.h"
2010-10-12 08:27:50 +04:00
# include "../libcli/security/security.h"
2011-02-26 02:17:33 +03:00
# include "../libds/common/flag_mapping.h"
2011-03-25 00:14:20 +03:00
# include "rpc_client/cli_pipe.h"
2008-04-09 14:38:22 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-07-18 22:12:13 +04:00
static void convert_USER_INFO_X_to_samr_user_info21 ( struct USER_INFO_X * infoX ,
struct samr_UserInfo21 * info21 )
2008-04-09 14:38:22 +04:00
{
2008-08-27 03:36:06 +04:00
uint32_t fields_present = 0 ;
2008-04-09 14:38:22 +04:00
struct samr_LogonHours zero_logon_hours ;
struct lsa_BinaryString zero_parameters ;
NTTIME password_age ;
2008-07-18 22:12:13 +04:00
ZERO_STRUCTP ( info21 ) ;
2008-04-09 14:38:22 +04:00
ZERO_STRUCT ( zero_logon_hours ) ;
ZERO_STRUCT ( zero_parameters ) ;
2008-08-27 03:36:06 +04:00
if ( infoX - > usriX_flags ) {
fields_present | = SAMR_FIELD_ACCT_FLAGS ;
}
2008-07-18 22:12:13 +04:00
if ( infoX - > usriX_name ) {
2008-08-27 02:57:07 +04:00
fields_present | = SAMR_FIELD_ACCOUNT_NAME ;
2008-04-09 14:38:22 +04:00
}
2008-07-18 22:12:13 +04:00
if ( infoX - > usriX_password ) {
2008-12-04 20:15:03 +03:00
fields_present | = SAMR_FIELD_NT_PASSWORD_PRESENT ;
2008-04-09 14:38:22 +04:00
}
2008-07-18 22:12:13 +04:00
if ( infoX - > usriX_flags ) {
2008-04-09 14:38:22 +04:00
fields_present | = SAMR_FIELD_ACCT_FLAGS ;
}
2008-07-18 22:12:13 +04:00
if ( infoX - > usriX_home_dir ) {
2008-04-09 14:38:22 +04:00
fields_present | = SAMR_FIELD_HOME_DIRECTORY ;
}
2008-07-18 22:12:13 +04:00
if ( infoX - > usriX_script_path ) {
2008-04-09 14:38:22 +04:00
fields_present | = SAMR_FIELD_LOGON_SCRIPT ;
}
2008-07-18 22:12:13 +04:00
if ( infoX - > usriX_comment ) {
2008-04-09 14:38:22 +04:00
fields_present | = SAMR_FIELD_DESCRIPTION ;
}
2008-07-18 22:12:13 +04:00
if ( infoX - > usriX_password_age ) {
2014-09-08 14:21:26 +04:00
fields_present | = SAMR_FIELD_EXPIRED_FLAG ;
2008-04-09 14:38:22 +04:00
}
2008-08-27 03:04:21 +04:00
if ( infoX - > usriX_full_name ) {
fields_present | = SAMR_FIELD_FULL_NAME ;
}
2008-08-27 03:36:49 +04:00
if ( infoX - > usriX_usr_comment ) {
fields_present | = SAMR_FIELD_COMMENT ;
}
2008-08-27 03:47:33 +04:00
if ( infoX - > usriX_profile ) {
fields_present | = SAMR_FIELD_PROFILE_PATH ;
}
2008-08-27 03:53:10 +04:00
if ( infoX - > usriX_home_dir_drive ) {
fields_present | = SAMR_FIELD_HOME_DRIVE ;
}
2008-08-27 04:02:30 +04:00
if ( infoX - > usriX_primary_group_id ) {
fields_present | = SAMR_FIELD_PRIMARY_GID ;
}
2008-08-27 04:11:54 +04:00
if ( infoX - > usriX_country_code ) {
fields_present | = SAMR_FIELD_COUNTRY_CODE ;
}
2008-08-27 04:18:30 +04:00
if ( infoX - > usriX_workstations ) {
fields_present | = SAMR_FIELD_WORKSTATIONS ;
}
2008-04-09 14:38:22 +04:00
2008-07-18 22:12:13 +04:00
unix_to_nt_time_abs ( & password_age , infoX - > usriX_password_age ) ;
2008-04-09 14:38:22 +04:00
2008-07-18 22:12:13 +04:00
/* TODO: infoX->usriX_priv */
2008-12-06 02:28:34 +03:00
info21 - > last_logon = 0 ;
info21 - > last_logoff = 0 ;
info21 - > last_password_change = 0 ;
info21 - > acct_expiry = 0 ;
info21 - > allow_password_change = 0 ;
info21 - > force_password_change = 0 ;
info21 - > account_name . string = infoX - > usriX_name ;
info21 - > full_name . string = infoX - > usriX_full_name ;
info21 - > home_directory . string = infoX - > usriX_home_dir ;
info21 - > home_drive . string = infoX - > usriX_home_dir_drive ;
info21 - > logon_script . string = infoX - > usriX_script_path ;
info21 - > profile_path . string = infoX - > usriX_profile ;
info21 - > description . string = infoX - > usriX_comment ;
info21 - > workstations . string = infoX - > usriX_workstations ;
info21 - > comment . string = infoX - > usriX_usr_comment ;
info21 - > parameters = zero_parameters ;
info21 - > lm_owf_password = zero_parameters ;
info21 - > nt_owf_password = zero_parameters ;
2010-07-05 00:34:43 +04:00
info21 - > private_data . string = NULL ;
2008-12-06 02:28:34 +03:00
info21 - > buf_count = 0 ;
info21 - > buffer = NULL ;
info21 - > rid = infoX - > usriX_user_id ;
info21 - > primary_gid = infoX - > usriX_primary_group_id ;
info21 - > acct_flags = infoX - > usriX_flags ;
info21 - > fields_present = fields_present ;
info21 - > logon_hours = zero_logon_hours ;
info21 - > bad_password_count = infoX - > usriX_bad_pw_count ;
info21 - > logon_count = infoX - > usriX_num_logons ;
info21 - > country_code = infoX - > usriX_country_code ;
info21 - > code_page = infoX - > usriX_code_page ;
info21 - > lm_password_set = 0 ;
info21 - > nt_password_set = 0 ;
info21 - > password_expired = infoX - > usriX_password_expired ;
2010-07-05 00:34:43 +04:00
info21 - > private_data_sensitive = 0 ;
2008-07-18 22:12:13 +04:00
}
2008-04-09 14:38:22 +04:00
2008-07-18 22:12:13 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-04-09 14:38:22 +04:00
2008-07-18 22:12:13 +04:00
static NTSTATUS construct_USER_INFO_X ( uint32_t level ,
uint8_t * buffer ,
struct USER_INFO_X * uX )
{
struct USER_INFO_0 * u0 = NULL ;
struct USER_INFO_1 * u1 = NULL ;
struct USER_INFO_2 * u2 = NULL ;
2008-09-16 19:53:06 +04:00
struct USER_INFO_3 * u3 = NULL ;
2008-08-27 02:33:16 +04:00
struct USER_INFO_1003 * u1003 = NULL ;
2008-08-27 03:40:46 +04:00
struct USER_INFO_1006 * u1006 = NULL ;
2008-07-18 22:12:13 +04:00
struct USER_INFO_1007 * u1007 = NULL ;
2008-08-27 03:15:21 +04:00
struct USER_INFO_1009 * u1009 = NULL ;
2008-08-27 03:04:21 +04:00
struct USER_INFO_1011 * u1011 = NULL ;
2008-08-27 03:36:49 +04:00
struct USER_INFO_1012 * u1012 = NULL ;
2008-08-27 04:18:30 +04:00
struct USER_INFO_1014 * u1014 = NULL ;
2008-08-27 04:11:54 +04:00
struct USER_INFO_1024 * u1024 = NULL ;
2008-08-27 04:02:30 +04:00
struct USER_INFO_1051 * u1051 = NULL ;
2008-08-27 03:47:33 +04:00
struct USER_INFO_1052 * u1052 = NULL ;
2008-08-27 03:53:10 +04:00
struct USER_INFO_1053 * u1053 = NULL ;
2008-04-09 14:38:22 +04:00
2008-07-18 22:12:13 +04:00
if ( ! buffer | | ! uX ) {
return NT_STATUS_INVALID_PARAMETER ;
}
2008-04-09 14:38:22 +04:00
2008-07-18 22:12:13 +04:00
ZERO_STRUCTP ( uX ) ;
2008-04-09 14:38:22 +04:00
2008-07-18 22:12:13 +04:00
switch ( level ) {
case 0 :
u0 = ( struct USER_INFO_0 * ) buffer ;
uX - > usriX_name = u0 - > usri0_name ;
break ;
case 1 :
u1 = ( struct USER_INFO_1 * ) buffer ;
uX - > usriX_name = u1 - > usri1_name ;
uX - > usriX_password = u1 - > usri1_password ;
uX - > usriX_password_age = u1 - > usri1_password_age ;
uX - > usriX_priv = u1 - > usri1_priv ;
uX - > usriX_home_dir = u1 - > usri1_home_dir ;
uX - > usriX_comment = u1 - > usri1_comment ;
uX - > usriX_flags = u1 - > usri1_flags ;
uX - > usriX_script_path = u1 - > usri1_script_path ;
break ;
case 2 :
u2 = ( struct USER_INFO_2 * ) buffer ;
uX - > usriX_name = u2 - > usri2_name ;
uX - > usriX_password = u2 - > usri2_password ;
uX - > usriX_password_age = u2 - > usri2_password_age ;
uX - > usriX_priv = u2 - > usri2_priv ;
uX - > usriX_home_dir = u2 - > usri2_home_dir ;
uX - > usriX_comment = u2 - > usri2_comment ;
uX - > usriX_flags = u2 - > usri2_flags ;
uX - > usriX_script_path = u2 - > usri2_script_path ;
uX - > usriX_auth_flags = u2 - > usri2_auth_flags ;
uX - > usriX_full_name = u2 - > usri2_full_name ;
uX - > usriX_usr_comment = u2 - > usri2_usr_comment ;
uX - > usriX_parms = u2 - > usri2_parms ;
uX - > usriX_workstations = u2 - > usri2_workstations ;
uX - > usriX_last_logon = u2 - > usri2_last_logon ;
uX - > usriX_last_logoff = u2 - > usri2_last_logoff ;
uX - > usriX_acct_expires = u2 - > usri2_acct_expires ;
uX - > usriX_max_storage = u2 - > usri2_max_storage ;
uX - > usriX_units_per_week = u2 - > usri2_units_per_week ;
uX - > usriX_logon_hours = u2 - > usri2_logon_hours ;
uX - > usriX_bad_pw_count = u2 - > usri2_bad_pw_count ;
uX - > usriX_num_logons = u2 - > usri2_num_logons ;
uX - > usriX_logon_server = u2 - > usri2_logon_server ;
uX - > usriX_country_code = u2 - > usri2_country_code ;
uX - > usriX_code_page = u2 - > usri2_code_page ;
break ;
2008-09-16 19:53:06 +04:00
case 3 :
u3 = ( struct USER_INFO_3 * ) buffer ;
uX - > usriX_name = u3 - > usri3_name ;
uX - > usriX_password_age = u3 - > usri3_password_age ;
uX - > usriX_priv = u3 - > usri3_priv ;
uX - > usriX_home_dir = u3 - > usri3_home_dir ;
uX - > usriX_comment = u3 - > usri3_comment ;
uX - > usriX_flags = u3 - > usri3_flags ;
uX - > usriX_script_path = u3 - > usri3_script_path ;
uX - > usriX_auth_flags = u3 - > usri3_auth_flags ;
uX - > usriX_full_name = u3 - > usri3_full_name ;
uX - > usriX_usr_comment = u3 - > usri3_usr_comment ;
uX - > usriX_parms = u3 - > usri3_parms ;
uX - > usriX_workstations = u3 - > usri3_workstations ;
uX - > usriX_last_logon = u3 - > usri3_last_logon ;
uX - > usriX_last_logoff = u3 - > usri3_last_logoff ;
uX - > usriX_acct_expires = u3 - > usri3_acct_expires ;
uX - > usriX_max_storage = u3 - > usri3_max_storage ;
uX - > usriX_units_per_week = u3 - > usri3_units_per_week ;
uX - > usriX_logon_hours = u3 - > usri3_logon_hours ;
uX - > usriX_bad_pw_count = u3 - > usri3_bad_pw_count ;
uX - > usriX_num_logons = u3 - > usri3_num_logons ;
uX - > usriX_logon_server = u3 - > usri3_logon_server ;
uX - > usriX_country_code = u3 - > usri3_country_code ;
uX - > usriX_code_page = u3 - > usri3_code_page ;
uX - > usriX_user_id = u3 - > usri3_user_id ;
uX - > usriX_primary_group_id = u3 - > usri3_primary_group_id ;
uX - > usriX_profile = u3 - > usri3_profile ;
uX - > usriX_home_dir_drive = u3 - > usri3_home_dir_drive ;
uX - > usriX_password_expired = u3 - > usri3_password_expired ;
break ;
2008-08-27 02:33:16 +04:00
case 1003 :
u1003 = ( struct USER_INFO_1003 * ) buffer ;
uX - > usriX_password = u1003 - > usri1003_password ;
break ;
2008-08-27 03:40:46 +04:00
case 1006 :
u1006 = ( struct USER_INFO_1006 * ) buffer ;
uX - > usriX_home_dir = u1006 - > usri1006_home_dir ;
break ;
2008-07-18 22:12:13 +04:00
case 1007 :
u1007 = ( struct USER_INFO_1007 * ) buffer ;
uX - > usriX_comment = u1007 - > usri1007_comment ;
break ;
2008-08-27 03:15:21 +04:00
case 1009 :
u1009 = ( struct USER_INFO_1009 * ) buffer ;
uX - > usriX_script_path = u1009 - > usri1009_script_path ;
break ;
2008-08-27 03:04:21 +04:00
case 1011 :
u1011 = ( struct USER_INFO_1011 * ) buffer ;
uX - > usriX_full_name = u1011 - > usri1011_full_name ;
break ;
2008-08-27 03:36:49 +04:00
case 1012 :
u1012 = ( struct USER_INFO_1012 * ) buffer ;
uX - > usriX_usr_comment = u1012 - > usri1012_usr_comment ;
break ;
2008-08-27 04:18:30 +04:00
case 1014 :
u1014 = ( struct USER_INFO_1014 * ) buffer ;
uX - > usriX_workstations = u1014 - > usri1014_workstations ;
break ;
2008-08-27 04:11:54 +04:00
case 1024 :
u1024 = ( struct USER_INFO_1024 * ) buffer ;
uX - > usriX_country_code = u1024 - > usri1024_country_code ;
break ;
2008-08-27 04:02:30 +04:00
case 1051 :
u1051 = ( struct USER_INFO_1051 * ) buffer ;
uX - > usriX_primary_group_id = u1051 - > usri1051_primary_group_id ;
break ;
2008-08-27 03:47:33 +04:00
case 1052 :
u1052 = ( struct USER_INFO_1052 * ) buffer ;
uX - > usriX_profile = u1052 - > usri1052_profile ;
break ;
2008-08-27 03:53:10 +04:00
case 1053 :
u1053 = ( struct USER_INFO_1053 * ) buffer ;
uX - > usriX_home_dir_drive = u1053 - > usri1053_home_dir_drive ;
break ;
2008-07-18 22:12:13 +04:00
case 4 :
default :
return NT_STATUS_INVALID_INFO_CLASS ;
2008-04-09 14:38:22 +04:00
}
2008-07-18 22:12:13 +04:00
return NT_STATUS_OK ;
2008-04-09 14:38:22 +04:00
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2019-07-16 16:20:23 +03:00
static NTSTATUS set_user_info_USER_INFO_X ( TALLOC_CTX * mem_ctx ,
2008-08-27 02:32:08 +04:00
struct rpc_pipe_client * pipe_cli ,
DATA_BLOB * session_key ,
struct policy_handle * user_handle ,
struct USER_INFO_X * uX )
{
union samr_UserInfo user_info ;
struct samr_UserInfo21 info21 ;
2011-01-14 19:05:32 +03:00
NTSTATUS status , result ;
struct dcerpc_binding_handle * b = pipe_cli - > binding_handle ;
2008-08-27 02:32:08 +04:00
if ( ! uX ) {
return NT_STATUS_INVALID_PARAMETER ;
}
convert_USER_INFO_X_to_samr_user_info21 ( uX , & info21 ) ;
ZERO_STRUCT ( user_info ) ;
if ( uX - > usriX_password ) {
user_info . info25 . info = info21 ;
2019-05-29 18:16:26 +03:00
status = init_samr_CryptPasswordEx ( uX - > usriX_password ,
session_key ,
& user_info . info25 . password ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2008-08-27 02:32:08 +04:00
2019-07-16 16:20:23 +03:00
status = dcerpc_samr_SetUserInfo2 ( b , mem_ctx ,
2008-08-27 02:32:08 +04:00
user_handle ,
25 ,
2011-01-14 19:05:32 +03:00
& user_info ,
& result ) ;
2011-04-24 02:00:40 +04:00
if ( NT_STATUS_EQUAL ( status , NT_STATUS_RPC_ENUM_VALUE_OUT_OF_RANGE ) ) {
2008-08-27 02:32:08 +04:00
user_info . info23 . info = info21 ;
2019-05-29 17:22:11 +03:00
status = init_samr_CryptPassword ( uX - > usriX_password ,
session_key ,
& user_info . info23 . password ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2008-08-27 02:32:08 +04:00
2019-07-16 16:20:23 +03:00
status = dcerpc_samr_SetUserInfo2 ( b , mem_ctx ,
2008-08-27 02:32:08 +04:00
user_handle ,
23 ,
2011-01-14 19:05:32 +03:00
& user_info ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
2008-08-27 02:32:08 +04:00
}
} else {
user_info . info21 = info21 ;
2019-07-16 16:20:23 +03:00
status = dcerpc_samr_SetUserInfo ( b , mem_ctx ,
2008-08-27 02:32:08 +04:00
user_handle ,
21 ,
2011-01-14 19:05:32 +03:00
& user_info ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
2008-08-27 02:32:08 +04:00
}
2011-01-14 19:05:32 +03:00
return result ;
2008-08-27 02:32:08 +04:00
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-04-09 14:38:22 +04:00
WERROR NetUserAdd_r ( struct libnetapi_ctx * ctx ,
struct NetUserAdd * r )
{
struct rpc_pipe_client * pipe_cli = NULL ;
2011-01-14 19:05:32 +03:00
NTSTATUS status , result ;
2008-04-09 14:38:22 +04:00
WERROR werr ;
2009-03-19 00:49:41 +03:00
struct policy_handle 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 ;
union samr_UserInfo * user_info = NULL ;
struct samr_PwInfo pw_info ;
uint32_t access_granted = 0 ;
uint32_t rid = 0 ;
2008-07-18 22:12:13 +04:00
struct USER_INFO_X uX ;
2011-01-14 19:05:32 +03:00
struct dcerpc_binding_handle * b = NULL ;
2011-03-25 00:14:20 +03:00
DATA_BLOB session_key ;
2008-04-09 14:38:22 +04:00
ZERO_STRUCT ( connect_handle ) ;
ZERO_STRUCT ( domain_handle ) ;
ZERO_STRUCT ( user_handle ) ;
if ( ! r - > in . buffer ) {
2015-12-03 17:24:23 +03:00
return WERR_INVALID_PARAMETER ;
2008-04-09 14:38:22 +04:00
}
switch ( r - > in . level ) {
case 1 :
break ;
case 2 :
case 3 :
case 4 :
default :
werr = WERR_NOT_SUPPORTED ;
goto done ;
}
2008-08-12 19:59:23 +04:00
werr = libnetapi_open_pipe ( ctx , r - > in . server_name ,
2013-05-17 18:10:13 +04:00
& ndr_table_samr ,
2008-07-20 19:59:30 +04:00
& pipe_cli ) ;
2008-04-11 00:44:00 +04:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
2008-04-09 14:38:22 +04:00
goto done ;
}
2011-01-14 19:05:32 +03:00
b = pipe_cli - > binding_handle ;
2008-07-18 22:12:13 +04:00
status = construct_USER_INFO_X ( r - > in . level , r - > in . buffer , & uX ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
2008-06-03 01:55:45 +04:00
werr = libnetapi_samr_open_domain ( ctx , pipe_cli ,
SAMR_ACCESS_ENUM_DOMAINS |
2009-04-16 02:40:00 +04:00
SAMR_ACCESS_LOOKUP_DOMAIN ,
2008-06-03 01:55:45 +04:00
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 ;
}
2008-07-18 22:12:13 +04:00
init_lsa_String ( & lsa_account_name , uX . usriX_name ) ;
2008-04-09 14:38:22 +04:00
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_CreateUser2 ( b , talloc_tos ( ) ,
2008-04-09 14:38:22 +04:00
& 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 ,
2011-01-14 19:05:32 +03:00
& rid ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-04-09 14:38:22 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_QueryUserInfo ( b , talloc_tos ( ) ,
2008-04-09 14:38:22 +04:00
& user_handle ,
16 ,
2011-01-14 19:05:32 +03:00
& user_info ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-04-09 14:38:22 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
if ( ! ( user_info - > info16 . acct_flags & ACB_NORMAL ) ) {
2015-12-03 17:24:23 +03:00
werr = WERR_INVALID_PARAMETER ;
2008-04-09 14:38:22 +04:00
goto done ;
}
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_GetUserPwInfo ( b , talloc_tos ( ) ,
2008-04-09 14:38:22 +04:00
& user_handle ,
2011-01-14 19:05:32 +03:00
& pw_info ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-04-09 14:38:22 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
2024-09-14 16:51:20 +03:00
status = dcerpc_binding_handle_transport_session_key (
b , talloc_tos ( ) , & session_key ) ;
2011-03-25 00:14:20 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
2008-08-27 03:36:06 +04:00
uX . usriX_flags | = ACB_NORMAL ;
2008-08-27 02:32:08 +04:00
status = set_user_info_USER_INFO_X ( ctx , pipe_cli ,
2011-03-25 00:14:20 +03:00
& session_key ,
2008-08-27 02:32:08 +04:00
& user_handle ,
& uX ) ;
2008-04-09 14:38:22 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto failed ;
}
werr = WERR_OK ;
goto done ;
failed :
2011-01-14 19:05:32 +03:00
dcerpc_samr_DeleteUser ( b , talloc_tos ( ) ,
& user_handle ,
& result ) ;
2008-04-09 14:38:22 +04:00
done :
2011-01-14 19:05:32 +03:00
if ( is_valid_policy_hnd ( & user_handle ) & & b ) {
dcerpc_samr_Close ( b , talloc_tos ( ) , & user_handle , & result ) ;
2008-04-09 14:38:22 +04:00
}
2008-07-18 00:44:24 +04:00
if ( ctx - > disable_policy_handle_cache ) {
libnetapi_samr_close_domain_handle ( ctx , & domain_handle ) ;
libnetapi_samr_close_connect_handle ( ctx , & connect_handle ) ;
2008-04-09 14:38:22 +04:00
}
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 )
{
2008-08-12 17:25:06 +04:00
LIBNETAPI_REDIRECT_TO_LOCALHOST ( ctx , r , NetUserAdd ) ;
2008-04-16 04:38:13 +04:00
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-04-09 15:35:49 +04:00
WERROR NetUserDel_r ( struct libnetapi_ctx * ctx ,
struct NetUserDel * r )
{
struct rpc_pipe_client * pipe_cli = NULL ;
2011-01-14 19:05:32 +03:00
NTSTATUS status , result ;
2008-04-09 15:35:49 +04:00
WERROR werr ;
2009-03-19 00:49:41 +03:00
struct policy_handle 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 ;
2011-01-14 19:05:32 +03:00
struct dcerpc_binding_handle * b = NULL ;
2008-04-09 15:35:49 +04:00
ZERO_STRUCT ( connect_handle ) ;
ZERO_STRUCT ( builtin_handle ) ;
ZERO_STRUCT ( domain_handle ) ;
ZERO_STRUCT ( user_handle ) ;
2008-08-12 19:59:23 +04:00
werr = libnetapi_open_pipe ( ctx , r - > in . server_name ,
2013-05-17 18:10:13 +04:00
& ndr_table_samr ,
2008-07-20 19:59:30 +04:00
& pipe_cli ) ;
2008-08-12 19:59:23 +04:00
2008-04-11 00:44:00 +04:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
2008-04-09 15:35:49 +04:00
goto done ;
}
2011-01-14 19:05:32 +03:00
b = pipe_cli - > binding_handle ;
2008-06-03 01:55:45 +04:00
werr = libnetapi_samr_open_domain ( ctx , pipe_cli ,
SAMR_ACCESS_ENUM_DOMAINS |
2009-04-16 02:40:00 +04:00
SAMR_ACCESS_LOOKUP_DOMAIN ,
2008-06-03 01:55:45 +04:00
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 ;
}
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_OpenDomain ( b , talloc_tos ( ) ,
2008-04-09 15:35:49 +04:00
& connect_handle ,
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT ,
2011-05-06 00:42:05 +04:00
discard_const_p ( struct dom_sid , & global_sid_Builtin ) ,
2011-01-14 19:05:32 +03:00
& builtin_handle ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-04-09 15:35:49 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
init_lsa_String ( & lsa_account_name , r - > in . user_name ) ;
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_LookupNames ( b , talloc_tos ( ) ,
2008-04-09 15:35:49 +04:00
& domain_handle ,
1 ,
& lsa_account_name ,
& user_rids ,
2011-01-14 19:05:32 +03:00
& name_types ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-04-09 15:35:49 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
2013-11-08 09:40:55 +04:00
if ( user_rids . count ! = 1 ) {
werr = WERR_BAD_NET_RESP ;
goto done ;
}
if ( name_types . count ! = 1 ) {
werr = WERR_BAD_NET_RESP ;
goto done ;
}
2008-04-09 15:35:49 +04:00
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_OpenUser ( b , talloc_tos ( ) ,
2008-04-09 15:35:49 +04:00
& domain_handle ,
2008-10-24 03:57:28 +04:00
SEC_STD_DELETE ,
2008-04-09 15:35:49 +04:00
user_rids . ids [ 0 ] ,
2011-01-14 19:05:32 +03:00
& user_handle ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-04-09 15:35:49 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
sid_compose ( & user_sid , domain_sid , user_rids . ids [ 0 ] ) ;
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_RemoveMemberFromForeignDomain ( b , talloc_tos ( ) ,
2008-04-09 15:35:49 +04:00
& builtin_handle ,
2011-01-14 19:05:32 +03:00
& user_sid ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-04-09 15:35:49 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_DeleteUser ( b , talloc_tos ( ) ,
& user_handle ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-04-09 15:35:49 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
werr = WERR_OK ;
done :
if ( is_valid_policy_hnd ( & user_handle ) ) {
2011-01-14 19:05:32 +03:00
dcerpc_samr_Close ( b , talloc_tos ( ) , & user_handle , & result ) ;
2008-04-09 15:35:49 +04:00
}
2008-07-18 00:44:24 +04:00
if ( ctx - > disable_policy_handle_cache ) {
libnetapi_samr_close_builtin_handle ( ctx , & builtin_handle ) ;
libnetapi_samr_close_domain_handle ( ctx , & domain_handle ) ;
libnetapi_samr_close_connect_handle ( ctx , & connect_handle ) ;
2008-04-09 15:35:49 +04:00
}
return werr ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetUserDel_l ( struct libnetapi_ctx * ctx ,
struct NetUserDel * r )
{
2008-08-12 17:25:06 +04:00
LIBNETAPI_REDIRECT_TO_LOCALHOST ( ctx , r , NetUserDel ) ;
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 ,
2008-08-28 13:57:43 +04:00
const struct dom_sid * domain_sid ,
2008-07-01 22:19:10 +04:00
uint32_t rid ,
uint32_t level ,
struct samr_UserInfo21 * * info21 ,
2008-08-28 13:57:43 +04:00
struct sec_desc_buf * * sec_desc ,
uint32_t * auth_flag_p )
2008-04-09 15:47:51 +04:00
{
2011-01-14 19:05:32 +03:00
NTSTATUS status , result ;
2008-07-01 22:19:10 +04:00
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 ;
2011-01-14 19:05:32 +03:00
struct dcerpc_binding_handle * b = pipe_cli - > binding_handle ;
2008-07-01 22:19:10 +04:00
ZERO_STRUCT ( user_handle ) ;
switch ( level ) {
case 0 :
2008-08-28 14:15:23 +04:00
break ;
2008-07-01 22:19:10 +04:00
case 1 :
2008-08-28 14:15:23 +04:00
access_mask | = SAMR_USER_ACCESS_GET_LOGONINFO |
SAMR_USER_ACCESS_GET_GROUPS ;
break ;
2008-07-01 22:19:10 +04:00
case 2 :
case 3 :
2008-08-28 14:21:13 +04:00
case 4 :
2008-07-01 22:19:10 +04:00
case 11 :
2008-08-28 14:21:13 +04:00
access_mask | = SAMR_USER_ACCESS_GET_LOGONINFO |
SAMR_USER_ACCESS_GET_GROUPS |
SAMR_USER_ACCESS_GET_LOCALE ;
break ;
case 10 :
2008-07-01 22:19:10 +04:00
case 20 :
case 23 :
break ;
default :
return NT_STATUS_INVALID_LEVEL ;
}
if ( level = = 0 ) {
return NT_STATUS_OK ;
}
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_OpenUser ( b , mem_ctx ,
2008-07-01 22:19:10 +04:00
domain_handle ,
access_mask ,
rid ,
2011-01-14 19:05:32 +03:00
& user_handle ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2011-01-14 19:05:32 +03:00
goto done ;
}
2008-07-01 22:19:10 +04:00
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_QueryUserInfo ( b , mem_ctx ,
2008-07-01 22:19:10 +04:00
& user_handle ,
21 ,
2011-01-14 19:05:32 +03:00
& user_info ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2011-01-14 19:05:32 +03:00
goto done ;
}
2008-07-01 22:19:10 +04:00
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_QuerySecurity ( b , mem_ctx ,
2008-07-01 22:19:10 +04:00
& user_handle ,
SECINFO_DACL ,
2011-01-14 19:05:32 +03:00
sec_desc ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2011-01-14 19:05:32 +03:00
goto done ;
}
2008-07-01 22:19:10 +04:00
2008-08-28 13:57:43 +04:00
if ( access_mask & SAMR_USER_ACCESS_GET_GROUPS ) {
struct lsa_SidArray sid_array ;
struct samr_Ids alias_rids ;
int i ;
uint32_t auth_flag = 0 ;
struct dom_sid sid ;
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_GetGroupsForUser ( b , mem_ctx ,
2008-07-01 22:19:10 +04:00
& user_handle ,
2011-01-14 19:05:32 +03:00
& rid_array ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2011-01-14 19:05:32 +03:00
goto done ;
}
2008-07-01 22:19:10 +04:00
2008-08-28 13:57:43 +04:00
sid_array . num_sids = rid_array - > count + 1 ;
sid_array . sids = talloc_array ( mem_ctx , struct lsa_SidPtr ,
sid_array . num_sids ) ;
NT_STATUS_HAVE_NO_MEMORY ( sid_array . sids ) ;
for ( i = 0 ; i < rid_array - > count ; i + + ) {
sid_compose ( & sid , domain_sid , rid_array - > rids [ i ] . rid ) ;
2010-08-26 19:21:39 +04:00
sid_array . sids [ i ] . sid = dom_sid_dup ( mem_ctx , & sid ) ;
2008-08-28 13:57:43 +04:00
NT_STATUS_HAVE_NO_MEMORY ( sid_array . sids [ i ] . sid ) ;
}
sid_compose ( & sid , domain_sid , rid ) ;
2010-08-26 19:21:39 +04:00
sid_array . sids [ i ] . sid = dom_sid_dup ( mem_ctx , & sid ) ;
2008-08-28 13:57:43 +04:00
NT_STATUS_HAVE_NO_MEMORY ( sid_array . sids [ i ] . sid ) ;
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_GetAliasMembership ( b , mem_ctx ,
2008-08-28 13:57:43 +04:00
builtin_handle ,
& sid_array ,
2011-01-14 19:05:32 +03:00
& alias_rids ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2011-01-14 19:05:32 +03:00
goto done ;
}
2008-08-28 13:57:43 +04:00
for ( i = 0 ; i < alias_rids . count ; i + + ) {
switch ( alias_rids . ids [ i ] ) {
case 550 : /* Print Operators */
auth_flag | = AF_OP_PRINT ;
break ;
case 549 : /* Server Operators */
auth_flag | = AF_OP_SERVER ;
break ;
case 548 : /* Account Operators */
auth_flag | = AF_OP_ACCOUNTS ;
break ;
default :
break ;
}
}
if ( auth_flag_p ) {
* auth_flag_p = auth_flag ;
}
2008-07-01 22:19:10 +04:00
}
* info21 = & user_info - > info21 ;
done :
if ( is_valid_policy_hnd ( & user_handle ) ) {
2011-01-14 19:05:32 +03:00
dcerpc_samr_Close ( b , mem_ctx , & user_handle , & result ) ;
2008-07-01 22:19:10 +04:00
}
return status ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-08-28 02:56:25 +04:00
static uint32_t samr_rid_to_priv_level ( uint32_t rid )
{
switch ( rid ) {
case DOMAIN_RID_ADMINISTRATOR :
return USER_PRIV_ADMIN ;
case DOMAIN_RID_GUEST :
return USER_PRIV_GUEST ;
default :
return USER_PRIV_USER ;
}
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-08-27 21:25:07 +04:00
static uint32_t samr_acb_flags_to_netapi_flags ( uint32_t acb )
{
uint32_t fl = UF_SCRIPT ; /* god knows why */
2009-06-12 17:20:48 +04:00
fl | = ds_acb2uf ( acb ) ;
2008-08-27 21:25:07 +04:00
return fl ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-08-28 14:15:23 +04:00
static NTSTATUS info21_to_USER_INFO_1 ( TALLOC_CTX * mem_ctx ,
const struct samr_UserInfo21 * i21 ,
struct USER_INFO_1 * i )
{
ZERO_STRUCTP ( i ) ;
i - > usri1_name = talloc_strdup ( mem_ctx , i21 - > account_name . string ) ;
NT_STATUS_HAVE_NO_MEMORY ( i - > usri1_name ) ;
i - > usri1_password = NULL ;
i - > usri1_password_age = time ( NULL ) - nt_time_to_unix ( i21 - > last_password_change ) ;
i - > usri1_priv = samr_rid_to_priv_level ( i21 - > rid ) ;
i - > usri1_home_dir = talloc_strdup ( mem_ctx , i21 - > home_directory . string ) ;
i - > usri1_comment = talloc_strdup ( mem_ctx , i21 - > description . string ) ;
i - > usri1_flags = samr_acb_flags_to_netapi_flags ( i21 - > acct_flags ) ;
i - > usri1_script_path = talloc_strdup ( mem_ctx , i21 - > logon_script . string ) ;
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-08-28 14:18:01 +04:00
static NTSTATUS info21_to_USER_INFO_2 ( TALLOC_CTX * mem_ctx ,
const struct samr_UserInfo21 * i21 ,
uint32_t auth_flag ,
struct USER_INFO_2 * i )
{
ZERO_STRUCTP ( i ) ;
i - > usri2_name = talloc_strdup ( mem_ctx , i21 - > account_name . string ) ;
NT_STATUS_HAVE_NO_MEMORY ( i - > usri2_name ) ;
i - > usri2_password = NULL ;
i - > usri2_password_age = time ( NULL ) - nt_time_to_unix ( i21 - > last_password_change ) ;
i - > usri2_priv = samr_rid_to_priv_level ( i21 - > rid ) ;
i - > usri2_home_dir = talloc_strdup ( mem_ctx , i21 - > home_directory . string ) ;
i - > usri2_comment = talloc_strdup ( mem_ctx , i21 - > description . string ) ;
i - > usri2_flags = samr_acb_flags_to_netapi_flags ( i21 - > acct_flags ) ;
i - > usri2_script_path = talloc_strdup ( mem_ctx , i21 - > logon_script . string ) ;
i - > usri2_auth_flags = auth_flag ;
i - > usri2_full_name = talloc_strdup ( mem_ctx , i21 - > full_name . string ) ;
i - > usri2_usr_comment = talloc_strdup ( mem_ctx , i21 - > comment . string ) ;
i - > usri2_parms = talloc_strndup ( mem_ctx , ( const char * ) i21 - > parameters . array , i21 - > parameters . size / 2 ) ;
i - > usri2_workstations = talloc_strdup ( mem_ctx , i21 - > workstations . string ) ;
i - > usri2_last_logon = nt_time_to_unix ( i21 - > last_logon ) ;
i - > usri2_last_logoff = nt_time_to_unix ( i21 - > last_logoff ) ;
i - > usri2_acct_expires = nt_time_to_unix ( i21 - > acct_expiry ) ;
i - > usri2_max_storage = USER_MAXSTORAGE_UNLIMITED ; /* FIXME */
i - > usri2_units_per_week = i21 - > logon_hours . units_per_week ;
i - > usri2_logon_hours = ( uint8_t * ) talloc_memdup ( mem_ctx , i21 - > logon_hours . bits , 21 ) ;
i - > usri2_bad_pw_count = i21 - > bad_password_count ;
i - > usri2_num_logons = i21 - > logon_count ;
i - > usri2_logon_server = talloc_strdup ( mem_ctx , " \\ \\ * " ) ;
i - > usri2_country_code = i21 - > country_code ;
i - > usri2_code_page = i21 - > code_page ;
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-08-28 14:20:04 +04:00
static NTSTATUS info21_to_USER_INFO_3 ( TALLOC_CTX * mem_ctx ,
const struct samr_UserInfo21 * i21 ,
uint32_t auth_flag ,
struct USER_INFO_3 * i )
{
ZERO_STRUCTP ( i ) ;
i - > usri3_name = talloc_strdup ( mem_ctx , i21 - > account_name . string ) ;
NT_STATUS_HAVE_NO_MEMORY ( i - > usri3_name ) ;
i - > usri3_password_age = time ( NULL ) - nt_time_to_unix ( i21 - > last_password_change ) ;
i - > usri3_priv = samr_rid_to_priv_level ( i21 - > rid ) ;
i - > usri3_home_dir = talloc_strdup ( mem_ctx , i21 - > home_directory . string ) ;
i - > usri3_comment = talloc_strdup ( mem_ctx , i21 - > description . string ) ;
i - > usri3_flags = samr_acb_flags_to_netapi_flags ( i21 - > acct_flags ) ;
i - > usri3_script_path = talloc_strdup ( mem_ctx , i21 - > logon_script . string ) ;
i - > usri3_auth_flags = auth_flag ;
i - > usri3_full_name = talloc_strdup ( mem_ctx , i21 - > full_name . string ) ;
i - > usri3_usr_comment = talloc_strdup ( mem_ctx , i21 - > comment . string ) ;
i - > usri3_parms = talloc_strndup ( mem_ctx , ( const char * ) i21 - > parameters . array , i21 - > parameters . size / 2 ) ;
i - > usri3_workstations = talloc_strdup ( mem_ctx , i21 - > workstations . string ) ;
i - > usri3_last_logon = nt_time_to_unix ( i21 - > last_logon ) ;
i - > usri3_last_logoff = nt_time_to_unix ( i21 - > last_logoff ) ;
i - > usri3_acct_expires = nt_time_to_unix ( i21 - > acct_expiry ) ;
i - > usri3_max_storage = USER_MAXSTORAGE_UNLIMITED ; /* FIXME */
i - > usri3_units_per_week = i21 - > logon_hours . units_per_week ;
i - > usri3_logon_hours = ( uint8_t * ) talloc_memdup ( mem_ctx , i21 - > logon_hours . bits , 21 ) ;
i - > usri3_bad_pw_count = i21 - > bad_password_count ;
i - > usri3_num_logons = i21 - > logon_count ;
i - > usri3_logon_server = talloc_strdup ( mem_ctx , " \\ \\ * " ) ;
i - > usri3_country_code = i21 - > country_code ;
i - > usri3_code_page = i21 - > code_page ;
i - > usri3_user_id = i21 - > rid ;
i - > usri3_primary_group_id = i21 - > primary_gid ;
i - > usri3_profile = talloc_strdup ( mem_ctx , i21 - > profile_path . string ) ;
i - > usri3_home_dir_drive = talloc_strdup ( mem_ctx , i21 - > home_drive . string ) ;
i - > usri3_password_expired = i21 - > password_expired ;
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-08-28 14:21:13 +04:00
static NTSTATUS info21_to_USER_INFO_4 ( TALLOC_CTX * mem_ctx ,
const struct samr_UserInfo21 * i21 ,
uint32_t auth_flag ,
struct dom_sid * domain_sid ,
struct USER_INFO_4 * i )
{
struct dom_sid sid ;
ZERO_STRUCTP ( i ) ;
i - > usri4_name = talloc_strdup ( mem_ctx , i21 - > account_name . string ) ;
NT_STATUS_HAVE_NO_MEMORY ( i - > usri4_name ) ;
i - > usri4_password_age = time ( NULL ) - nt_time_to_unix ( i21 - > last_password_change ) ;
i - > usri4_password = NULL ;
i - > usri4_priv = samr_rid_to_priv_level ( i21 - > rid ) ;
i - > usri4_home_dir = talloc_strdup ( mem_ctx , i21 - > home_directory . string ) ;
i - > usri4_comment = talloc_strdup ( mem_ctx , i21 - > description . string ) ;
i - > usri4_flags = samr_acb_flags_to_netapi_flags ( i21 - > acct_flags ) ;
i - > usri4_script_path = talloc_strdup ( mem_ctx , i21 - > logon_script . string ) ;
i - > usri4_auth_flags = auth_flag ;
i - > usri4_full_name = talloc_strdup ( mem_ctx , i21 - > full_name . string ) ;
i - > usri4_usr_comment = talloc_strdup ( mem_ctx , i21 - > comment . string ) ;
i - > usri4_parms = talloc_strndup ( mem_ctx , ( const char * ) i21 - > parameters . array , i21 - > parameters . size / 2 ) ;
i - > usri4_workstations = talloc_strdup ( mem_ctx , i21 - > workstations . string ) ;
i - > usri4_last_logon = nt_time_to_unix ( i21 - > last_logon ) ;
i - > usri4_last_logoff = nt_time_to_unix ( i21 - > last_logoff ) ;
i - > usri4_acct_expires = nt_time_to_unix ( i21 - > acct_expiry ) ;
i - > usri4_max_storage = USER_MAXSTORAGE_UNLIMITED ; /* FIXME */
i - > usri4_units_per_week = i21 - > logon_hours . units_per_week ;
i - > usri4_logon_hours = ( uint8_t * ) talloc_memdup ( mem_ctx , i21 - > logon_hours . bits , 21 ) ;
i - > usri4_bad_pw_count = i21 - > bad_password_count ;
i - > usri4_num_logons = i21 - > logon_count ;
i - > usri4_logon_server = talloc_strdup ( mem_ctx , " \\ \\ * " ) ;
i - > usri4_country_code = i21 - > country_code ;
i - > usri4_code_page = i21 - > code_page ;
if ( ! sid_compose ( & sid , domain_sid , i21 - > rid ) ) {
return NT_STATUS_NO_MEMORY ;
}
2010-08-26 19:21:39 +04:00
i - > usri4_user_sid = ( struct domsid * ) dom_sid_dup ( mem_ctx , & sid ) ;
2008-08-28 14:21:13 +04:00
i - > usri4_primary_group_id = i21 - > primary_gid ;
i - > usri4_profile = talloc_strdup ( mem_ctx , i21 - > profile_path . string ) ;
i - > usri4_home_dir_drive = talloc_strdup ( mem_ctx , i21 - > home_drive . string ) ;
i - > usri4_password_expired = i21 - > password_expired ;
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-08-28 14:05:43 +04:00
static NTSTATUS info21_to_USER_INFO_10 ( TALLOC_CTX * mem_ctx ,
const struct samr_UserInfo21 * i21 ,
struct USER_INFO_10 * i )
{
ZERO_STRUCTP ( i ) ;
i - > usri10_name = talloc_strdup ( mem_ctx , i21 - > account_name . string ) ;
NT_STATUS_HAVE_NO_MEMORY ( i - > usri10_name ) ;
i - > usri10_comment = talloc_strdup ( mem_ctx , i21 - > description . string ) ;
i - > usri10_full_name = talloc_strdup ( mem_ctx , i21 - > full_name . string ) ;
i - > usri10_usr_comment = talloc_strdup ( mem_ctx , i21 - > comment . string ) ;
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-08-28 14:22:19 +04:00
static NTSTATUS info21_to_USER_INFO_11 ( TALLOC_CTX * mem_ctx ,
const struct samr_UserInfo21 * i21 ,
uint32_t auth_flag ,
struct USER_INFO_11 * i )
{
ZERO_STRUCTP ( i ) ;
i - > usri11_name = talloc_strdup ( mem_ctx , i21 - > account_name . string ) ;
NT_STATUS_HAVE_NO_MEMORY ( i - > usri11_name ) ;
i - > usri11_comment = talloc_strdup ( mem_ctx , i21 - > description . string ) ;
i - > usri11_usr_comment = talloc_strdup ( mem_ctx , i21 - > comment . string ) ;
i - > usri11_full_name = talloc_strdup ( mem_ctx , i21 - > full_name . string ) ;
i - > usri11_priv = samr_rid_to_priv_level ( i21 - > rid ) ;
i - > usri11_auth_flags = auth_flag ;
i - > usri11_password_age = time ( NULL ) - nt_time_to_unix ( i21 - > last_password_change ) ;
i - > usri11_home_dir = talloc_strdup ( mem_ctx , i21 - > home_directory . string ) ;
i - > usri11_parms = talloc_strndup ( mem_ctx , ( const char * ) i21 - > parameters . array , i21 - > parameters . size / 2 ) ;
i - > usri11_last_logon = nt_time_to_unix ( i21 - > last_logon ) ;
i - > usri11_last_logoff = nt_time_to_unix ( i21 - > last_logoff ) ;
i - > usri11_bad_pw_count = i21 - > bad_password_count ;
i - > usri11_num_logons = i21 - > logon_count ;
i - > usri11_logon_server = talloc_strdup ( mem_ctx , " \\ \\ * " ) ;
i - > usri11_country_code = i21 - > country_code ;
i - > usri11_workstations = talloc_strdup ( mem_ctx , i21 - > workstations . string ) ;
i - > usri11_max_storage = USER_MAXSTORAGE_UNLIMITED ; /* FIXME */
i - > usri11_units_per_week = i21 - > logon_hours . units_per_week ;
i - > usri11_logon_hours = ( uint8_t * ) talloc_memdup ( mem_ctx , i21 - > logon_hours . bits , 21 ) ;
i - > usri11_code_page = i21 - > code_page ;
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-08-28 14:07:25 +04:00
static NTSTATUS info21_to_USER_INFO_20 ( TALLOC_CTX * mem_ctx ,
const struct samr_UserInfo21 * i21 ,
struct USER_INFO_20 * i )
{
ZERO_STRUCTP ( i ) ;
i - > usri20_name = talloc_strdup ( mem_ctx , i21 - > account_name . string ) ;
NT_STATUS_HAVE_NO_MEMORY ( i - > usri20_name ) ;
i - > usri20_comment = talloc_strdup ( mem_ctx , i21 - > description . string ) ;
i - > usri20_full_name = talloc_strdup ( mem_ctx , i21 - > full_name . string ) ;
i - > usri20_flags = samr_acb_flags_to_netapi_flags ( i21 - > acct_flags ) ;
i - > usri20_user_id = i21 - > rid ;
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-08-28 14:08:31 +04:00
static NTSTATUS info21_to_USER_INFO_23 ( TALLOC_CTX * mem_ctx ,
const struct samr_UserInfo21 * i21 ,
struct dom_sid * domain_sid ,
struct USER_INFO_23 * i )
{
struct dom_sid sid ;
ZERO_STRUCTP ( i ) ;
i - > usri23_name = talloc_strdup ( mem_ctx , i21 - > account_name . string ) ;
NT_STATUS_HAVE_NO_MEMORY ( i - > usri23_name ) ;
i - > usri23_comment = talloc_strdup ( mem_ctx , i21 - > description . string ) ;
i - > usri23_full_name = talloc_strdup ( mem_ctx , i21 - > full_name . string ) ;
i - > usri23_flags = samr_acb_flags_to_netapi_flags ( i21 - > acct_flags ) ;
if ( ! sid_compose ( & sid , domain_sid , i21 - > rid ) ) {
return NT_STATUS_NO_MEMORY ;
}
2010-08-26 19:21:39 +04:00
i - > usri23_user_sid = ( struct domsid * ) dom_sid_dup ( mem_ctx , & sid ) ;
2008-08-28 14:08:31 +04:00
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-07-01 22:19:10 +04:00
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 ;
2008-08-28 13:57:43 +04:00
uint32_t auth_flag = 0 ;
2008-07-01 22:19:10 +04:00
2008-07-19 01:35:33 +04:00
struct USER_INFO_0 info0 ;
2008-08-28 14:15:23 +04:00
struct USER_INFO_1 info1 ;
2008-08-28 14:18:01 +04:00
struct USER_INFO_2 info2 ;
2008-08-28 14:20:04 +04:00
struct USER_INFO_3 info3 ;
2008-08-28 14:21:13 +04:00
struct USER_INFO_4 info4 ;
2008-07-19 01:35:33 +04:00
struct USER_INFO_10 info10 ;
2008-08-28 14:22:19 +04:00
struct USER_INFO_11 info11 ;
2008-07-19 01:35:33 +04:00
struct USER_INFO_20 info20 ;
struct USER_INFO_23 info23 ;
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 :
2008-08-28 14:21:13 +04:00
case 4 :
2008-07-01 22:19:10 +04:00
case 10 :
case 11 :
case 20 :
case 23 :
break ;
default :
return NT_STATUS_INVALID_LEVEL ;
}
if ( level = = 0 ) {
2008-07-19 01:35:33 +04:00
info0 . usri0_name = talloc_strdup ( mem_ctx , user_name ) ;
NT_STATUS_HAVE_NO_MEMORY ( info0 . usri0_name ) ;
2008-07-01 22:19:10 +04:00
2008-07-19 01:35:33 +04:00
ADD_TO_ARRAY ( mem_ctx , struct USER_INFO_0 , info0 ,
2008-07-01 22:19:10 +04:00
( 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 ,
2008-08-28 13:57:43 +04:00
domain_sid ,
2008-07-01 22:19:10 +04:00
rid ,
level ,
& info21 ,
2008-08-28 13:57:43 +04:00
& sec_desc ,
& auth_flag ) ;
2008-07-01 22:19:10 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto done ;
}
switch ( level ) {
2008-08-28 14:15:23 +04:00
case 1 :
status = info21_to_USER_INFO_1 ( mem_ctx , info21 , & info1 ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
ADD_TO_ARRAY ( mem_ctx , struct USER_INFO_1 , info1 ,
( struct USER_INFO_1 * * ) buffer , num_entries ) ;
2008-08-28 14:18:01 +04:00
break ;
case 2 :
status = info21_to_USER_INFO_2 ( mem_ctx , info21 , auth_flag , & info2 ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
ADD_TO_ARRAY ( mem_ctx , struct USER_INFO_2 , info2 ,
( struct USER_INFO_2 * * ) buffer , num_entries ) ;
2008-08-28 14:20:04 +04:00
break ;
case 3 :
status = info21_to_USER_INFO_3 ( mem_ctx , info21 , auth_flag , & info3 ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
ADD_TO_ARRAY ( mem_ctx , struct USER_INFO_3 , info3 ,
( struct USER_INFO_3 * * ) buffer , num_entries ) ;
2008-08-28 14:21:13 +04:00
break ;
case 4 :
status = info21_to_USER_INFO_4 ( mem_ctx , info21 , auth_flag , domain_sid , & info4 ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
ADD_TO_ARRAY ( mem_ctx , struct USER_INFO_4 , info4 ,
( struct USER_INFO_4 * * ) buffer , num_entries ) ;
2008-08-28 14:15:23 +04:00
break ;
2008-07-01 22:19:10 +04:00
case 10 :
2008-08-28 14:05:43 +04:00
status = info21_to_USER_INFO_10 ( mem_ctx , info21 , & info10 ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
2008-07-01 22:19:10 +04:00
2008-07-19 01:35:33 +04:00
ADD_TO_ARRAY ( mem_ctx , struct USER_INFO_10 , info10 ,
2008-07-01 22:19:10 +04:00
( struct USER_INFO_10 * * ) buffer , num_entries ) ;
break ;
2008-08-28 14:22:19 +04:00
case 11 :
status = info21_to_USER_INFO_11 ( mem_ctx , info21 , auth_flag , & info11 ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
ADD_TO_ARRAY ( mem_ctx , struct USER_INFO_11 , info11 ,
( struct USER_INFO_11 * * ) buffer , num_entries ) ;
2008-07-01 22:19:10 +04:00
2008-08-28 14:22:19 +04:00
break ;
2008-07-01 22:19:10 +04:00
case 20 :
2008-08-28 14:07:25 +04:00
status = info21_to_USER_INFO_20 ( mem_ctx , info21 , & info20 ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
2008-07-01 22:19:10 +04:00
2008-07-19 01:35:33 +04:00
ADD_TO_ARRAY ( mem_ctx , struct USER_INFO_20 , info20 ,
2008-07-01 22:19:10 +04:00
( struct USER_INFO_20 * * ) buffer , num_entries ) ;
break ;
case 23 :
2008-08-28 14:08:31 +04:00
status = info21_to_USER_INFO_23 ( mem_ctx , info21 , domain_sid , & info23 ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
2008-07-01 22:19:10 +04:00
2008-07-19 01:35:33 +04:00
ADD_TO_ARRAY ( mem_ctx , struct USER_INFO_23 , info23 ,
2008-07-01 22:19:10 +04:00
( struct USER_INFO_23 * * ) buffer , num_entries ) ;
2008-04-09 15:47:51 +04:00
break ;
2008-08-28 14:08:31 +04:00
default :
return NT_STATUS_INVALID_LEVEL ;
2008-04-09 15:47:51 +04:00
}
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 rpc_pipe_client * pipe_cli = NULL ;
struct policy_handle connect_handle ;
struct dom_sid2 * domain_sid = NULL ;
2008-08-28 14:00:07 +04:00
struct policy_handle domain_handle , builtin_handle ;
2008-04-09 15:47:51 +04:00
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
2019-09-17 17:43:20 +03:00
NTSTATUS status ;
2011-01-14 19:05:32 +03:00
NTSTATUS result = NT_STATUS_OK ;
2008-04-09 15:47:51 +04:00
WERROR werr ;
2011-01-14 19:05:32 +03:00
struct dcerpc_binding_handle * b = NULL ;
2008-04-09 15:47:51 +04:00
ZERO_STRUCT ( connect_handle ) ;
ZERO_STRUCT ( domain_handle ) ;
2008-08-28 14:00:07 +04:00
ZERO_STRUCT ( builtin_handle ) ;
2008-04-09 15:47:51 +04:00
2008-07-01 22:19:10 +04:00
if ( ! r - > out . buffer ) {
2015-12-03 17:24:23 +03:00
return WERR_INVALID_PARAMETER ;
2008-07-01 22:19:10 +04:00
}
* r - > out . buffer = NULL ;
* r - > out . entries_read = 0 ;
2008-04-09 15:47:51 +04:00
switch ( r - > in . level ) {
case 0 :
2008-08-28 14:15:23 +04:00
case 1 :
2008-08-28 14:18:01 +04:00
case 2 :
2008-08-28 14:20:04 +04:00
case 3 :
2008-08-28 14:21:13 +04:00
case 4 :
2008-07-01 22:19:10 +04:00
case 10 :
2008-08-28 14:22:19 +04:00
case 11 :
2008-07-01 22:19:10 +04:00
case 20 :
case 23 :
2008-04-09 15:47:51 +04:00
break ;
2008-08-28 02:23:51 +04:00
default :
2015-12-03 17:24:41 +03:00
return WERR_INVALID_LEVEL ;
2008-04-09 15:47:51 +04:00
}
2008-08-12 19:59:23 +04:00
werr = libnetapi_open_pipe ( ctx , r - > in . server_name ,
2013-05-17 18:10:13 +04:00
& ndr_table_samr ,
2008-07-20 19:59:30 +04:00
& pipe_cli ) ;
2008-04-11 00:44:00 +04:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
2008-04-09 15:47:51 +04:00
goto done ;
}
2011-01-14 19:05:32 +03:00
b = pipe_cli - > binding_handle ;
2008-08-28 14:00:07 +04:00
werr = libnetapi_samr_open_builtin_domain ( ctx , pipe_cli ,
SAMR_ACCESS_ENUM_DOMAINS |
2009-04-16 02:40:00 +04:00
SAMR_ACCESS_LOOKUP_DOMAIN ,
2008-08-28 14:00:07 +04:00
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS ,
& connect_handle ,
& builtin_handle ) ;
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 |
2009-04-16 02:40:00 +04:00
SAMR_ACCESS_LOOKUP_DOMAIN ,
2008-06-03 01:55:45 +04:00
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 ;
}
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_EnumDomainUsers ( b ,
2008-04-09 15:47:51 +04:00
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 ,
2011-01-14 19:05:32 +03:00
& entries_read ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
werr = ntstatus_to_werror ( result ) ;
if ( NT_STATUS_IS_ERR ( result ) ) {
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 ,
2008-08-28 14:00:07 +04:00
& builtin_handle ,
2008-07-01 22:19:10 +04:00
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-07-18 00:44:24 +04:00
/* if last query */
2011-01-14 19:05:32 +03:00
if ( NT_STATUS_IS_OK ( result ) | |
NT_STATUS_IS_ERR ( result ) ) {
2008-07-18 00:44:24 +04:00
if ( ctx - > disable_policy_handle_cache ) {
libnetapi_samr_close_domain_handle ( ctx , & domain_handle ) ;
2008-08-28 14:00:07 +04:00
libnetapi_samr_close_builtin_handle ( ctx , & builtin_handle ) ;
2008-07-18 00:44:24 +04:00
libnetapi_samr_close_connect_handle ( ctx , & connect_handle ) ;
}
2008-04-09 15:47:51 +04:00
}
return werr ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetUserEnum_l ( struct libnetapi_ctx * ctx ,
struct NetUserEnum * r )
{
2008-08-12 17:25:06 +04:00
LIBNETAPI_REDIRECT_TO_LOCALHOST ( ctx , r , NetUserEnum ) ;
2008-04-09 15:47:51 +04:00
}
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 ;
2011-06-07 05:58:39 +04:00
user = talloc_zero_array ( mem_ctx ,
2008-04-13 21:12:31 +04:00
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 ) {
2015-12-03 17:24:14 +03:00
return WERR_NOT_ENOUGH_MEMORY ;
2008-04-13 21:12:31 +04:00
}
}
* 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 ;
2011-06-07 05:58:39 +04:00
machine = talloc_zero_array ( mem_ctx ,
2008-04-13 21:12:31 +04:00
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 ) {
2015-12-03 17:24:14 +03:00
return WERR_NOT_ENOUGH_MEMORY ;
2008-04-13 21:12:31 +04:00
}
}
* 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 ;
2011-06-07 05:58:39 +04:00
group = talloc_zero_array ( mem_ctx ,
2008-04-13 21:12:31 +04:00
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 ) {
2015-12-03 17:24:14 +03:00
return WERR_NOT_ENOUGH_MEMORY ;
2008-04-13 21:12:31 +04:00
}
}
* 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 :
2009-06-26 19:38:58 +04:00
break ;
2008-04-13 21:12:31 +04:00
}
2015-12-03 17:24:41 +03:00
return WERR_INVALID_LEVEL ;
2008-04-13 21:12:31 +04:00
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
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 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 ;
2011-01-14 19:05:32 +03:00
struct dcerpc_binding_handle * b = NULL ;
2008-04-13 21:12:31 +04:00
uint32_t total_size = 0 ;
uint32_t returned_size = 0 ;
2019-09-17 17:43:20 +03:00
NTSTATUS status ;
2011-01-14 19:05:32 +03:00
NTSTATUS result = NT_STATUS_OK ;
2008-04-13 21:12:31 +04:00
WERROR werr ;
2009-03-26 12:11:59 +03:00
WERROR werr_tmp ;
* r - > out . entries_read = 0 ;
2008-04-13 21:12:31 +04:00
ZERO_STRUCT ( connect_handle ) ;
ZERO_STRUCT ( domain_handle ) ;
switch ( r - > in . level ) {
case 1 :
case 2 :
case 3 :
break ;
default :
2015-12-03 17:24:41 +03:00
return WERR_INVALID_LEVEL ;
2008-04-13 21:12:31 +04:00
}
2008-08-12 19:59:23 +04:00
werr = libnetapi_open_pipe ( ctx , r - > in . server_name ,
2013-05-17 18:10:13 +04:00
& ndr_table_samr ,
2008-07-20 19:59:30 +04:00
& pipe_cli ) ;
2008-04-13 21:12:31 +04:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
2011-01-14 19:05:32 +03:00
b = pipe_cli - > binding_handle ;
2008-06-03 01:55:45 +04:00
werr = libnetapi_samr_open_domain ( ctx , pipe_cli ,
SAMR_ACCESS_ENUM_DOMAINS |
2009-04-16 02:40:00 +04:00
SAMR_ACCESS_LOOKUP_DOMAIN ,
2008-06-03 01:55:45 +04:00
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 ;
}
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_QueryDisplayInfo2 ( b ,
2008-04-13 21:12:31 +04:00
ctx ,
& domain_handle ,
r - > in . level ,
r - > in . idx ,
r - > in . entries_requested ,
r - > in . prefmaxlen ,
& total_size ,
& returned_size ,
2011-01-14 19:05:32 +03:00
& info ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
werr = ntstatus_to_werror ( result ) ;
if ( NT_STATUS_IS_ERR ( result ) ) {
2008-04-13 21:12:31 +04:00
goto done ;
}
2009-03-26 12:11:59 +03:00
werr_tmp = convert_samr_dispinfo_to_NET_DISPLAY ( ctx , & info ,
r - > in . level ,
r - > out . entries_read ,
r - > out . buffer ) ;
if ( ! W_ERROR_IS_OK ( werr_tmp ) ) {
werr = werr_tmp ;
}
2008-04-13 21:12:31 +04:00
done :
2008-07-18 00:44:24 +04:00
/* if last query */
2011-01-14 19:05:32 +03:00
if ( NT_STATUS_IS_OK ( result ) | |
NT_STATUS_IS_ERR ( result ) ) {
2008-07-18 00:44:24 +04:00
if ( ctx - > disable_policy_handle_cache ) {
libnetapi_samr_close_domain_handle ( ctx , & domain_handle ) ;
libnetapi_samr_close_connect_handle ( ctx , & connect_handle ) ;
}
2008-04-13 21:12:31 +04:00
}
return werr ;
2008-04-13 21:04:18 +04:00
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetQueryDisplayInformation_l ( struct libnetapi_ctx * ctx ,
struct NetQueryDisplayInformation * r )
{
2008-08-12 17:25:06 +04:00
LIBNETAPI_REDIRECT_TO_LOCALHOST ( ctx , r , NetQueryDisplayInformation ) ;
2008-04-13 21:04:18 +04:00
}
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 rpc_pipe_client * pipe_cli = NULL ;
2011-01-14 19:05:32 +03:00
NTSTATUS status , result ;
2008-07-18 00:45:09 +04:00
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 ;
2011-01-14 19:05:32 +03:00
struct dcerpc_binding_handle * b = NULL ;
2008-07-18 00:45:09 +04:00
ZERO_STRUCT ( connect_handle ) ;
ZERO_STRUCT ( domain_handle ) ;
ZERO_STRUCT ( builtin_handle ) ;
ZERO_STRUCT ( user_handle ) ;
if ( ! r - > out . buffer ) {
2015-12-03 17:24:23 +03:00
return WERR_INVALID_PARAMETER ;
2008-07-18 00:45:09 +04:00
}
switch ( r - > in . level ) {
case 0 :
2008-08-28 14:15:23 +04:00
case 1 :
2008-08-28 14:18:01 +04:00
case 2 :
2008-08-28 14:20:04 +04:00
case 3 :
2008-08-28 14:21:13 +04:00
case 4 :
2008-07-18 00:45:09 +04:00
case 10 :
2008-08-28 14:22:19 +04:00
case 11 :
2008-07-18 00:45:09 +04:00
case 20 :
case 23 :
break ;
2008-08-27 21:28:34 +04:00
default :
2015-12-03 17:24:41 +03:00
werr = WERR_INVALID_LEVEL ;
2008-08-27 21:28:34 +04:00
goto done ;
2008-07-18 00:45:09 +04:00
}
2008-08-12 19:59:23 +04:00
werr = libnetapi_open_pipe ( ctx , r - > in . server_name ,
2013-05-17 18:10:13 +04:00
& ndr_table_samr ,
2008-07-20 19:59:30 +04:00
& pipe_cli ) ;
2008-07-18 00:45:09 +04:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
2011-01-14 19:05:32 +03:00
b = pipe_cli - > binding_handle ;
2008-07-18 00:45:09 +04:00
werr = libnetapi_samr_open_domain ( ctx , pipe_cli ,
SAMR_ACCESS_ENUM_DOMAINS |
2009-04-16 02:40:00 +04:00
SAMR_ACCESS_LOOKUP_DOMAIN ,
2008-07-18 00:45:09 +04:00
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 |
2009-04-16 02:40:00 +04:00
SAMR_ACCESS_LOOKUP_DOMAIN ,
2008-07-18 00:45:09 +04:00
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 ) ;
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_LookupNames ( b , talloc_tos ( ) ,
2008-07-18 00:45:09 +04:00
& domain_handle ,
1 ,
& lsa_account_name ,
& user_rids ,
2011-01-14 19:05:32 +03:00
& name_types ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-07-18 00:45:09 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
2013-11-08 09:40:55 +04:00
if ( user_rids . count ! = 1 ) {
werr = WERR_BAD_NET_RESP ;
goto done ;
}
if ( name_types . count ! = 1 ) {
werr = WERR_BAD_NET_RESP ;
goto done ;
}
2008-07-18 00:45:09 +04:00
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 :
2011-01-14 19:05:32 +03:00
if ( is_valid_policy_hnd ( & user_handle ) & & b ) {
dcerpc_samr_Close ( b , talloc_tos ( ) , & user_handle , & result ) ;
2008-07-18 00:45:09 +04:00
}
2008-07-18 00:44:24 +04:00
if ( ctx - > disable_policy_handle_cache ) {
libnetapi_samr_close_domain_handle ( ctx , & domain_handle ) ;
libnetapi_samr_close_connect_handle ( ctx , & connect_handle ) ;
}
2008-07-18 00:45:09 +04:00
return werr ;
2008-07-16 12:47:38 +04:00
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetUserGetInfo_l ( struct libnetapi_ctx * ctx ,
struct NetUserGetInfo * r )
{
2008-08-12 17:25:06 +04:00
LIBNETAPI_REDIRECT_TO_LOCALHOST ( ctx , r , NetUserGetInfo ) ;
2008-07-16 12:47:38 +04:00
}
2008-07-17 03:00:33 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetUserSetInfo_r ( struct libnetapi_ctx * ctx ,
struct NetUserSetInfo * r )
{
2008-07-18 22:12:45 +04:00
struct rpc_pipe_client * pipe_cli = NULL ;
2011-01-14 19:05:32 +03:00
NTSTATUS status , result ;
2008-07-18 22:12:45 +04:00
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 ;
2008-08-27 02:33:49 +04:00
uint32_t user_mask = 0 ;
2008-07-18 22:12:45 +04:00
struct USER_INFO_X uX ;
2011-01-14 19:05:32 +03:00
struct dcerpc_binding_handle * b = NULL ;
2011-03-25 00:14:20 +03:00
DATA_BLOB session_key ;
2008-07-18 22:12:45 +04:00
ZERO_STRUCT ( connect_handle ) ;
ZERO_STRUCT ( domain_handle ) ;
ZERO_STRUCT ( builtin_handle ) ;
ZERO_STRUCT ( user_handle ) ;
if ( ! r - > in . buffer ) {
2015-12-03 17:24:23 +03:00
return WERR_INVALID_PARAMETER ;
2008-07-18 22:12:45 +04:00
}
switch ( r - > in . level ) {
case 0 :
2009-06-16 17:00:20 +04:00
user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES ;
break ;
2008-08-27 02:33:49 +04:00
case 1003 :
user_mask = SAMR_USER_ACCESS_SET_PASSWORD ;
break ;
2008-08-27 03:40:46 +04:00
case 1006 :
2008-07-18 22:12:45 +04:00
case 1007 :
2008-08-27 03:15:21 +04:00
case 1009 :
2008-08-27 03:04:21 +04:00
case 1011 :
2008-08-27 04:18:30 +04:00
case 1014 :
2008-08-27 03:47:33 +04:00
case 1052 :
2008-08-27 03:53:10 +04:00
case 1053 :
2008-08-27 02:33:49 +04:00
user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES ;
2008-07-18 22:12:45 +04:00
break ;
2008-08-27 03:36:49 +04:00
case 1012 :
2008-08-27 04:11:54 +04:00
case 1024 :
2008-08-27 03:36:49 +04:00
user_mask = SAMR_USER_ACCESS_SET_LOC_COM ;
2012-12-18 19:31:36 +04:00
break ;
2008-08-27 04:02:30 +04:00
case 1051 :
user_mask = SAMR_USER_ACCESS_SET_ATTRIBUTES |
SAMR_USER_ACCESS_GET_GROUPS ;
2008-08-27 03:36:49 +04:00
break ;
2008-09-16 19:53:06 +04:00
case 3 :
2010-06-03 12:36:05 +04:00
user_mask = SEC_STD_READ_CONTROL |
SEC_STD_WRITE_DAC |
2008-09-16 19:53:06 +04:00
SAMR_USER_ACCESS_GET_GROUPS |
SAMR_USER_ACCESS_SET_PASSWORD |
SAMR_USER_ACCESS_SET_ATTRIBUTES |
SAMR_USER_ACCESS_GET_ATTRIBUTES |
SAMR_USER_ACCESS_SET_LOC_COM ;
break ;
2008-08-27 13:55:57 +04:00
case 1 :
case 2 :
case 4 :
case 21 :
case 22 :
case 1005 :
case 1008 :
case 1010 :
case 1017 :
case 1020 :
2008-07-18 22:12:45 +04:00
werr = WERR_NOT_SUPPORTED ;
goto done ;
2008-08-27 13:55:57 +04:00
default :
2015-12-03 17:24:41 +03:00
werr = WERR_INVALID_LEVEL ;
2008-08-27 13:55:57 +04:00
goto done ;
2008-07-18 22:12:45 +04:00
}
2008-08-12 19:59:23 +04:00
werr = libnetapi_open_pipe ( ctx , r - > in . server_name ,
2013-05-17 18:10:13 +04:00
& ndr_table_samr ,
2008-07-18 22:12:45 +04:00
& pipe_cli ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
2011-01-14 19:05:32 +03:00
b = pipe_cli - > binding_handle ;
2008-07-18 22:12:45 +04:00
werr = libnetapi_samr_open_domain ( ctx , pipe_cli ,
SAMR_ACCESS_ENUM_DOMAINS |
2009-04-16 02:40:00 +04:00
SAMR_ACCESS_LOOKUP_DOMAIN ,
2008-07-18 22:12:45 +04:00
SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
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 |
2009-04-16 02:40:00 +04:00
SAMR_ACCESS_LOOKUP_DOMAIN ,
2008-07-18 22:12:45 +04:00
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 ) ;
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_LookupNames ( b , talloc_tos ( ) ,
2008-07-18 22:12:45 +04:00
& domain_handle ,
1 ,
& lsa_account_name ,
& user_rids ,
2011-01-14 19:05:32 +03:00
& name_types ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-07-18 22:12:45 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
2013-11-08 09:40:55 +04:00
if ( user_rids . count ! = 1 ) {
werr = WERR_BAD_NET_RESP ;
goto done ;
}
if ( name_types . count ! = 1 ) {
werr = WERR_BAD_NET_RESP ;
goto done ;
}
2008-07-18 22:12:45 +04:00
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_OpenUser ( b , talloc_tos ( ) ,
2008-07-18 22:12:45 +04:00
& domain_handle ,
2008-08-27 02:33:49 +04:00
user_mask ,
2008-07-18 22:12:45 +04:00
user_rids . ids [ 0 ] ,
2011-01-14 19:05:32 +03:00
& user_handle ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-07-18 22:12:45 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
status = construct_USER_INFO_X ( r - > in . level , r - > in . buffer , & uX ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
2024-09-14 16:51:20 +03:00
status = dcerpc_binding_handle_transport_session_key (
b , talloc_tos ( ) , & session_key ) ;
2011-03-25 00:14:20 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
2008-08-27 02:33:49 +04:00
status = set_user_info_USER_INFO_X ( ctx , pipe_cli ,
2011-03-25 00:14:20 +03:00
& session_key ,
2008-08-27 02:33:49 +04:00
& user_handle ,
& uX ) ;
2008-07-18 22:12:45 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
werr = WERR_OK ;
done :
2011-01-14 19:05:32 +03:00
if ( is_valid_policy_hnd ( & user_handle ) & & b ) {
dcerpc_samr_Close ( b , talloc_tos ( ) , & user_handle , & result ) ;
2008-07-18 22:12:45 +04:00
}
if ( ctx - > disable_policy_handle_cache ) {
libnetapi_samr_close_domain_handle ( ctx , & domain_handle ) ;
libnetapi_samr_close_builtin_handle ( ctx , & builtin_handle ) ;
libnetapi_samr_close_connect_handle ( ctx , & connect_handle ) ;
}
return werr ;
2008-07-17 03:00:33 +04:00
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetUserSetInfo_l ( struct libnetapi_ctx * ctx ,
struct NetUserSetInfo * r )
{
2008-08-12 17:25:06 +04:00
LIBNETAPI_REDIRECT_TO_LOCALHOST ( ctx , r , NetUserSetInfo ) ;
2008-07-17 03:00:33 +04:00
}
2008-07-31 18:43:27 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-07-31 21:26:29 +04:00
static NTSTATUS query_USER_MODALS_INFO_rpc ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_cli ,
struct policy_handle * domain_handle ,
struct samr_DomInfo1 * info1 ,
struct samr_DomInfo3 * info3 ,
struct samr_DomInfo5 * info5 ,
struct samr_DomInfo6 * info6 ,
struct samr_DomInfo7 * info7 ,
struct samr_DomInfo12 * info12 )
{
2011-01-14 19:05:32 +03:00
NTSTATUS status , result ;
2008-07-31 21:26:29 +04:00
union samr_DomainInfo * dom_info = NULL ;
2011-01-14 19:05:32 +03:00
struct dcerpc_binding_handle * b = pipe_cli - > binding_handle ;
2008-07-31 21:26:29 +04:00
if ( info1 ) {
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_QueryDomainInfo ( b , mem_ctx ,
2008-07-31 21:26:29 +04:00
domain_handle ,
1 ,
2011-01-14 19:05:32 +03:00
& dom_info ,
& result ) ;
2008-07-31 21:26:29 +04:00
NT_STATUS_NOT_OK_RETURN ( status ) ;
2011-01-14 19:05:32 +03:00
NT_STATUS_NOT_OK_RETURN ( result ) ;
2008-07-31 21:26:29 +04:00
* info1 = dom_info - > info1 ;
}
if ( info3 ) {
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_QueryDomainInfo ( b , mem_ctx ,
2008-07-31 21:26:29 +04:00
domain_handle ,
3 ,
2011-01-14 19:05:32 +03:00
& dom_info ,
& result ) ;
2008-07-31 21:26:29 +04:00
NT_STATUS_NOT_OK_RETURN ( status ) ;
2011-01-14 19:05:32 +03:00
NT_STATUS_NOT_OK_RETURN ( result ) ;
2008-07-31 21:26:29 +04:00
* info3 = dom_info - > info3 ;
}
if ( info5 ) {
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_QueryDomainInfo ( b , mem_ctx ,
2008-07-31 21:26:29 +04:00
domain_handle ,
5 ,
2011-01-14 19:05:32 +03:00
& dom_info ,
& result ) ;
2008-07-31 21:26:29 +04:00
NT_STATUS_NOT_OK_RETURN ( status ) ;
2011-01-14 19:05:32 +03:00
NT_STATUS_NOT_OK_RETURN ( result ) ;
2008-07-31 21:26:29 +04:00
* info5 = dom_info - > info5 ;
}
if ( info6 ) {
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_QueryDomainInfo ( b , mem_ctx ,
2008-07-31 21:26:29 +04:00
domain_handle ,
6 ,
2011-01-14 19:05:32 +03:00
& dom_info ,
& result ) ;
2008-07-31 21:26:29 +04:00
NT_STATUS_NOT_OK_RETURN ( status ) ;
2011-01-14 19:05:32 +03:00
NT_STATUS_NOT_OK_RETURN ( result ) ;
2008-07-31 21:26:29 +04:00
* info6 = dom_info - > info6 ;
}
if ( info7 ) {
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_QueryDomainInfo ( b , mem_ctx ,
2008-07-31 21:26:29 +04:00
domain_handle ,
7 ,
2011-01-14 19:05:32 +03:00
& dom_info ,
& result ) ;
2008-07-31 21:26:29 +04:00
NT_STATUS_NOT_OK_RETURN ( status ) ;
2011-01-14 19:05:32 +03:00
NT_STATUS_NOT_OK_RETURN ( result ) ;
2008-07-31 21:26:29 +04:00
* info7 = dom_info - > info7 ;
}
if ( info12 ) {
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_QueryDomainInfo2 ( b , mem_ctx ,
2008-07-31 21:26:29 +04:00
domain_handle ,
12 ,
2011-01-14 19:05:32 +03:00
& dom_info ,
& result ) ;
2008-07-31 21:26:29 +04:00
NT_STATUS_NOT_OK_RETURN ( status ) ;
2011-01-14 19:05:32 +03:00
NT_STATUS_NOT_OK_RETURN ( result ) ;
2008-07-31 21:26:29 +04:00
* info12 = dom_info - > info12 ;
}
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS query_USER_MODALS_INFO_0 ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_cli ,
struct policy_handle * domain_handle ,
struct USER_MODALS_INFO_0 * info0 )
{
NTSTATUS status ;
struct samr_DomInfo1 dom_info1 ;
struct samr_DomInfo3 dom_info3 ;
ZERO_STRUCTP ( info0 ) ;
status = query_USER_MODALS_INFO_rpc ( mem_ctx ,
pipe_cli ,
domain_handle ,
& dom_info1 ,
& dom_info3 ,
NULL ,
NULL ,
NULL ,
NULL ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
info0 - > usrmod0_min_passwd_len =
dom_info1 . min_password_length ;
info0 - > usrmod0_max_passwd_age =
nt_time_to_unix_abs ( ( NTTIME * ) & dom_info1 . max_password_age ) ;
info0 - > usrmod0_min_passwd_age =
nt_time_to_unix_abs ( ( NTTIME * ) & dom_info1 . min_password_age ) ;
info0 - > usrmod0_password_hist_len =
dom_info1 . password_history_length ;
info0 - > usrmod0_force_logoff =
nt_time_to_unix_abs ( & dom_info3 . force_logoff_time ) ;
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS query_USER_MODALS_INFO_1 ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_cli ,
struct policy_handle * domain_handle ,
struct USER_MODALS_INFO_1 * info1 )
{
NTSTATUS status ;
struct samr_DomInfo6 dom_info6 ;
struct samr_DomInfo7 dom_info7 ;
status = query_USER_MODALS_INFO_rpc ( mem_ctx ,
pipe_cli ,
domain_handle ,
NULL ,
NULL ,
NULL ,
& dom_info6 ,
& dom_info7 ,
NULL ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
info1 - > usrmod1_primary =
talloc_strdup ( mem_ctx , dom_info6 . primary . string ) ;
info1 - > usrmod1_role = dom_info7 . role ;
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS query_USER_MODALS_INFO_2 ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_cli ,
struct policy_handle * domain_handle ,
struct dom_sid * domain_sid ,
struct USER_MODALS_INFO_2 * info2 )
{
NTSTATUS status ;
struct samr_DomInfo5 dom_info5 ;
status = query_USER_MODALS_INFO_rpc ( mem_ctx ,
pipe_cli ,
domain_handle ,
NULL ,
NULL ,
& dom_info5 ,
NULL ,
NULL ,
NULL ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
info2 - > usrmod2_domain_name =
talloc_strdup ( mem_ctx , dom_info5 . domain_name . string ) ;
info2 - > usrmod2_domain_id =
2010-08-26 19:21:39 +04:00
( struct domsid * ) dom_sid_dup ( mem_ctx , domain_sid ) ;
2008-07-31 21:26:29 +04:00
NT_STATUS_HAVE_NO_MEMORY ( info2 - > usrmod2_domain_name ) ;
NT_STATUS_HAVE_NO_MEMORY ( info2 - > usrmod2_domain_id ) ;
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS query_USER_MODALS_INFO_3 ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_cli ,
struct policy_handle * domain_handle ,
struct USER_MODALS_INFO_3 * info3 )
{
NTSTATUS status ;
struct samr_DomInfo12 dom_info12 ;
status = query_USER_MODALS_INFO_rpc ( mem_ctx ,
pipe_cli ,
domain_handle ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
& dom_info12 ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
info3 - > usrmod3_lockout_duration =
nt_time_to_unix_abs ( & dom_info12 . lockout_duration ) ;
info3 - > usrmod3_lockout_observation_window =
nt_time_to_unix_abs ( & dom_info12 . lockout_window ) ;
info3 - > usrmod3_lockout_threshold =
dom_info12 . lockout_threshold ;
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS query_USER_MODALS_INFO_to_buffer ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_cli ,
uint32_t level ,
struct policy_handle * domain_handle ,
struct dom_sid * domain_sid ,
uint8_t * * buffer )
{
NTSTATUS status ;
struct USER_MODALS_INFO_0 info0 ;
struct USER_MODALS_INFO_1 info1 ;
struct USER_MODALS_INFO_2 info2 ;
struct USER_MODALS_INFO_3 info3 ;
if ( ! buffer ) {
return ERROR_INSUFFICIENT_BUFFER ;
}
switch ( level ) {
case 0 :
status = query_USER_MODALS_INFO_0 ( mem_ctx ,
pipe_cli ,
domain_handle ,
& info0 ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
* buffer = ( uint8_t * ) talloc_memdup ( mem_ctx , & info0 ,
sizeof ( info0 ) ) ;
break ;
case 1 :
status = query_USER_MODALS_INFO_1 ( mem_ctx ,
pipe_cli ,
domain_handle ,
& info1 ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
* buffer = ( uint8_t * ) talloc_memdup ( mem_ctx , & info1 ,
sizeof ( info1 ) ) ;
break ;
case 2 :
status = query_USER_MODALS_INFO_2 ( mem_ctx ,
pipe_cli ,
domain_handle ,
domain_sid ,
& info2 ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
* buffer = ( uint8_t * ) talloc_memdup ( mem_ctx , & info2 ,
sizeof ( info2 ) ) ;
break ;
case 3 :
status = query_USER_MODALS_INFO_3 ( mem_ctx ,
pipe_cli ,
domain_handle ,
& info3 ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
* buffer = ( uint8_t * ) talloc_memdup ( mem_ctx , & info3 ,
sizeof ( info3 ) ) ;
break ;
default :
break ;
}
NT_STATUS_HAVE_NO_MEMORY ( * buffer ) ;
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-07-31 18:43:27 +04:00
WERROR NetUserModalsGet_r ( struct libnetapi_ctx * ctx ,
struct NetUserModalsGet * r )
{
2008-07-31 21:26:29 +04:00
struct rpc_pipe_client * pipe_cli = NULL ;
NTSTATUS status ;
WERROR werr ;
struct policy_handle connect_handle , domain_handle ;
struct dom_sid2 * domain_sid = NULL ;
uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT ;
ZERO_STRUCT ( connect_handle ) ;
ZERO_STRUCT ( domain_handle ) ;
if ( ! r - > out . buffer ) {
2015-12-03 17:24:23 +03:00
return WERR_INVALID_PARAMETER ;
2008-07-31 21:26:29 +04:00
}
switch ( r - > in . level ) {
case 0 :
access_mask | = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 ;
break ;
case 1 :
case 2 :
access_mask | = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 ;
break ;
case 3 :
access_mask | = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 ;
break ;
default :
2015-12-03 17:24:41 +03:00
werr = WERR_INVALID_LEVEL ;
2008-07-31 21:26:29 +04:00
goto done ;
}
2008-08-12 19:59:23 +04:00
werr = libnetapi_open_pipe ( ctx , r - > in . server_name ,
2013-05-17 18:10:13 +04:00
& ndr_table_samr ,
2008-07-31 21:26:29 +04:00
& pipe_cli ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
werr = libnetapi_samr_open_domain ( ctx , pipe_cli ,
SAMR_ACCESS_ENUM_DOMAINS |
2009-04-16 02:40:00 +04:00
SAMR_ACCESS_LOOKUP_DOMAIN ,
2008-07-31 21:26:29 +04:00
access_mask ,
& connect_handle ,
& domain_handle ,
& domain_sid ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
/* 0: 1 + 3 */
/* 1: 6 + 7 */
/* 2: 5 */
/* 3: 12 (DomainInfo2) */
status = query_USER_MODALS_INFO_to_buffer ( ctx ,
pipe_cli ,
r - > in . level ,
& domain_handle ,
domain_sid ,
r - > out . buffer ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
done :
if ( ctx - > disable_policy_handle_cache ) {
libnetapi_samr_close_domain_handle ( ctx , & domain_handle ) ;
libnetapi_samr_close_connect_handle ( ctx , & connect_handle ) ;
}
return werr ;
2008-07-31 18:43:27 +04:00
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetUserModalsGet_l ( struct libnetapi_ctx * ctx ,
struct NetUserModalsGet * r )
{
2008-08-12 17:25:06 +04:00
LIBNETAPI_REDIRECT_TO_LOCALHOST ( ctx , r , NetUserModalsGet ) ;
2008-07-31 18:43:27 +04:00
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-07-31 23:08:31 +04:00
static NTSTATUS set_USER_MODALS_INFO_rpc ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_cli ,
struct policy_handle * domain_handle ,
struct samr_DomInfo1 * info1 ,
struct samr_DomInfo3 * info3 ,
struct samr_DomInfo12 * info12 )
{
2011-01-14 19:05:32 +03:00
NTSTATUS status , result ;
2008-07-31 23:08:31 +04:00
union samr_DomainInfo dom_info ;
2011-01-14 19:05:32 +03:00
struct dcerpc_binding_handle * b = pipe_cli - > binding_handle ;
2008-07-31 23:08:31 +04:00
if ( info1 ) {
ZERO_STRUCT ( dom_info ) ;
dom_info . info1 = * info1 ;
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_SetDomainInfo ( b , mem_ctx ,
2008-07-31 23:08:31 +04:00
domain_handle ,
1 ,
2011-01-14 19:05:32 +03:00
& dom_info ,
& result ) ;
2008-07-31 23:08:31 +04:00
NT_STATUS_NOT_OK_RETURN ( status ) ;
2011-01-14 19:05:32 +03:00
NT_STATUS_NOT_OK_RETURN ( result ) ;
2008-07-31 23:08:31 +04:00
}
if ( info3 ) {
ZERO_STRUCT ( dom_info ) ;
dom_info . info3 = * info3 ;
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_SetDomainInfo ( b , mem_ctx ,
2008-07-31 23:08:31 +04:00
domain_handle ,
3 ,
2011-01-14 19:05:32 +03:00
& dom_info ,
& result ) ;
2008-07-31 23:08:31 +04:00
NT_STATUS_NOT_OK_RETURN ( status ) ;
2011-01-14 19:05:32 +03:00
NT_STATUS_NOT_OK_RETURN ( result ) ;
2008-07-31 23:08:31 +04:00
}
if ( info12 ) {
ZERO_STRUCT ( dom_info ) ;
dom_info . info12 = * info12 ;
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_SetDomainInfo ( b , mem_ctx ,
2008-07-31 23:08:31 +04:00
domain_handle ,
12 ,
2011-01-14 19:05:32 +03:00
& dom_info ,
& result ) ;
2008-07-31 23:08:31 +04:00
NT_STATUS_NOT_OK_RETURN ( status ) ;
2011-01-14 19:05:32 +03:00
NT_STATUS_NOT_OK_RETURN ( result ) ;
2008-07-31 23:08:31 +04:00
}
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS set_USER_MODALS_INFO_0_buffer ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_cli ,
struct policy_handle * domain_handle ,
struct USER_MODALS_INFO_0 * info0 )
{
NTSTATUS status ;
struct samr_DomInfo1 dom_info_1 ;
struct samr_DomInfo3 dom_info_3 ;
status = query_USER_MODALS_INFO_rpc ( mem_ctx ,
pipe_cli ,
domain_handle ,
& dom_info_1 ,
& dom_info_3 ,
NULL ,
NULL ,
NULL ,
NULL ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
dom_info_1 . min_password_length =
info0 - > usrmod0_min_passwd_len ;
dom_info_1 . password_history_length =
info0 - > usrmod0_password_hist_len ;
unix_to_nt_time_abs ( ( NTTIME * ) & dom_info_1 . max_password_age ,
info0 - > usrmod0_max_passwd_age ) ;
unix_to_nt_time_abs ( ( NTTIME * ) & dom_info_1 . min_password_age ,
info0 - > usrmod0_min_passwd_age ) ;
unix_to_nt_time_abs ( & dom_info_3 . force_logoff_time ,
info0 - > usrmod0_force_logoff ) ;
return set_USER_MODALS_INFO_rpc ( mem_ctx ,
pipe_cli ,
domain_handle ,
& dom_info_1 ,
& dom_info_3 ,
NULL ) ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS set_USER_MODALS_INFO_3_buffer ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_cli ,
struct policy_handle * domain_handle ,
struct USER_MODALS_INFO_3 * info3 )
{
NTSTATUS status ;
struct samr_DomInfo12 dom_info_12 ;
status = query_USER_MODALS_INFO_rpc ( mem_ctx ,
pipe_cli ,
domain_handle ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
& dom_info_12 ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
unix_to_nt_time_abs ( ( NTTIME * ) & dom_info_12 . lockout_duration ,
info3 - > usrmod3_lockout_duration ) ;
unix_to_nt_time_abs ( ( NTTIME * ) & dom_info_12 . lockout_window ,
info3 - > usrmod3_lockout_observation_window ) ;
dom_info_12 . lockout_threshold = info3 - > usrmod3_lockout_threshold ;
return set_USER_MODALS_INFO_rpc ( mem_ctx ,
pipe_cli ,
domain_handle ,
NULL ,
NULL ,
& dom_info_12 ) ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS set_USER_MODALS_INFO_1001_buffer ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_cli ,
struct policy_handle * domain_handle ,
struct USER_MODALS_INFO_1001 * info1001 )
{
NTSTATUS status ;
struct samr_DomInfo1 dom_info_1 ;
status = query_USER_MODALS_INFO_rpc ( mem_ctx ,
pipe_cli ,
domain_handle ,
& dom_info_1 ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
dom_info_1 . min_password_length =
info1001 - > usrmod1001_min_passwd_len ;
return set_USER_MODALS_INFO_rpc ( mem_ctx ,
pipe_cli ,
domain_handle ,
& dom_info_1 ,
NULL ,
NULL ) ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS set_USER_MODALS_INFO_1002_buffer ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_cli ,
struct policy_handle * domain_handle ,
struct USER_MODALS_INFO_1002 * info1002 )
{
NTSTATUS status ;
struct samr_DomInfo1 dom_info_1 ;
status = query_USER_MODALS_INFO_rpc ( mem_ctx ,
pipe_cli ,
domain_handle ,
& dom_info_1 ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
unix_to_nt_time_abs ( ( NTTIME * ) & dom_info_1 . max_password_age ,
info1002 - > usrmod1002_max_passwd_age ) ;
return set_USER_MODALS_INFO_rpc ( mem_ctx ,
pipe_cli ,
domain_handle ,
& dom_info_1 ,
NULL ,
NULL ) ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS set_USER_MODALS_INFO_1003_buffer ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_cli ,
struct policy_handle * domain_handle ,
struct USER_MODALS_INFO_1003 * info1003 )
{
NTSTATUS status ;
struct samr_DomInfo1 dom_info_1 ;
status = query_USER_MODALS_INFO_rpc ( mem_ctx ,
pipe_cli ,
domain_handle ,
& dom_info_1 ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
unix_to_nt_time_abs ( ( NTTIME * ) & dom_info_1 . min_password_age ,
info1003 - > usrmod1003_min_passwd_age ) ;
return set_USER_MODALS_INFO_rpc ( mem_ctx ,
pipe_cli ,
domain_handle ,
& dom_info_1 ,
NULL ,
NULL ) ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS set_USER_MODALS_INFO_1004_buffer ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_cli ,
struct policy_handle * domain_handle ,
struct USER_MODALS_INFO_1004 * info1004 )
{
NTSTATUS status ;
struct samr_DomInfo3 dom_info_3 ;
status = query_USER_MODALS_INFO_rpc ( mem_ctx ,
pipe_cli ,
domain_handle ,
NULL ,
& dom_info_3 ,
NULL ,
NULL ,
NULL ,
NULL ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
unix_to_nt_time_abs ( & dom_info_3 . force_logoff_time ,
info1004 - > usrmod1004_force_logoff ) ;
return set_USER_MODALS_INFO_rpc ( mem_ctx ,
pipe_cli ,
domain_handle ,
NULL ,
& dom_info_3 ,
NULL ) ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS set_USER_MODALS_INFO_1005_buffer ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_cli ,
struct policy_handle * domain_handle ,
struct USER_MODALS_INFO_1005 * info1005 )
{
NTSTATUS status ;
struct samr_DomInfo1 dom_info_1 ;
status = query_USER_MODALS_INFO_rpc ( mem_ctx ,
pipe_cli ,
domain_handle ,
& dom_info_1 ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ) ;
NT_STATUS_NOT_OK_RETURN ( status ) ;
dom_info_1 . password_history_length =
info1005 - > usrmod1005_password_hist_len ;
return set_USER_MODALS_INFO_rpc ( mem_ctx ,
pipe_cli ,
domain_handle ,
& dom_info_1 ,
NULL ,
NULL ) ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS set_USER_MODALS_INFO_buffer ( TALLOC_CTX * mem_ctx ,
struct rpc_pipe_client * pipe_cli ,
uint32_t level ,
struct policy_handle * domain_handle ,
struct dom_sid * domain_sid ,
uint8_t * buffer )
{
struct USER_MODALS_INFO_0 * info0 ;
struct USER_MODALS_INFO_3 * info3 ;
struct USER_MODALS_INFO_1001 * info1001 ;
struct USER_MODALS_INFO_1002 * info1002 ;
struct USER_MODALS_INFO_1003 * info1003 ;
struct USER_MODALS_INFO_1004 * info1004 ;
struct USER_MODALS_INFO_1005 * info1005 ;
if ( ! buffer ) {
return ERROR_INSUFFICIENT_BUFFER ;
}
switch ( level ) {
case 0 :
info0 = ( struct USER_MODALS_INFO_0 * ) buffer ;
return set_USER_MODALS_INFO_0_buffer ( mem_ctx ,
pipe_cli ,
domain_handle ,
info0 ) ;
case 3 :
info3 = ( struct USER_MODALS_INFO_3 * ) buffer ;
return set_USER_MODALS_INFO_3_buffer ( mem_ctx ,
pipe_cli ,
domain_handle ,
info3 ) ;
case 1001 :
info1001 = ( struct USER_MODALS_INFO_1001 * ) buffer ;
return set_USER_MODALS_INFO_1001_buffer ( mem_ctx ,
pipe_cli ,
domain_handle ,
info1001 ) ;
case 1002 :
info1002 = ( struct USER_MODALS_INFO_1002 * ) buffer ;
return set_USER_MODALS_INFO_1002_buffer ( mem_ctx ,
pipe_cli ,
domain_handle ,
info1002 ) ;
case 1003 :
info1003 = ( struct USER_MODALS_INFO_1003 * ) buffer ;
return set_USER_MODALS_INFO_1003_buffer ( mem_ctx ,
pipe_cli ,
domain_handle ,
info1003 ) ;
case 1004 :
info1004 = ( struct USER_MODALS_INFO_1004 * ) buffer ;
return set_USER_MODALS_INFO_1004_buffer ( mem_ctx ,
pipe_cli ,
domain_handle ,
info1004 ) ;
case 1005 :
info1005 = ( struct USER_MODALS_INFO_1005 * ) buffer ;
return set_USER_MODALS_INFO_1005_buffer ( mem_ctx ,
pipe_cli ,
domain_handle ,
info1005 ) ;
default :
break ;
}
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-07-31 18:43:27 +04:00
WERROR NetUserModalsSet_r ( struct libnetapi_ctx * ctx ,
struct NetUserModalsSet * r )
{
2008-07-31 23:08:31 +04:00
struct rpc_pipe_client * pipe_cli = NULL ;
NTSTATUS status ;
WERROR werr ;
struct policy_handle connect_handle , domain_handle ;
struct dom_sid2 * domain_sid = NULL ;
uint32_t access_mask = SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT ;
ZERO_STRUCT ( connect_handle ) ;
ZERO_STRUCT ( domain_handle ) ;
if ( ! r - > in . buffer ) {
2015-12-03 17:24:23 +03:00
return WERR_INVALID_PARAMETER ;
2008-07-31 23:08:31 +04:00
}
switch ( r - > in . level ) {
case 0 :
access_mask | = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
SAMR_DOMAIN_ACCESS_SET_INFO_1 |
SAMR_DOMAIN_ACCESS_SET_INFO_2 ;
break ;
case 3 :
case 1001 :
case 1002 :
case 1003 :
case 1005 :
access_mask | = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 |
SAMR_DOMAIN_ACCESS_SET_INFO_1 ;
break ;
case 1004 :
access_mask | = SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 |
SAMR_DOMAIN_ACCESS_SET_INFO_2 ;
break ;
case 1 :
case 2 :
case 1006 :
case 1007 :
werr = WERR_NOT_SUPPORTED ;
break ;
default :
2015-12-03 17:24:41 +03:00
werr = WERR_INVALID_LEVEL ;
2008-07-31 23:08:31 +04:00
goto done ;
}
2008-08-12 19:59:23 +04:00
werr = libnetapi_open_pipe ( ctx , r - > in . server_name ,
2013-05-17 18:10:13 +04:00
& ndr_table_samr ,
2008-07-31 23:08:31 +04:00
& pipe_cli ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
werr = libnetapi_samr_open_domain ( ctx , pipe_cli ,
SAMR_ACCESS_ENUM_DOMAINS |
2009-04-16 02:40:00 +04:00
SAMR_ACCESS_LOOKUP_DOMAIN ,
2008-07-31 23:08:31 +04:00
access_mask ,
& connect_handle ,
& domain_handle ,
& domain_sid ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
status = set_USER_MODALS_INFO_buffer ( ctx ,
pipe_cli ,
r - > in . level ,
& domain_handle ,
domain_sid ,
r - > in . buffer ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
done :
if ( ctx - > disable_policy_handle_cache ) {
libnetapi_samr_close_domain_handle ( ctx , & domain_handle ) ;
libnetapi_samr_close_connect_handle ( ctx , & connect_handle ) ;
}
return werr ;
2008-07-31 18:43:27 +04:00
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetUserModalsSet_l ( struct libnetapi_ctx * ctx ,
struct NetUserModalsSet * r )
{
2008-08-12 17:25:06 +04:00
LIBNETAPI_REDIRECT_TO_LOCALHOST ( ctx , r , NetUserModalsSet ) ;
2008-07-31 18:43:27 +04:00
}
2008-08-27 13:49:55 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-09-08 18:42:10 +04:00
NTSTATUS add_GROUP_USERS_INFO_X_buffer ( TALLOC_CTX * mem_ctx ,
uint32_t level ,
const char * group_name ,
uint32_t attributes ,
uint8_t * * buffer ,
uint32_t * num_entries )
2008-08-27 15:37:56 +04:00
{
struct GROUP_USERS_INFO_0 u0 ;
struct GROUP_USERS_INFO_1 u1 ;
switch ( level ) {
case 0 :
2008-10-23 05:32:38 +04:00
if ( group_name ) {
u0 . grui0_name = talloc_strdup ( mem_ctx , group_name ) ;
NT_STATUS_HAVE_NO_MEMORY ( u0 . grui0_name ) ;
} else {
u0 . grui0_name = NULL ;
}
2008-08-27 15:37:56 +04:00
ADD_TO_ARRAY ( mem_ctx , struct GROUP_USERS_INFO_0 , u0 ,
( struct GROUP_USERS_INFO_0 * * ) buffer , num_entries ) ;
break ;
case 1 :
2008-10-23 05:32:38 +04:00
if ( group_name ) {
u1 . grui1_name = talloc_strdup ( mem_ctx , group_name ) ;
NT_STATUS_HAVE_NO_MEMORY ( u1 . grui1_name ) ;
} else {
u1 . grui1_name = NULL ;
}
2008-08-27 15:37:56 +04:00
u1 . grui1_attributes = attributes ;
ADD_TO_ARRAY ( mem_ctx , struct GROUP_USERS_INFO_1 , u1 ,
( struct GROUP_USERS_INFO_1 * * ) buffer , num_entries ) ;
break ;
default :
return NT_STATUS_INVALID_INFO_CLASS ;
}
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-08-27 13:49:55 +04:00
WERROR NetUserGetGroups_r ( struct libnetapi_ctx * ctx ,
struct NetUserGetGroups * r )
{
2008-08-27 15:37:56 +04:00
struct rpc_pipe_client * pipe_cli = NULL ;
struct policy_handle connect_handle , domain_handle , user_handle ;
struct lsa_String lsa_account_name ;
struct dom_sid2 * domain_sid = NULL ;
struct samr_Ids user_rids , name_types ;
struct samr_RidWithAttributeArray * rid_array = NULL ;
struct lsa_Strings names ;
struct samr_Ids types ;
uint32_t * rids = NULL ;
int i ;
uint32_t entries_read = 0 ;
2019-09-17 17:43:20 +03:00
NTSTATUS status ;
2011-01-14 19:05:32 +03:00
NTSTATUS result = NT_STATUS_OK ;
2008-08-27 15:37:56 +04:00
WERROR werr ;
2011-01-14 19:05:32 +03:00
struct dcerpc_binding_handle * b = NULL ;
2008-08-27 15:37:56 +04:00
ZERO_STRUCT ( connect_handle ) ;
ZERO_STRUCT ( domain_handle ) ;
if ( ! r - > out . buffer ) {
2015-12-03 17:24:23 +03:00
return WERR_INVALID_PARAMETER ;
2008-08-27 15:37:56 +04:00
}
* r - > out . buffer = NULL ;
* r - > out . entries_read = 0 ;
2009-03-20 13:21:36 +03:00
* r - > out . total_entries = 0 ;
2008-08-27 15:37:56 +04:00
switch ( r - > in . level ) {
case 0 :
case 1 :
break ;
default :
2015-12-03 17:24:41 +03:00
return WERR_INVALID_LEVEL ;
2008-08-27 15:37:56 +04:00
}
werr = libnetapi_open_pipe ( ctx , r - > in . server_name ,
2013-05-17 18:10:13 +04:00
& ndr_table_samr ,
2008-08-27 15:37:56 +04:00
& pipe_cli ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
2011-01-14 19:05:32 +03:00
b = pipe_cli - > binding_handle ;
2008-08-27 15:37:56 +04:00
werr = libnetapi_samr_open_domain ( ctx , pipe_cli ,
SAMR_ACCESS_ENUM_DOMAINS |
2009-04-16 02:40:00 +04:00
SAMR_ACCESS_LOOKUP_DOMAIN ,
2008-08-27 15:37:56 +04:00
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT ,
& connect_handle ,
& domain_handle ,
& domain_sid ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
init_lsa_String ( & lsa_account_name , r - > in . user_name ) ;
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_LookupNames ( b , talloc_tos ( ) ,
2008-08-27 15:37:56 +04:00
& domain_handle ,
1 ,
& lsa_account_name ,
& user_rids ,
2011-01-14 19:05:32 +03:00
& name_types ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-08-27 15:37:56 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
2013-11-08 09:40:55 +04:00
if ( user_rids . count ! = 1 ) {
werr = WERR_BAD_NET_RESP ;
goto done ;
}
if ( name_types . count ! = 1 ) {
werr = WERR_BAD_NET_RESP ;
goto done ;
}
2008-08-27 15:37:56 +04:00
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_OpenUser ( b , talloc_tos ( ) ,
2008-08-27 15:37:56 +04:00
& domain_handle ,
SAMR_USER_ACCESS_GET_GROUPS ,
user_rids . ids [ 0 ] ,
2011-01-14 19:05:32 +03:00
& user_handle ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-08-27 15:37:56 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_GetGroupsForUser ( b , talloc_tos ( ) ,
2008-08-27 15:37:56 +04:00
& user_handle ,
2011-01-14 19:05:32 +03:00
& rid_array ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-08-27 15:37:56 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
rids = talloc_array ( ctx , uint32_t , rid_array - > count ) ;
if ( ! rids ) {
2015-12-03 17:24:14 +03:00
werr = WERR_NOT_ENOUGH_MEMORY ;
2008-08-27 15:37:56 +04:00
goto done ;
}
for ( i = 0 ; i < rid_array - > count ; i + + ) {
rids [ i ] = rid_array - > rids [ i ] . rid ;
}
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_LookupRids ( b , talloc_tos ( ) ,
2008-08-27 15:37:56 +04:00
& domain_handle ,
rid_array - > count ,
rids ,
& names ,
2011-01-14 19:05:32 +03:00
& types ,
& result ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-08-27 15:37:56 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
2011-01-14 19:05:32 +03:00
if ( ! NT_STATUS_IS_OK ( result ) & &
! NT_STATUS_EQUAL ( result , STATUS_SOME_UNMAPPED ) ) {
werr = ntstatus_to_werror ( result ) ;
goto done ;
}
2013-11-08 10:41:22 +04:00
if ( names . count ! = rid_array - > count ) {
werr = WERR_BAD_NET_RESP ;
goto done ;
}
if ( types . count ! = rid_array - > count ) {
werr = WERR_BAD_NET_RESP ;
goto done ;
}
2008-08-27 15:37:56 +04:00
2008-10-23 05:32:15 +04:00
for ( i = 0 ; i < names . count ; i + + ) {
2008-08-27 15:37:56 +04:00
status = add_GROUP_USERS_INFO_X_buffer ( ctx ,
r - > in . level ,
names . names [ i ] . string ,
rid_array - > rids [ i ] . attributes ,
r - > out . buffer ,
& entries_read ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
}
2009-03-20 13:21:36 +03:00
* r - > out . entries_read = entries_read ;
* r - > out . total_entries = entries_read ;
2008-08-27 15:37:56 +04:00
done :
if ( ctx - > disable_policy_handle_cache ) {
libnetapi_samr_close_domain_handle ( ctx , & domain_handle ) ;
libnetapi_samr_close_connect_handle ( ctx , & connect_handle ) ;
}
return werr ;
2008-08-27 13:49:55 +04:00
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetUserGetGroups_l ( struct libnetapi_ctx * ctx ,
struct NetUserGetGroups * r )
{
LIBNETAPI_REDIRECT_TO_LOCALHOST ( ctx , r , NetUserGetGroups ) ;
}
2008-09-05 18:51:55 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetUserSetGroups_r ( struct libnetapi_ctx * ctx ,
struct NetUserSetGroups * r )
{
2008-09-08 21:10:00 +04:00
struct rpc_pipe_client * pipe_cli = NULL ;
struct policy_handle connect_handle , domain_handle , user_handle , group_handle ;
struct lsa_String lsa_account_name ;
struct dom_sid2 * domain_sid = NULL ;
struct samr_Ids user_rids , name_types ;
struct samr_Ids group_rids ;
struct samr_RidWithAttributeArray * rid_array = NULL ;
2008-09-12 13:28:03 +04:00
struct lsa_String * lsa_names = NULL ;
2008-09-08 21:10:00 +04:00
uint32_t * add_rids = NULL ;
uint32_t * del_rids = NULL ;
size_t num_add_rids = 0 ;
size_t num_del_rids = 0 ;
uint32_t * member_rids = NULL ;
struct GROUP_USERS_INFO_0 * i0 = NULL ;
struct GROUP_USERS_INFO_1 * i1 = NULL ;
int i , k ;
2019-09-17 17:43:20 +03:00
NTSTATUS status ;
2011-01-14 19:05:32 +03:00
NTSTATUS result = NT_STATUS_OK ;
2008-09-08 21:10:00 +04:00
WERROR werr ;
2011-01-14 19:05:32 +03:00
struct dcerpc_binding_handle * b = NULL ;
2008-09-08 21:10:00 +04:00
ZERO_STRUCT ( connect_handle ) ;
ZERO_STRUCT ( domain_handle ) ;
2012-12-06 21:15:12 +04:00
ZERO_STRUCT ( group_handle ) ;
2008-09-08 21:10:00 +04:00
if ( ! r - > in . buffer ) {
2015-12-03 17:24:23 +03:00
return WERR_INVALID_PARAMETER ;
2008-09-08 21:10:00 +04:00
}
switch ( r - > in . level ) {
case 0 :
case 1 :
break ;
default :
2015-12-03 17:24:41 +03:00
return WERR_INVALID_LEVEL ;
2008-09-08 21:10:00 +04:00
}
werr = libnetapi_open_pipe ( ctx , r - > in . server_name ,
2013-05-17 18:10:13 +04:00
& ndr_table_samr ,
2008-09-08 21:10:00 +04:00
& pipe_cli ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
2011-01-14 19:05:32 +03:00
b = pipe_cli - > binding_handle ;
2008-09-08 21:10:00 +04:00
werr = libnetapi_samr_open_domain ( ctx , pipe_cli ,
SAMR_ACCESS_ENUM_DOMAINS |
2009-04-16 02:40:00 +04:00
SAMR_ACCESS_LOOKUP_DOMAIN ,
2008-09-08 21:10:00 +04:00
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT ,
& connect_handle ,
& domain_handle ,
& domain_sid ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
init_lsa_String ( & lsa_account_name , r - > in . user_name ) ;
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_LookupNames ( b , talloc_tos ( ) ,
2008-09-08 21:10:00 +04:00
& domain_handle ,
1 ,
& lsa_account_name ,
& user_rids ,
2011-01-14 19:05:32 +03:00
& name_types ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-09-08 21:10:00 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
2013-11-08 09:40:55 +04:00
if ( user_rids . count ! = 1 ) {
werr = WERR_BAD_NET_RESP ;
goto done ;
}
if ( name_types . count ! = 1 ) {
werr = WERR_BAD_NET_RESP ;
goto done ;
}
2008-09-08 21:10:00 +04:00
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_OpenUser ( b , talloc_tos ( ) ,
2008-09-08 21:10:00 +04:00
& domain_handle ,
SAMR_USER_ACCESS_GET_GROUPS ,
user_rids . ids [ 0 ] ,
2011-01-14 19:05:32 +03:00
& user_handle ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-09-08 21:10:00 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
switch ( r - > in . level ) {
case 0 :
i0 = ( struct GROUP_USERS_INFO_0 * ) r - > in . buffer ;
break ;
case 1 :
i1 = ( struct GROUP_USERS_INFO_1 * ) r - > in . buffer ;
break ;
}
2008-09-12 13:28:03 +04:00
lsa_names = talloc_array ( ctx , struct lsa_String , r - > in . num_entries ) ;
if ( ! lsa_names ) {
2015-12-03 17:24:14 +03:00
werr = WERR_NOT_ENOUGH_MEMORY ;
2008-09-12 13:28:03 +04:00
goto done ;
}
2008-09-08 21:10:00 +04:00
for ( i = 0 ; i < r - > in . num_entries ; i + + ) {
switch ( r - > in . level ) {
case 0 :
2008-09-12 13:28:03 +04:00
init_lsa_String ( & lsa_names [ i ] , i0 - > grui0_name ) ;
2008-09-08 21:10:00 +04:00
i0 + + ;
break ;
case 1 :
2008-09-12 13:28:03 +04:00
init_lsa_String ( & lsa_names [ i ] , i1 - > grui1_name ) ;
2008-09-08 21:10:00 +04:00
i1 + + ;
break ;
}
2008-09-12 13:28:03 +04:00
}
2008-09-08 21:10:00 +04:00
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_LookupNames ( b , talloc_tos ( ) ,
2008-09-12 13:28:03 +04:00
& domain_handle ,
r - > in . num_entries ,
lsa_names ,
& group_rids ,
2011-01-14 19:05:32 +03:00
& name_types ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-09-12 13:28:03 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
2008-09-08 21:10:00 +04:00
}
2013-11-08 09:40:55 +04:00
if ( group_rids . count ! = r - > in . num_entries ) {
werr = WERR_BAD_NET_RESP ;
goto done ;
}
if ( name_types . count ! = r - > in . num_entries ) {
werr = WERR_BAD_NET_RESP ;
goto done ;
}
2008-09-08 21:10:00 +04:00
2008-09-12 13:28:03 +04:00
member_rids = group_rids . ids ;
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_GetGroupsForUser ( b , talloc_tos ( ) ,
2008-09-08 21:10:00 +04:00
& user_handle ,
2011-01-14 19:05:32 +03:00
& rid_array ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-09-08 21:10:00 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
/* add list */
for ( i = 0 ; i < r - > in . num_entries ; i + + ) {
bool already_member = false ;
for ( k = 0 ; k < rid_array - > count ; k + + ) {
if ( member_rids [ i ] = = rid_array - > rids [ k ] . rid ) {
already_member = true ;
break ;
}
}
if ( ! already_member ) {
if ( ! add_rid_to_array_unique ( ctx ,
member_rids [ i ] ,
& add_rids , & num_add_rids ) ) {
2015-12-03 17:24:20 +03:00
werr = WERR_GEN_FAILURE ;
2008-09-08 21:10:00 +04:00
goto done ;
}
}
}
/* del list */
for ( k = 0 ; k < rid_array - > count ; k + + ) {
bool keep_member = false ;
for ( i = 0 ; i < r - > in . num_entries ; i + + ) {
if ( member_rids [ i ] = = rid_array - > rids [ k ] . rid ) {
keep_member = true ;
break ;
}
}
if ( ! keep_member ) {
if ( ! add_rid_to_array_unique ( ctx ,
rid_array - > rids [ k ] . rid ,
& del_rids , & num_del_rids ) ) {
2015-12-03 17:24:20 +03:00
werr = WERR_GEN_FAILURE ;
2008-09-08 21:10:00 +04:00
goto done ;
}
}
}
/* add list */
for ( i = 0 ; i < num_add_rids ; i + + ) {
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_OpenGroup ( b , talloc_tos ( ) ,
2008-09-08 21:10:00 +04:00
& domain_handle ,
SAMR_GROUP_ACCESS_ADD_MEMBER ,
add_rids [ i ] ,
2011-01-14 19:05:32 +03:00
& group_handle ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-09-08 21:10:00 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_AddGroupMember ( b , talloc_tos ( ) ,
2008-09-08 21:10:00 +04:00
& group_handle ,
user_rids . ids [ 0 ] ,
2011-01-14 19:05:32 +03:00
7 /* ? */ ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-09-08 21:10:00 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
if ( is_valid_policy_hnd ( & group_handle ) ) {
2011-01-14 19:05:32 +03:00
dcerpc_samr_Close ( b , talloc_tos ( ) , & group_handle , & result ) ;
2008-09-08 21:10:00 +04:00
}
}
/* del list */
for ( i = 0 ; i < num_del_rids ; i + + ) {
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_OpenGroup ( b , talloc_tos ( ) ,
2008-09-08 21:10:00 +04:00
& domain_handle ,
SAMR_GROUP_ACCESS_REMOVE_MEMBER ,
del_rids [ i ] ,
2011-01-14 19:05:32 +03:00
& group_handle ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-09-08 21:10:00 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_DeleteGroupMember ( b , talloc_tos ( ) ,
2008-09-08 21:10:00 +04:00
& group_handle ,
2011-01-14 19:05:32 +03:00
user_rids . ids [ 0 ] ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-09-08 21:10:00 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
if ( is_valid_policy_hnd ( & group_handle ) ) {
2011-01-14 19:05:32 +03:00
dcerpc_samr_Close ( b , talloc_tos ( ) , & group_handle , & result ) ;
2008-09-08 21:10:00 +04:00
}
}
werr = WERR_OK ;
done :
if ( is_valid_policy_hnd ( & group_handle ) ) {
2011-01-14 19:05:32 +03:00
dcerpc_samr_Close ( b , talloc_tos ( ) , & group_handle , & result ) ;
2008-09-08 21:10:00 +04:00
}
if ( ctx - > disable_policy_handle_cache ) {
libnetapi_samr_close_domain_handle ( ctx , & domain_handle ) ;
libnetapi_samr_close_connect_handle ( ctx , & connect_handle ) ;
}
return werr ;
2008-09-05 18:51:55 +04:00
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetUserSetGroups_l ( struct libnetapi_ctx * ctx ,
struct NetUserSetGroups * r )
{
LIBNETAPI_REDIRECT_TO_LOCALHOST ( ctx , r , NetUserSetGroups ) ;
}
2008-09-09 15:42:27 +04:00
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-09-09 20:44:40 +04:00
static NTSTATUS add_LOCALGROUP_USERS_INFO_X_buffer ( TALLOC_CTX * mem_ctx ,
uint32_t level ,
const char * group_name ,
uint8_t * * buffer ,
uint32_t * num_entries )
{
struct LOCALGROUP_USERS_INFO_0 u0 ;
switch ( level ) {
case 0 :
u0 . lgrui0_name = talloc_strdup ( mem_ctx , group_name ) ;
NT_STATUS_HAVE_NO_MEMORY ( u0 . lgrui0_name ) ;
ADD_TO_ARRAY ( mem_ctx , struct LOCALGROUP_USERS_INFO_0 , u0 ,
( struct LOCALGROUP_USERS_INFO_0 * * ) buffer , num_entries ) ;
break ;
default :
return NT_STATUS_INVALID_INFO_CLASS ;
}
return NT_STATUS_OK ;
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-09-09 15:42:27 +04:00
WERROR NetUserGetLocalGroups_r ( struct libnetapi_ctx * ctx ,
struct NetUserGetLocalGroups * r )
{
2008-09-09 20:44:40 +04:00
struct rpc_pipe_client * pipe_cli = NULL ;
struct policy_handle connect_handle , domain_handle , user_handle ,
builtin_handle ;
struct lsa_String lsa_account_name ;
struct dom_sid2 * domain_sid = NULL ;
struct samr_Ids user_rids , name_types ;
struct samr_RidWithAttributeArray * rid_array = NULL ;
struct lsa_Strings names ;
struct samr_Ids types ;
uint32_t * rids = NULL ;
size_t num_rids = 0 ;
struct dom_sid user_sid ;
struct lsa_SidArray sid_array ;
struct samr_Ids domain_rids ;
struct samr_Ids builtin_rids ;
int i ;
uint32_t entries_read = 0 ;
2019-09-17 17:43:20 +03:00
NTSTATUS status ;
2011-01-14 19:05:32 +03:00
NTSTATUS result = NT_STATUS_OK ;
2008-09-09 20:44:40 +04:00
WERROR werr ;
2011-01-14 19:05:32 +03:00
struct dcerpc_binding_handle * b = NULL ;
2008-09-09 20:44:40 +04:00
ZERO_STRUCT ( connect_handle ) ;
ZERO_STRUCT ( domain_handle ) ;
if ( ! r - > out . buffer ) {
2015-12-03 17:24:23 +03:00
return WERR_INVALID_PARAMETER ;
2008-09-09 20:44:40 +04:00
}
* r - > out . buffer = NULL ;
* r - > out . entries_read = 0 ;
2009-03-20 13:19:59 +03:00
* r - > out . total_entries = 0 ;
2008-09-09 20:44:40 +04:00
switch ( r - > in . level ) {
case 0 :
case 1 :
break ;
default :
2015-12-03 17:24:41 +03:00
return WERR_INVALID_LEVEL ;
2008-09-09 20:44:40 +04:00
}
werr = libnetapi_open_pipe ( ctx , r - > in . server_name ,
2013-05-17 18:10:13 +04:00
& ndr_table_samr ,
2008-09-09 20:44:40 +04:00
& pipe_cli ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
goto done ;
}
2011-01-14 19:05:32 +03:00
b = pipe_cli - > binding_handle ;
2008-09-09 20:44:40 +04:00
werr = libnetapi_samr_open_domain ( ctx , pipe_cli ,
SAMR_ACCESS_ENUM_DOMAINS |
2009-04-16 02:40:00 +04:00
SAMR_ACCESS_LOOKUP_DOMAIN ,
2008-09-09 20:44:40 +04:00
SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT |
SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS ,
& 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 |
2009-04-16 02:40:00 +04:00
SAMR_ACCESS_LOOKUP_DOMAIN ,
2008-09-09 20:44:40 +04:00
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 ) ;
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_LookupNames ( b , talloc_tos ( ) ,
2008-09-09 20:44:40 +04:00
& domain_handle ,
1 ,
& lsa_account_name ,
& user_rids ,
2011-01-14 19:05:32 +03:00
& name_types ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-09-09 20:44:40 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
2013-11-08 09:40:55 +04:00
if ( user_rids . count ! = 1 ) {
werr = WERR_BAD_NET_RESP ;
goto done ;
}
if ( name_types . count ! = 1 ) {
werr = WERR_BAD_NET_RESP ;
goto done ;
}
2008-09-09 20:44:40 +04:00
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_OpenUser ( b , talloc_tos ( ) ,
2008-09-09 20:44:40 +04:00
& domain_handle ,
SAMR_USER_ACCESS_GET_GROUPS ,
user_rids . ids [ 0 ] ,
2011-01-14 19:05:32 +03:00
& user_handle ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-09-09 20:44:40 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_GetGroupsForUser ( b , talloc_tos ( ) ,
2008-09-09 20:44:40 +04:00
& user_handle ,
2011-01-14 19:05:32 +03:00
& rid_array ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-09-09 20:44:40 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
if ( ! sid_compose ( & user_sid , domain_sid , user_rids . ids [ 0 ] ) ) {
2015-12-03 17:24:14 +03:00
werr = WERR_NOT_ENOUGH_MEMORY ;
2008-09-09 20:44:40 +04:00
goto done ;
}
sid_array . num_sids = rid_array - > count + 1 ;
2011-06-07 05:30:12 +04:00
sid_array . sids = talloc_array ( ctx , struct lsa_SidPtr , sid_array . num_sids ) ;
2008-09-09 20:44:40 +04:00
if ( ! sid_array . sids ) {
2015-12-03 17:24:14 +03:00
werr = WERR_NOT_ENOUGH_MEMORY ;
2008-09-09 20:44:40 +04:00
goto done ;
}
2010-08-26 19:21:39 +04:00
sid_array . sids [ 0 ] . sid = dom_sid_dup ( ctx , & user_sid ) ;
2008-09-09 20:44:40 +04:00
if ( ! sid_array . sids [ 0 ] . sid ) {
2015-12-03 17:24:14 +03:00
werr = WERR_NOT_ENOUGH_MEMORY ;
2008-09-09 20:44:40 +04:00
goto done ;
}
for ( i = 0 ; i < rid_array - > count ; i + + ) {
struct dom_sid sid ;
if ( ! sid_compose ( & sid , domain_sid , rid_array - > rids [ i ] . rid ) ) {
2015-12-03 17:24:14 +03:00
werr = WERR_NOT_ENOUGH_MEMORY ;
2008-09-09 20:44:40 +04:00
goto done ;
}
2010-08-26 19:21:39 +04:00
sid_array . sids [ i + 1 ] . sid = dom_sid_dup ( ctx , & sid ) ;
2008-09-09 20:44:40 +04:00
if ( ! sid_array . sids [ i + 1 ] . sid ) {
2015-12-03 17:24:14 +03:00
werr = WERR_NOT_ENOUGH_MEMORY ;
2008-09-09 20:44:40 +04:00
goto done ;
}
}
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_GetAliasMembership ( b , talloc_tos ( ) ,
2008-09-09 20:44:40 +04:00
& domain_handle ,
& sid_array ,
2011-01-14 19:05:32 +03:00
& domain_rids ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-09-09 20:44:40 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
for ( i = 0 ; i < domain_rids . count ; i + + ) {
if ( ! add_rid_to_array_unique ( ctx , domain_rids . ids [ i ] ,
& rids , & num_rids ) ) {
2015-12-03 17:24:14 +03:00
werr = WERR_NOT_ENOUGH_MEMORY ;
2008-09-09 20:44:40 +04:00
goto done ;
}
}
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_GetAliasMembership ( b , talloc_tos ( ) ,
2008-09-09 20:44:40 +04:00
& builtin_handle ,
& sid_array ,
2011-01-14 19:05:32 +03:00
& builtin_rids ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-09-09 20:44:40 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
for ( i = 0 ; i < builtin_rids . count ; i + + ) {
if ( ! add_rid_to_array_unique ( ctx , builtin_rids . ids [ i ] ,
& rids , & num_rids ) ) {
2015-12-03 17:24:14 +03:00
werr = WERR_NOT_ENOUGH_MEMORY ;
2008-09-09 20:44:40 +04:00
goto done ;
}
}
2011-01-14 19:05:32 +03:00
status = dcerpc_samr_LookupRids ( b , talloc_tos ( ) ,
2008-09-09 20:44:40 +04:00
& builtin_handle ,
num_rids ,
rids ,
& names ,
2011-01-14 19:05:32 +03:00
& types ,
& result ) ;
2021-07-25 11:26:30 +03:00
if ( any_nt_status_not_ok ( status , result , & status ) ) {
2008-09-09 20:44:40 +04:00
werr = ntstatus_to_werror ( status ) ;
goto done ;
2011-01-14 19:05:32 +03:00
}
2013-11-08 10:41:22 +04:00
if ( names . count ! = num_rids ) {
werr = WERR_BAD_NET_RESP ;
goto done ;
}
if ( types . count ! = num_rids ) {
werr = WERR_BAD_NET_RESP ;
goto done ;
}
2008-09-09 20:44:40 +04:00
for ( i = 0 ; i < names . count ; i + + ) {
status = add_LOCALGROUP_USERS_INFO_X_buffer ( ctx ,
r - > in . level ,
names . names [ i ] . string ,
r - > out . buffer ,
& entries_read ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
werr = ntstatus_to_werror ( status ) ;
goto done ;
}
}
2009-03-20 13:19:59 +03:00
* r - > out . entries_read = entries_read ;
* r - > out . total_entries = entries_read ;
2008-09-09 20:44:40 +04:00
done :
if ( ctx - > disable_policy_handle_cache ) {
libnetapi_samr_close_domain_handle ( ctx , & domain_handle ) ;
libnetapi_samr_close_connect_handle ( ctx , & connect_handle ) ;
}
return werr ;
2008-09-09 15:42:27 +04:00
}
/****************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR NetUserGetLocalGroups_l ( struct libnetapi_ctx * ctx ,
struct NetUserGetLocalGroups * r )
{
LIBNETAPI_REDIRECT_TO_LOCALHOST ( ctx , r , NetUserGetLocalGroups ) ;
}