2009-08-04 23:23:13 +04:00
/*
Unix SMB / CIFS implementation .
async queryuser
Copyright ( C ) Volker Lendecke 2009
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"
2022-06-07 20:35:16 +03:00
# include "util/debug.h"
2009-08-04 23:23:13 +04:00
# include "winbindd.h"
2014-05-08 04:17:32 +04:00
# include "librpc/gen_ndr/ndr_winbind_c.h"
2010-10-12 08:27:50 +04:00
# include "../libcli/security/security.h"
2016-12-29 13:05:28 +03:00
# include "libsmb/samlogon_cache.h"
2022-06-07 20:35:16 +03:00
# include "librpc/gen_ndr/ndr_winbind.h"
2009-08-04 23:23:13 +04:00
struct wb_queryuser_state {
2016-12-29 13:05:28 +03:00
struct tevent_context * ev ;
2021-08-31 18:04:56 +03:00
struct wbint_userinfo * info ;
const struct wb_parent_idmap_config * idmap_cfg ;
2016-12-29 13:05:28 +03:00
bool tried_dclookup ;
2009-08-04 23:23:13 +04:00
} ;
2021-08-31 18:04:56 +03:00
static void wb_queryuser_idmap_setup_done ( struct tevent_req * subreq ) ;
2016-12-29 13:05:28 +03:00
static void wb_queryuser_got_uid ( struct tevent_req * subreq ) ;
static void wb_queryuser_got_domain ( struct tevent_req * subreq ) ;
static void wb_queryuser_got_dc ( struct tevent_req * subreq ) ;
static void wb_queryuser_got_gid ( struct tevent_req * subreq ) ;
static void wb_queryuser_got_group_name ( struct tevent_req * subreq ) ;
2009-08-04 23:23:13 +04:00
static void wb_queryuser_done ( struct tevent_req * subreq ) ;
struct tevent_req * wb_queryuser_send ( TALLOC_CTX * mem_ctx ,
struct tevent_context * ev ,
const struct dom_sid * user_sid )
{
struct tevent_req * req , * subreq ;
struct wb_queryuser_state * state ;
2016-12-29 13:05:28 +03:00
struct wbint_userinfo * info ;
2022-06-07 20:35:16 +03:00
struct dom_sid_buf buf ;
2009-08-04 23:23:13 +04:00
req = tevent_req_create ( mem_ctx , & state , struct wb_queryuser_state ) ;
if ( req = = NULL ) {
return NULL ;
}
2022-06-07 20:35:16 +03:00
D_INFO ( " WB command queryuser start. \n Query user sid %s \n " ,
dom_sid_str_buf ( user_sid , & buf ) ) ;
2016-12-29 13:05:28 +03:00
state - > ev = ev ;
2009-08-04 23:23:13 +04:00
2016-12-29 13:05:28 +03:00
state - > info = talloc_zero ( state , struct wbint_userinfo ) ;
2009-08-09 15:31:31 +04:00
if ( tevent_req_nomem ( state - > info , req ) ) {
return tevent_req_post ( req , ev ) ;
}
2016-12-29 13:05:28 +03:00
info = state - > info ;
info - > primary_gid = ( gid_t ) - 1 ;
2009-08-09 15:31:31 +04:00
2016-12-29 13:05:28 +03:00
sid_copy ( & info - > user_sid , user_sid ) ;
2021-08-31 18:04:56 +03:00
subreq = wb_parent_idmap_setup_send ( state , state - > ev ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return tevent_req_post ( req , ev ) ;
}
tevent_req_set_callback ( subreq , wb_queryuser_idmap_setup_done , req ) ;
return req ;
}
static void wb_queryuser_idmap_setup_done ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct wb_queryuser_state * state = tevent_req_data (
req , struct wb_queryuser_state ) ;
NTSTATUS status ;
2022-06-07 20:35:16 +03:00
struct dom_sid_buf buf ;
2021-08-31 18:04:56 +03:00
status = wb_parent_idmap_setup_recv ( subreq , & state - > idmap_cfg ) ;
TALLOC_FREE ( subreq ) ;
if ( tevent_req_nterror ( req , status ) ) {
2022-06-07 20:35:16 +03:00
D_WARNING ( " wb_parent_idmap_setup_recv() failed with %s. \n " ,
nt_errstr ( status ) ) ;
2021-08-31 18:04:56 +03:00
return ;
}
2022-06-07 20:35:16 +03:00
D_DEBUG ( " Convert the user SID %s to XID. \n " ,
dom_sid_str_buf ( & state - > info - > user_sid , & buf ) ) ;
2016-12-29 13:05:28 +03:00
subreq = wb_sids2xids_send (
state , state - > ev , & state - > info - > user_sid , 1 ) ;
2009-08-04 23:23:13 +04:00
if ( tevent_req_nomem ( subreq , req ) ) {
2021-08-31 18:04:56 +03:00
return ;
2009-08-04 23:23:13 +04:00
}
2016-12-29 13:05:28 +03:00
tevent_req_set_callback ( subreq , wb_queryuser_got_uid , req ) ;
2021-08-31 18:04:56 +03:00
return ;
2009-08-04 23:23:13 +04:00
}
2016-12-29 13:05:28 +03:00
static void wb_queryuser_got_uid ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct wb_queryuser_state * state = tevent_req_data (
req , struct wb_queryuser_state ) ;
struct wbint_userinfo * info = state - > info ;
struct netr_SamInfo3 * info3 ;
2020-09-11 14:52:17 +03:00
struct dcerpc_binding_handle * child_binding_handle = NULL ;
2016-12-29 13:05:28 +03:00
struct unixid xid ;
NTSTATUS status ;
2022-06-07 20:35:16 +03:00
struct dom_sid_buf buf , buf1 ;
2016-12-29 13:05:28 +03:00
status = wb_sids2xids_recv ( subreq , & xid , 1 ) ;
TALLOC_FREE ( subreq ) ;
if ( tevent_req_nterror ( req , status ) ) {
2022-06-07 20:35:16 +03:00
D_WARNING ( " wb_sids2xids_recv() failed with %s. \n " ,
nt_errstr ( status ) ) ;
2016-12-29 13:05:28 +03:00
return ;
}
if ( ( xid . type ! = ID_TYPE_UID ) & & ( xid . type ! = ID_TYPE_BOTH ) ) {
2022-06-07 20:35:16 +03:00
D_WARNING ( " XID type is %d, should be ID_TYPE_UID or ID_TYPE_BOTH. \n " ,
xid . type ) ;
2016-12-29 13:05:28 +03:00
tevent_req_nterror ( req , NT_STATUS_NO_SUCH_USER ) ;
return ;
}
2022-07-18 16:28:10 +03:00
D_DEBUG ( " Received XID % " PRIu32 " for SID %s. \n " ,
2022-06-07 20:35:16 +03:00
xid . id ,
dom_sid_str_buf ( & info - > user_sid , & buf1 ) ) ;
2016-12-29 13:05:28 +03:00
info - > uid = xid . id ;
/*
* Default the group sid to " Domain Users " in the user ' s
* domain . The samlogon cache or the query_user call later on
* can override this .
*/
sid_copy ( & info - > group_sid , & info - > user_sid ) ;
sid_split_rid ( & info - > group_sid , NULL ) ;
sid_append_rid ( & info - > group_sid , DOMAIN_RID_USERS ) ;
2022-06-07 20:35:16 +03:00
D_DEBUG ( " Preconfigured 'Domain Users' RID %u was used to create group SID %s from user SID %s. \n " ,
DOMAIN_RID_USERS ,
dom_sid_str_buf ( & info - > group_sid , & buf ) ,
dom_sid_str_buf ( & info - > user_sid , & buf1 ) ) ;
2016-12-29 13:05:28 +03:00
info - > homedir = talloc_strdup ( info , lp_template_homedir ( ) ) ;
2022-06-07 20:35:16 +03:00
D_DEBUG ( " Setting 'homedir' to the template '%s'. \n " , info - > homedir ) ;
2016-12-29 13:05:28 +03:00
if ( tevent_req_nomem ( info - > homedir , req ) ) {
return ;
}
info - > shell = talloc_strdup ( info , lp_template_shell ( ) ) ;
2022-06-07 20:35:16 +03:00
D_DEBUG ( " Setting 'shell' to the template '%s'. \n " , info - > shell ) ;
2016-12-29 13:05:28 +03:00
if ( tevent_req_nomem ( info - > shell , req ) ) {
return ;
}
info3 = netsamlogon_cache_get ( state , & info - > user_sid ) ;
if ( info3 ! = NULL ) {
2022-06-07 20:35:16 +03:00
D_DEBUG ( " Filling data received from netsamlogon_cache \n " ) ;
2016-12-29 13:05:28 +03:00
sid_compose ( & info - > group_sid , info3 - > base . domain_sid ,
info3 - > base . primary_gid ) ;
info - > acct_name = talloc_move (
info , & info3 - > base . account_name . string ) ;
info - > full_name = talloc_move (
info , & info3 - > base . full_name . string ) ;
info - > domain_name = talloc_move (
state , & info3 - > base . logon_domain . string ) ;
TALLOC_FREE ( info3 ) ;
}
2022-06-07 20:35:16 +03:00
NDR_PRINT_DEBUG_LEVEL ( DBGLVL_DEBUG , wbint_userinfo , state - > info ) ;
2016-12-29 13:05:28 +03:00
if ( info - > domain_name = = NULL ) {
2022-06-07 20:35:16 +03:00
D_DEBUG ( " Domain name is empty, calling wb_lookupsid_send() to get it. \n " ) ;
2016-12-29 13:05:28 +03:00
subreq = wb_lookupsid_send ( state , state - > ev , & info - > user_sid ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return ;
}
tevent_req_set_callback ( subreq , wb_queryuser_got_domain , req ) ;
return ;
}
2020-09-11 14:52:17 +03:00
/*
* Note wb_sids2xids_send / recv was called before ,
* so we ' re sure that wb_parent_idmap_setup_send / recv
* was already called .
*/
2020-09-11 14:52:17 +03:00
child_binding_handle = idmap_child_handle ( ) ;
2022-06-07 20:35:16 +03:00
D_DEBUG ( " Domain name is set, calling dcerpc_wbint_GetNssInfo_send() \n " ) ;
2016-12-29 13:05:28 +03:00
subreq = dcerpc_wbint_GetNssInfo_send (
2020-09-11 14:52:17 +03:00
state , state - > ev , child_binding_handle , info ) ;
2016-12-29 13:05:28 +03:00
if ( tevent_req_nomem ( subreq , req ) ) {
return ;
}
tevent_req_set_callback ( subreq , wb_queryuser_done , req ) ;
}
static void wb_queryuser_got_domain ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct wb_queryuser_state * state = tevent_req_data (
req , struct wb_queryuser_state ) ;
struct wbint_userinfo * info = state - > info ;
enum lsa_SidType type ;
2020-09-11 14:52:17 +03:00
struct dcerpc_binding_handle * child_binding_handle = NULL ;
2016-12-29 13:05:28 +03:00
NTSTATUS status ;
status = wb_lookupsid_recv ( subreq , state , & type ,
& info - > domain_name , & info - > acct_name ) ;
TALLOC_FREE ( subreq ) ;
if ( tevent_req_nterror ( req , status ) ) {
2022-06-07 20:35:16 +03:00
D_WARNING ( " wb_lookupsid_recv failed with %s. \n " ,
nt_errstr ( status ) ) ;
2016-12-29 13:05:28 +03:00
return ;
}
2022-06-07 20:35:16 +03:00
NDR_PRINT_DEBUG_LEVEL ( DBGLVL_DEBUG , wbint_userinfo , state - > info ) ;
2019-01-11 12:44:30 +03:00
switch ( type ) {
case SID_NAME_USER :
case SID_NAME_COMPUTER :
/*
* user case : we only need the account name from lookup_sids
*/
break ;
case SID_NAME_DOM_GRP :
case SID_NAME_ALIAS :
case SID_NAME_WKN_GRP :
/*
* also treat group - type SIDs ( they might map to ID_TYPE_BOTH )
*/
sid_copy ( & info - > group_sid , & info - > user_sid ) ;
break ;
default :
2022-06-07 20:35:16 +03:00
D_WARNING ( " Unknown type:%d, return NT_STATUS_NO_SUCH_USER. \n " ,
type ) ;
2016-12-29 13:05:28 +03:00
tevent_req_nterror ( req , NT_STATUS_NO_SUCH_USER ) ;
return ;
}
2020-09-11 14:52:17 +03:00
/*
* Note wb_sids2xids_send / recv was called before ,
* so we ' re sure that wb_parent_idmap_setup_send / recv
* was already called .
*/
2020-09-11 14:52:17 +03:00
child_binding_handle = idmap_child_handle ( ) ;
2022-06-07 20:35:16 +03:00
D_DEBUG ( " About to call dcerpc_wbint_GetNssInfo_send() \n " ) ;
2016-12-29 13:05:28 +03:00
subreq = dcerpc_wbint_GetNssInfo_send (
2020-09-11 14:52:17 +03:00
state , state - > ev , child_binding_handle , info ) ;
2016-12-29 13:05:28 +03:00
if ( tevent_req_nomem ( subreq , req ) ) {
return ;
}
tevent_req_set_callback ( subreq , wb_queryuser_done , req ) ;
}
2009-08-04 23:23:13 +04:00
static void wb_queryuser_done ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct wb_queryuser_state * state = tevent_req_data (
req , struct wb_queryuser_state ) ;
2016-12-29 13:05:28 +03:00
struct wbint_userinfo * info = state - > info ;
2009-08-04 23:23:13 +04:00
NTSTATUS status , result ;
2017-06-07 20:33:57 +03:00
bool need_group_name = false ;
const char * tmpl = NULL ;
2009-08-04 23:23:13 +04:00
2016-12-29 13:05:28 +03:00
status = dcerpc_wbint_GetNssInfo_recv ( subreq , info , & result ) ;
TALLOC_FREE ( subreq ) ;
if ( tevent_req_nterror ( req , status ) ) {
2022-06-07 20:35:16 +03:00
D_WARNING ( " GetNssInfo failed with %s. \n " , nt_errstr ( status ) ) ;
2016-12-29 13:05:28 +03:00
return ;
}
if ( NT_STATUS_EQUAL ( result , NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND ) & &
! state - > tried_dclookup ) {
2022-06-07 20:35:16 +03:00
D_DEBUG ( " GetNssInfo got DOMAIN_CONTROLLER_NOT_FOUND, calling wb_dsgetdcname_send() \n " ) ;
2016-12-29 13:05:28 +03:00
subreq = wb_dsgetdcname_send (
state , state - > ev , state - > info - > domain_name , NULL , NULL ,
DS_RETURN_DNS_NAME ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return ;
}
tevent_req_set_callback ( subreq , wb_queryuser_got_dc , req ) ;
return ;
}
/*
* Ignore failure in " result " here . We ' ll try to fill in stuff
* that misses further down .
*/
if ( state - > info - > primary_gid = = ( gid_t ) - 1 ) {
2022-06-07 20:35:16 +03:00
D_DEBUG ( " Calling wb_sids2xids_send() to resolve primary gid. \n " ) ;
2016-12-29 13:05:28 +03:00
subreq = wb_sids2xids_send (
state , state - > ev , & info - > group_sid , 1 ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return ;
}
tevent_req_set_callback ( subreq , wb_queryuser_got_gid , req ) ;
return ;
}
2017-06-07 20:33:57 +03:00
tmpl = lp_template_homedir ( ) ;
if ( strstr_m ( tmpl , " %g " ) | | strstr_m ( tmpl , " %G " ) ) {
need_group_name = true ;
}
tmpl = lp_template_shell ( ) ;
if ( strstr_m ( tmpl , " %g " ) | | strstr_m ( tmpl , " %G " ) ) {
need_group_name = true ;
}
if ( need_group_name & & state - > info - > primary_group_name = = NULL ) {
2022-06-07 20:35:16 +03:00
D_DEBUG ( " Calling wb_lookupsid_send() to resolve primary group name. \n " ) ;
2016-12-29 13:05:28 +03:00
subreq = wb_lookupsid_send ( state , state - > ev , & info - > group_sid ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return ;
}
tevent_req_set_callback ( subreq , wb_queryuser_got_group_name ,
req ) ;
return ;
}
2022-06-07 20:35:16 +03:00
NDR_PRINT_DEBUG_LEVEL ( DBGLVL_DEBUG , wbint_userinfo , state - > info ) ;
2016-12-29 13:05:28 +03:00
tevent_req_done ( req ) ;
}
static void wb_queryuser_got_dc ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct wb_queryuser_state * state = tevent_req_data (
req , struct wb_queryuser_state ) ;
struct wbint_userinfo * info = state - > info ;
struct netr_DsRGetDCNameInfo * dcinfo ;
2020-09-11 14:52:17 +03:00
struct dcerpc_binding_handle * child_binding_handle = NULL ;
2016-12-29 13:05:28 +03:00
NTSTATUS status ;
status = wb_dsgetdcname_recv ( subreq , state , & dcinfo ) ;
TALLOC_FREE ( subreq ) ;
if ( tevent_req_nterror ( req , status ) ) {
2022-06-07 20:35:16 +03:00
D_WARNING ( " wb_dsgetdcname_recv() failed with %s. \n " ,
nt_errstr ( status ) ) ;
2016-12-29 13:05:28 +03:00
return ;
}
state - > tried_dclookup = true ;
2022-06-07 20:35:16 +03:00
D_DEBUG ( " Got DC name, calling wb_dsgetdcname_gencache_set(). \n " ) ;
2016-12-29 13:05:28 +03:00
status = wb_dsgetdcname_gencache_set ( info - > domain_name , dcinfo ) ;
if ( tevent_req_nterror ( req , status ) ) {
2022-06-07 20:35:16 +03:00
D_WARNING ( " wb_dsgetdcname_gencache_set() failed with %s. \n " ,
nt_errstr ( status ) ) ;
2016-12-29 13:05:28 +03:00
return ;
}
2022-06-07 20:35:16 +03:00
NDR_PRINT_DEBUG_LEVEL ( DBGLVL_DEBUG , wbint_userinfo , state - > info ) ;
2016-12-29 13:05:28 +03:00
2020-09-11 14:52:17 +03:00
/*
* Note wb_sids2xids_send / recv was called before ,
* so we ' re sure that wb_parent_idmap_setup_send / recv
* was already called .
*/
2020-09-11 14:52:17 +03:00
child_binding_handle = idmap_child_handle ( ) ;
2016-12-29 13:05:28 +03:00
subreq = dcerpc_wbint_GetNssInfo_send (
2020-09-11 14:52:17 +03:00
state , state - > ev , child_binding_handle , info ) ;
2016-12-29 13:05:28 +03:00
if ( tevent_req_nomem ( subreq , req ) ) {
return ;
}
tevent_req_set_callback ( subreq , wb_queryuser_done , req ) ;
}
static void wb_queryuser_got_gid ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct wb_queryuser_state * state = tevent_req_data (
req , struct wb_queryuser_state ) ;
struct unixid xid ;
NTSTATUS status ;
2017-06-07 20:33:57 +03:00
bool need_group_name = false ;
const char * tmpl = NULL ;
2022-06-07 20:35:16 +03:00
struct dom_sid_buf buf ;
2016-12-29 13:05:28 +03:00
status = wb_sids2xids_recv ( subreq , & xid , 1 ) ;
TALLOC_FREE ( subreq ) ;
if ( tevent_req_nterror ( req , status ) ) {
2022-06-07 20:35:16 +03:00
D_WARNING ( " wb_sids2xids_recv() failed with %s. \n " ,
nt_errstr ( status ) ) ;
2016-12-29 13:05:28 +03:00
return ;
}
2022-07-18 16:28:10 +03:00
D_DEBUG ( " Got XID % " PRIu32 " with type %d. \n " , xid . id , xid . type ) ;
2016-12-29 13:05:28 +03:00
if ( ( xid . type ! = ID_TYPE_GID ) & & ( xid . type ! = ID_TYPE_BOTH ) ) {
2022-06-07 20:35:16 +03:00
D_WARNING ( " Returning NT_STATUS_NO_SUCH_USER \n "
" xid.type must be ID_TYPE_UID or ID_TYPE_BOTH. \n " ) ;
2016-12-29 13:05:28 +03:00
tevent_req_nterror ( req , NT_STATUS_NO_SUCH_USER ) ;
return ;
}
state - > info - > primary_gid = xid . id ;
2017-06-07 20:33:57 +03:00
tmpl = lp_template_homedir ( ) ;
if ( strstr_m ( tmpl , " %g " ) | | strstr_m ( tmpl , " %G " ) ) {
need_group_name = true ;
}
tmpl = lp_template_shell ( ) ;
if ( strstr_m ( tmpl , " %g " ) | | strstr_m ( tmpl , " %G " ) ) {
need_group_name = true ;
}
2022-06-07 20:35:16 +03:00
NDR_PRINT_DEBUG_LEVEL ( DBGLVL_DEBUG , wbint_userinfo , state - > info ) ;
2017-06-07 20:33:57 +03:00
if ( need_group_name & & state - > info - > primary_group_name = = NULL ) {
2022-06-07 20:35:16 +03:00
D_DEBUG ( " Calling wb_lookupsid_send for group SID %s. \n " ,
dom_sid_str_buf ( & state - > info - > group_sid , & buf ) ) ;
2016-12-29 13:05:28 +03:00
subreq = wb_lookupsid_send ( state , state - > ev ,
& state - > info - > group_sid ) ;
if ( tevent_req_nomem ( subreq , req ) ) {
return ;
}
tevent_req_set_callback ( subreq , wb_queryuser_got_group_name ,
req ) ;
return ;
}
2022-06-07 20:35:16 +03:00
D_DEBUG ( " No need to lookup primary group name. Request is done! \n " ) ;
2016-12-29 13:05:28 +03:00
tevent_req_done ( req ) ;
}
static void wb_queryuser_got_group_name ( struct tevent_req * subreq )
{
struct tevent_req * req = tevent_req_callback_data (
subreq , struct tevent_req ) ;
struct wb_queryuser_state * state = tevent_req_data (
req , struct wb_queryuser_state ) ;
enum lsa_SidType type ;
NTSTATUS status ;
const char * domain_name ;
2017-03-17 15:52:57 +03:00
status = wb_lookupsid_recv ( subreq , state - > info , & type , & domain_name ,
2016-12-29 13:05:28 +03:00
& state - > info - > primary_group_name ) ;
2009-08-04 23:23:13 +04:00
TALLOC_FREE ( subreq ) ;
2016-12-29 13:05:28 +03:00
if ( tevent_req_nterror ( req , status ) ) {
2022-06-07 20:35:16 +03:00
D_WARNING ( " wb_lookupsid_recv() failed with %s. \n " ,
nt_errstr ( status ) ) ;
2009-08-04 23:23:13 +04:00
return ;
}
tevent_req_done ( req ) ;
}
NTSTATUS wb_queryuser_recv ( struct tevent_req * req , TALLOC_CTX * mem_ctx ,
2009-08-09 15:31:31 +04:00
struct wbint_userinfo * * pinfo )
2009-08-04 23:23:13 +04:00
{
struct wb_queryuser_state * state = tevent_req_data (
req , struct wb_queryuser_state ) ;
NTSTATUS status ;
2022-06-07 20:35:16 +03:00
D_INFO ( " WB command queryuser end. \n " ) ;
NDR_PRINT_DEBUG_LEVEL ( DBGLVL_INFO , wbint_userinfo , state - > info ) ;
2009-08-04 23:23:13 +04:00
if ( tevent_req_is_nterror ( req , & status ) ) {
return status ;
}
2009-08-09 15:31:31 +04:00
* pinfo = talloc_move ( mem_ctx , & state - > info ) ;
2009-08-04 23:23:13 +04:00
return NT_STATUS_OK ;
}