2008-04-10 23:41:03 +04: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"
# include "lib/netapi/netapi.h"
2008-04-10 23:56:12 +04:00
# include "lib/netapi/netapi_private.h"
2011-05-06 13:47:43 +04:00
# include "libsmb/libsmb.h"
2011-02-28 12:19:44 +03:00
# include "rpc_client/cli_pipe.h"
2012-05-19 19:31:50 +04:00
# include "../libcli/smb/smbXcli_base.h"
2008-04-10 23:41:03 +04:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-09-21 08:05:37 +04: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-22 02:41:23 +04:00
static struct client_ipc_connection * ipc_cm_find (
struct libnetapi_private_ctx * priv_ctx , const char * server_name )
2010-09-21 08:05:37 +04:00
{
struct client_ipc_connection * p ;
2010-09-22 02:41:23 +04:00
for ( p = priv_ctx - > ipc_connections ; p ; p = p - > next ) {
2012-05-19 19:31:50 +04:00
const char * remote_name = smbXcli_conn_remote_name ( p - > cli - > conn ) ;
2011-07-22 18:19:00 +04:00
if ( strequal ( remote_name , server_name ) ) {
2010-09-21 08:05:37 +04:00
return p ;
}
}
return NULL ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-08-12 19:59:23 +04:00
static WERROR libnetapi_open_ipc_connection ( struct libnetapi_ctx * ctx ,
const char * server_name ,
2010-09-21 08:05:37 +04:00
struct client_ipc_connection * * pp )
2008-04-10 23:41:03 +04:00
{
2011-03-16 23:52:20 +03:00
struct libnetapi_private_ctx * priv_ctx ;
2008-04-10 23:41:03 +04:00
struct cli_state * cli_ipc = NULL ;
2010-09-21 08:05:37 +04:00
struct client_ipc_connection * p ;
2011-07-03 21:59:37 +04:00
NTSTATUS status ;
2021-03-18 13:14:39 +03:00
const char * username = NULL ;
const char * password = NULL ;
NET_API_STATUS rc ;
2021-03-18 15:39:54 +03:00
enum credentials_use_kerberos krb5_state ;
2008-04-10 23:41:03 +04:00
2010-09-21 08:05:37 +04:00
if ( ! ctx | | ! pp | | ! server_name ) {
2015-12-03 17:24:23 +03:00
return WERR_INVALID_PARAMETER ;
2008-04-10 23:41:03 +04:00
}
2011-03-16 23:52:20 +03:00
priv_ctx = ( struct libnetapi_private_ctx * ) ctx - > private_data ;
2010-09-22 02:41:23 +04:00
p = ipc_cm_find ( priv_ctx , server_name ) ;
2010-09-21 08:05:37 +04:00
if ( p ) {
* pp = p ;
return WERR_OK ;
}
2021-03-18 13:14:39 +03:00
rc = libnetapi_get_username ( ctx , & username ) ;
if ( rc ! = 0 ) {
return WERR_INTERNAL_ERROR ;
}
rc = libnetapi_get_password ( ctx , & password ) ;
if ( rc ! = 0 ) {
return WERR_INTERNAL_ERROR ;
}
2021-03-18 15:49:27 +03:00
if ( password = = NULL ) {
cli_credentials_set_cmdline_callbacks ( ctx - > creds ) ;
2009-05-14 01:57:26 +04:00
}
2008-04-10 23:41:03 +04:00
2021-03-18 15:49:27 +03:00
krb5_state = cli_credentials_get_kerberos_state ( ctx - > creds ) ;
2008-04-10 23:41:03 +04:00
2021-03-18 15:49:27 +03:00
if ( username ! = NULL & & username [ 0 ] ! = ' \0 ' & &
password ! = NULL & & password [ 0 ] ! = ' \0 ' & &
krb5_state = = CRED_USE_KERBEROS_REQUIRED ) {
2020-08-19 16:46:11 +03:00
cli_credentials_set_kerberos_state ( ctx - > creds ,
CRED_USE_KERBEROS_DESIRED ,
CRED_SPECIFIED ) ;
2010-01-24 20:50:31 +03:00
}
2011-07-03 21:59:37 +04:00
status = cli_cm_open ( ctx , NULL ,
server_name , " IPC$ " ,
2021-03-18 15:49:27 +03:00
ctx - > creds ,
2018-08-23 10:21:41 +03:00
NULL , 0 , 0x20 , & cli_ipc ) ;
2014-09-26 05:14:53 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-03 21:59:37 +04:00
cli_ipc = NULL ;
2009-03-26 12:26:59 +03:00
}
2009-03-18 00:53:06 +03:00
2008-04-10 23:41:03 +04:00
if ( ! cli_ipc ) {
libnetapi_set_error_string ( ctx ,
2008-04-10 23:56:12 +04:00
" Failed to connect to IPC$ share on %s " , server_name ) ;
2008-04-10 23:41:03 +04:00
return WERR_CAN_NOT_COMPLETE ;
}
2011-06-07 05:44:43 +04:00
p = talloc_zero ( ctx , struct client_ipc_connection ) ;
2010-09-21 08:05:37 +04:00
if ( p = = NULL ) {
2015-12-03 17:24:14 +03:00
return WERR_NOT_ENOUGH_MEMORY ;
2010-09-21 08:05:37 +04:00
}
2008-04-10 23:41:03 +04:00
2010-09-21 08:05:37 +04:00
p - > cli = cli_ipc ;
2010-09-22 02:41:23 +04:00
DLIST_ADD ( priv_ctx - > ipc_connections , p ) ;
2008-04-10 23:41:03 +04:00
2010-09-21 08:05:37 +04:00
* pp = p ;
2008-04-10 23:41:03 +04:00
2010-09-21 08:05:37 +04:00
return WERR_OK ;
}
2008-04-11 00:42:07 +04:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-03-13 03:59:24 +03:00
WERROR libnetapi_shutdown_cm ( struct libnetapi_ctx * ctx )
{
2010-09-22 02:41:23 +04:00
struct libnetapi_private_ctx * priv_ctx =
( struct libnetapi_private_ctx * ) ctx - > private_data ;
2010-09-21 08:05:37 +04:00
struct client_ipc_connection * p ;
2009-03-13 03:59:24 +03:00
2010-09-22 02:41:23 +04:00
for ( p = priv_ctx - > ipc_connections ; p ; p = p - > next ) {
2009-03-13 03:59:24 +03:00
cli_shutdown ( p - > cli ) ;
}
return WERR_OK ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-09-21 08:05:37 +04:00
static NTSTATUS pipe_cm_find ( struct client_ipc_connection * ipc ,
2013-05-17 18:13:26 +04:00
const struct ndr_interface_table * table ,
2008-07-20 19:59:30 +04:00
struct rpc_pipe_client * * presult )
2008-04-11 00:42:07 +04:00
{
struct client_pipe_connection * p ;
2010-09-21 08:05:37 +04:00
for ( p = ipc - > pipe_connections ; p ; p = p - > next ) {
2011-07-22 18:19:00 +04:00
const char * ipc_remote_name ;
2008-04-11 00:42:07 +04:00
2013-09-13 13:12:25 +04:00
if ( ! rpccli_is_connected ( p - > pipe ) ) {
2008-07-20 19:59:30 +04:00
return NT_STATUS_PIPE_EMPTY ;
2008-04-11 00:42:07 +04:00
}
2012-05-19 19:31:50 +04:00
ipc_remote_name = smbXcli_conn_remote_name ( ipc - > cli - > conn ) ;
2011-07-22 18:19:00 +04:00
if ( strequal ( ipc_remote_name , p - > pipe - > desthost )
2008-07-20 19:59:30 +04:00
& & ndr_syntax_id_equal ( & p - > pipe - > abstract_syntax ,
2013-05-17 18:13:26 +04:00
& table - > syntax_id ) ) {
2008-07-20 19:59:30 +04:00
* presult = p - > pipe ;
return NT_STATUS_OK ;
2008-04-11 00:42:07 +04:00
}
}
2008-07-20 19:59:30 +04:00
return NT_STATUS_PIPE_NOT_AVAILABLE ;
2008-04-11 00:42:07 +04:00
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-07-20 19:59:30 +04:00
static NTSTATUS pipe_cm_connect ( TALLOC_CTX * mem_ctx ,
2010-09-21 08:05:37 +04:00
struct client_ipc_connection * ipc ,
2013-05-17 18:13:26 +04:00
const struct ndr_interface_table * table ,
2008-07-20 19:59:30 +04:00
struct rpc_pipe_client * * presult )
2008-04-11 00:42:07 +04:00
{
struct client_pipe_connection * p ;
2008-07-20 19:59:30 +04:00
NTSTATUS status ;
2008-04-11 00:42:07 +04:00
2011-06-07 05:58:39 +04:00
p = talloc_zero_array ( mem_ctx , struct client_pipe_connection , 1 ) ;
2008-04-11 00:42:07 +04:00
if ( ! p ) {
2008-07-20 19:59:30 +04:00
return NT_STATUS_NO_MEMORY ;
2008-04-11 00:42:07 +04:00
}
2013-05-24 15:29:28 +04:00
status = cli_rpc_pipe_open_noauth ( ipc - > cli , table , & p - > pipe ) ;
2008-07-20 19:59:30 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-04-11 00:42:07 +04:00
TALLOC_FREE ( p ) ;
2008-07-20 19:59:30 +04:00
return status ;
2008-04-11 00:42:07 +04:00
}
2010-09-21 08:05:37 +04:00
DLIST_ADD ( ipc - > pipe_connections , p ) ;
2008-04-11 00:42:07 +04:00
2008-07-20 19:59:30 +04:00
* presult = p - > pipe ;
return NT_STATUS_OK ;
2008-04-11 00:42:07 +04:00
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-07-20 19:59:30 +04:00
static NTSTATUS pipe_cm_open ( TALLOC_CTX * ctx ,
2010-09-21 08:05:37 +04:00
struct client_ipc_connection * ipc ,
2013-05-17 18:13:26 +04:00
const struct ndr_interface_table * table ,
2008-07-20 19:59:30 +04:00
struct rpc_pipe_client * * presult )
2008-04-11 00:42:07 +04:00
{
2013-05-17 18:13:26 +04:00
if ( NT_STATUS_IS_OK ( pipe_cm_find ( ipc , table , presult ) ) ) {
2008-07-20 19:59:30 +04:00
return NT_STATUS_OK ;
2008-04-11 00:42:07 +04:00
}
2013-05-17 18:13:26 +04:00
return pipe_cm_connect ( ctx , ipc , table , presult ) ;
2008-04-11 00:42:07 +04:00
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR libnetapi_open_pipe ( struct libnetapi_ctx * ctx ,
2008-08-12 19:59:23 +04:00
const char * server_name ,
2013-05-17 18:10:13 +04:00
const struct ndr_interface_table * table ,
2008-07-20 19:59:30 +04:00
struct rpc_pipe_client * * presult )
2008-04-11 00:42:07 +04:00
{
2008-07-31 03:06:30 +04:00
struct rpc_pipe_client * result = NULL ;
2008-04-11 00:42:07 +04:00
NTSTATUS status ;
2008-08-12 19:59:23 +04:00
WERROR werr ;
2010-09-21 08:05:37 +04:00
struct client_ipc_connection * ipc = NULL ;
2008-04-11 00:42:07 +04:00
2008-08-12 19:59:23 +04:00
if ( ! presult ) {
2015-12-03 17:24:23 +03:00
return WERR_INVALID_PARAMETER ;
2008-04-11 00:42:07 +04:00
}
2010-09-21 08:05:37 +04:00
werr = libnetapi_open_ipc_connection ( ctx , server_name , & ipc ) ;
2008-08-12 19:59:23 +04:00
if ( ! W_ERROR_IS_OK ( werr ) ) {
return werr ;
}
2013-05-17 18:13:26 +04:00
status = pipe_cm_open ( ctx , ipc , table , & result ) ;
2008-07-20 19:59:30 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-04-11 00:42:07 +04:00
libnetapi_set_error_string ( ctx , " failed to open PIPE %s: %s " ,
2013-08-08 19:40:22 +04:00
table - > name ,
2008-04-11 00:42:07 +04:00
get_friendly_nt_error_msg ( status ) ) ;
2015-12-03 17:24:33 +03:00
return WERR_NERR_DESTNOTFOUND ;
2008-04-11 00:42:07 +04:00
}
2008-07-20 19:59:30 +04:00
* presult = result ;
2008-08-12 19:59:23 +04:00
2008-04-11 00:42:07 +04:00
return WERR_OK ;
}
2011-04-06 16:21:30 +04:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
WERROR libnetapi_get_binding_handle ( struct libnetapi_ctx * ctx ,
const char * server_name ,
2013-05-17 18:08:16 +04:00
const struct ndr_interface_table * table ,
2011-04-06 16:21:30 +04:00
struct dcerpc_binding_handle * * binding_handle )
{
struct rpc_pipe_client * pipe_cli ;
WERROR result ;
* binding_handle = NULL ;
2013-05-17 18:10:13 +04:00
result = libnetapi_open_pipe ( ctx , server_name , table , & pipe_cli ) ;
2011-04-06 16:21:30 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
return result ;
}
* binding_handle = pipe_cli - > binding_handle ;
return WERR_OK ;
}