2008-04-10 21:41:03 +02:00
/*
* Unix SMB / CIFS implementation .
* NetApi 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"
2012-01-30 10:53:18 +01:00
# include "auth_info.h"
2008-04-10 21:41:03 +02:00
# include "lib/netapi/netapi.h"
2008-04-10 21:56:12 +02:00
# include "lib/netapi/netapi_private.h"
2011-05-06 11:47:43 +02:00
# include "libsmb/libsmb.h"
2011-02-28 10:19:44 +01:00
# include "rpc_client/cli_pipe.h"
2012-05-19 17:31:50 +02:00
# include "../libcli/smb/smbXcli_base.h"
2008-04-10 21:41:03 +02:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-09-20 21:05:37 -07:00
struct client_ipc_connection {
struct client_ipc_connection * prev , * next ;
struct cli_state * cli ;
struct client_pipe_connection * pipe_connections ;
} ;
struct client_pipe_connection {
struct client_pipe_connection * prev , * next ;
struct rpc_pipe_client * pipe ;
} ;
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-09-21 15:41:23 -07:00
static struct client_ipc_connection * ipc_cm_find (
struct libnetapi_private_ctx * priv_ctx , const char * server_name )
2010-09-20 21:05:37 -07:00
{
struct client_ipc_connection * p ;
2010-09-21 15:41:23 -07:00
for ( p = priv_ctx - > ipc_connections ; p ; p = p - > next ) {
2012-05-19 17:31:50 +02:00
const char * remote_name = smbXcli_conn_remote_name ( p - > cli - > conn ) ;
2011-07-22 16:19:00 +02:00
if ( strequal ( remote_name , server_name ) ) {
2010-09-20 21:05:37 -07:00
return p ;
}
}
return NULL ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-08-12 17:59:23 +02:00
static WERROR libnetapi_open_ipc_connection ( struct libnetapi_ctx * ctx ,
const char * server_name ,
2010-09-20 21:05:37 -07:00
struct client_ipc_connection * * pp )
2008-04-10 21:41:03 +02:00
{
2011-03-16 21:52:20 +01:00
struct libnetapi_private_ctx * priv_ctx ;
2009-03-17 14:53:06 -07:00
struct user_auth_info * auth_info = NULL ;
2008-04-10 21:41:03 +02:00
struct cli_state * cli_ipc = NULL ;
2010-09-20 21:05:37 -07:00
struct client_ipc_connection * p ;
2011-07-03 19:59:37 +02:00
NTSTATUS status ;
2008-04-10 21:41:03 +02:00
2010-09-20 21:05:37 -07:00
if ( ! ctx | | ! pp | | ! server_name ) {
2008-04-10 21:41:03 +02:00
return WERR_INVALID_PARAM ;
}
2011-03-16 21:52:20 +01:00
priv_ctx = ( struct libnetapi_private_ctx * ) ctx - > private_data ;
2010-09-21 15:41:23 -07:00
p = ipc_cm_find ( priv_ctx , server_name ) ;
2010-09-20 21:05:37 -07:00
if ( p ) {
* pp = p ;
return WERR_OK ;
}
auth_info = user_auth_info_init ( ctx ) ;
2009-03-17 14:53:06 -07:00
if ( ! auth_info ) {
return WERR_NOMEM ;
2008-04-10 21:41:03 +02:00
}
2015-12-16 10:01:59 +01:00
auth_info - > signing_state = SMB_SIGNING_IPC_DEFAULT ;
2009-03-17 14:53:06 -07:00
set_cmdline_auth_info_use_kerberos ( auth_info , ctx - > use_kerberos ) ;
set_cmdline_auth_info_username ( auth_info , ctx - > username ) ;
2009-05-13 23:57:26 +02:00
if ( ctx - > password ) {
set_cmdline_auth_info_password ( auth_info , ctx - > password ) ;
} else {
set_cmdline_auth_info_getpass ( auth_info ) ;
}
2008-04-10 21:41:03 +02:00
if ( ctx - > username & & ctx - > username [ 0 ] & &
2008-04-13 19:22:24 +02:00
ctx - > password & & ctx - > password [ 0 ] & &
ctx - > use_kerberos ) {
2009-03-17 14:53:06 -07:00
set_cmdline_auth_info_fallback_after_kerberos ( auth_info , true ) ;
2008-04-10 21:41:03 +02:00
}
2010-01-24 18:50:31 +01:00
if ( ctx - > use_ccache ) {
set_cmdline_auth_info_use_ccache ( auth_info , true ) ;
}
2011-07-03 19:59:37 +02:00
status = cli_cm_open ( ctx , NULL ,
server_name , " IPC$ " ,
auth_info ,
false , false ,
2014-02-04 15:09:08 +13:00
lp_client_max_protocol ( ) ,
2011-07-03 19:59:37 +02:00
0 , 0x20 , & cli_ipc ) ;
2014-09-26 03:14:53 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-03 19:59:37 +02:00
cli_ipc = NULL ;
2009-03-26 10:26:59 +01:00
}
2009-03-17 14:53:06 -07:00
TALLOC_FREE ( auth_info ) ;
2008-04-10 21:41:03 +02:00
if ( ! cli_ipc ) {
libnetapi_set_error_string ( ctx ,
2008-04-10 21:56:12 +02:00
" Failed to connect to IPC$ share on %s " , server_name ) ;
2008-04-10 21:41:03 +02:00
return WERR_CAN_NOT_COMPLETE ;
}
2011-06-07 11:44:43 +10:00
p = talloc_zero ( ctx , struct client_ipc_connection ) ;
2010-09-20 21:05:37 -07:00
if ( p = = NULL ) {
return WERR_NOMEM ;
}
2008-04-10 21:41:03 +02:00
2010-09-20 21:05:37 -07:00
p - > cli = cli_ipc ;
2010-09-21 15:41:23 -07:00
DLIST_ADD ( priv_ctx - > ipc_connections , p ) ;
2008-04-10 21:41:03 +02:00
2010-09-20 21:05:37 -07:00
* pp = p ;
2008-04-10 21:41:03 +02:00
2010-09-20 21:05:37 -07:00
return WERR_OK ;
}
2008-04-10 22:42:07 +02:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-03-12 17:59:24 -07:00
WERROR libnetapi_shutdown_cm ( struct libnetapi_ctx * ctx )
{
2010-09-21 15:41:23 -07:00
struct libnetapi_private_ctx * priv_ctx =
( struct libnetapi_private_ctx * ) ctx - > private_data ;
2010-09-20 21:05:37 -07:00
struct client_ipc_connection * p ;
2009-03-12 17:59:24 -07:00
2010-09-21 15:41:23 -07:00
for ( p = priv_ctx - > ipc_connections ; p ; p = p - > next ) {
2009-03-12 17:59:24 -07:00
cli_shutdown ( p - > cli ) ;
}
return WERR_OK ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-09-20 21:05:37 -07:00
static NTSTATUS pipe_cm_find ( struct client_ipc_connection * ipc ,
2013-05-17 16:13:26 +02:00
const struct ndr_interface_table * table ,
2008-07-20 17:59:30 +02:00
struct rpc_pipe_client * * presult )
2008-04-10 22:42:07 +02:00
{
struct client_pipe_connection * p ;
2010-09-20 21:05:37 -07:00
for ( p = ipc - > pipe_connections ; p ; p = p - > next ) {
2011-07-22 16:19:00 +02:00
const char * ipc_remote_name ;
2008-04-10 22:42:07 +02:00
2013-09-13 11:12:25 +02:00
if ( ! rpccli_is_connected ( p - > pipe ) ) {
2008-07-20 17:59:30 +02:00
return NT_STATUS_PIPE_EMPTY ;
2008-04-10 22:42:07 +02:00
}
2012-05-19 17:31:50 +02:00
ipc_remote_name = smbXcli_conn_remote_name ( ipc - > cli - > conn ) ;
2011-07-22 16:19:00 +02:00
if ( strequal ( ipc_remote_name , p - > pipe - > desthost )
2008-07-20 17:59:30 +02:00
& & ndr_syntax_id_equal ( & p - > pipe - > abstract_syntax ,
2013-05-17 16:13:26 +02:00
& table - > syntax_id ) ) {
2008-07-20 17:59:30 +02:00
* presult = p - > pipe ;
return NT_STATUS_OK ;
2008-04-10 22:42:07 +02:00
}
}
2008-07-20 17:59:30 +02:00
return NT_STATUS_PIPE_NOT_AVAILABLE ;
2008-04-10 22:42:07 +02:00
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-07-20 17:59:30 +02:00
static NTSTATUS pipe_cm_connect ( TALLOC_CTX * mem_ctx ,
2010-09-20 21:05:37 -07:00
struct client_ipc_connection * ipc ,
2013-05-17 16:13:26 +02:00
const struct ndr_interface_table * table ,
2008-07-20 17:59:30 +02:00
struct rpc_pipe_client * * presult )
2008-04-10 22:42:07 +02:00
{
struct client_pipe_connection * p ;
2008-07-20 17:59:30 +02:00
NTSTATUS status ;
2008-04-10 22:42:07 +02:00
2011-06-07 11:58:39 +10:00
p = talloc_zero_array ( mem_ctx , struct client_pipe_connection , 1 ) ;
2008-04-10 22:42:07 +02:00
if ( ! p ) {
2008-07-20 17:59:30 +02:00
return NT_STATUS_NO_MEMORY ;
2008-04-10 22:42:07 +02:00
}
2013-05-24 13:29:28 +02:00
status = cli_rpc_pipe_open_noauth ( ipc - > cli , table , & p - > pipe ) ;
2008-07-20 17:59:30 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-04-10 22:42:07 +02:00
TALLOC_FREE ( p ) ;
2008-07-20 17:59:30 +02:00
return status ;
2008-04-10 22:42:07 +02:00
}
2010-09-20 21:05:37 -07:00
DLIST_ADD ( ipc - > pipe_connections , p ) ;
2008-04-10 22:42:07 +02:00
2008-07-20 17:59:30 +02:00
* presult = p - > pipe ;
return NT_STATUS_OK ;
2008-04-10 22:42:07 +02:00
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-07-20 17:59:30 +02:00
static NTSTATUS pipe_cm_open ( TALLOC_CTX * ctx ,
2010-09-20 21:05:37 -07:00
struct client_ipc_connection * ipc ,
2013-05-17 16:13:26 +02:00
const struct ndr_interface_table * table ,
2008-07-20 17:59:30 +02:00
struct rpc_pipe_client * * presult )
2008-04-10 22:42:07 +02:00
{
2013-05-17 16:13:26 +02:00
if ( NT_STATUS_IS_OK ( pipe_cm_find ( ipc , table , presult ) ) ) {
2008-07-20 17:59:30 +02:00
return NT_STATUS_OK ;
2008-04-10 22:42:07 +02:00
}
2013-05-17 16:13:26 +02:00
return pipe_cm_connect ( ctx , ipc , table , presult ) ;
2008-04-10 22:42:07 +02:00
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR libnetapi_open_pipe ( struct libnetapi_ctx * ctx ,
2008-08-12 17:59:23 +02:00
const char * server_name ,
2013-05-17 16:10:13 +02:00
const struct ndr_interface_table * table ,
2008-07-20 17:59:30 +02:00
struct rpc_pipe_client * * presult )
2008-04-10 22:42:07 +02:00
{
2008-07-30 16:06:30 -07:00
struct rpc_pipe_client * result = NULL ;
2008-04-10 22:42:07 +02:00
NTSTATUS status ;
2008-08-12 17:59:23 +02:00
WERROR werr ;
2010-09-20 21:05:37 -07:00
struct client_ipc_connection * ipc = NULL ;
2008-04-10 22:42:07 +02:00
2008-08-12 17:59:23 +02:00
if ( ! presult ) {
2008-04-10 22:42:07 +02:00
return WERR_INVALID_PARAM ;
}
2010-09-20 21:05:37 -07:00
werr = libnetapi_open_ipc_connection ( ctx , server_name , & ipc ) ;
2008-08-12 17:59:23 +02:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
return werr ;
}
2013-05-17 16:13:26 +02:00
status = pipe_cm_open ( ctx , ipc , table , & result ) ;
2008-07-20 17:59:30 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-04-10 22:42:07 +02:00
libnetapi_set_error_string ( ctx , " failed to open PIPE %s: %s " ,
2013-08-08 17:40:22 +02:00
table - > name ,
2008-04-10 22:42:07 +02:00
get_friendly_nt_error_msg ( status ) ) ;
return WERR_DEST_NOT_FOUND ;
}
2008-07-20 17:59:30 +02:00
* presult = result ;
2008-08-12 17:59:23 +02:00
2008-04-10 22:42:07 +02:00
return WERR_OK ;
}
2011-04-06 14:21:30 +02:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR libnetapi_get_binding_handle ( struct libnetapi_ctx * ctx ,
const char * server_name ,
2013-05-17 16:08:16 +02:00
const struct ndr_interface_table * table ,
2011-04-06 14:21:30 +02:00
struct dcerpc_binding_handle * * binding_handle )
{
struct rpc_pipe_client * pipe_cli ;
WERROR result ;
* binding_handle = NULL ;
2013-05-17 16:10:13 +02:00
result = libnetapi_open_pipe ( ctx , server_name , table , & pipe_cli ) ;
2011-04-06 14:21:30 +02:00
if ( ! W_ERROR_IS_OK ( result ) ) {
return result ;
}
* binding_handle = pipe_cli - > binding_handle ;
return WERR_OK ;
}