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"
2012-01-30 13:53:18 +04:00
# include "auth_info.h"
2008-04-10 23:41:03 +04:00
# 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"
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 ) {
2011-07-22 18:19:00 +04:00
const char * remote_name = cli_state_remote_name ( p - > cli ) ;
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 ;
2009-03-18 00:53:06 +03:00
struct user_auth_info * auth_info = NULL ;
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 ;
2008-04-10 23:41:03 +04:00
2010-09-21 08:05:37 +04:00
if ( ! ctx | | ! pp | | ! server_name ) {
2008-04-10 23:41:03 +04:00
return WERR_INVALID_PARAM ;
}
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 ;
}
auth_info = user_auth_info_init ( ctx ) ;
2009-03-18 00:53:06 +03:00
if ( ! auth_info ) {
return WERR_NOMEM ;
2008-04-10 23:41:03 +04:00
}
2011-11-02 21:41:50 +04:00
auth_info - > signing_state = SMB_SIGNING_DEFAULT ;
2009-03-18 00:53:06 +03:00
set_cmdline_auth_info_use_kerberos ( auth_info , ctx - > use_kerberos ) ;
set_cmdline_auth_info_username ( auth_info , ctx - > username ) ;
2009-05-14 01:57:26 +04:00
if ( ctx - > password ) {
set_cmdline_auth_info_password ( auth_info , ctx - > password ) ;
} else {
set_cmdline_auth_info_getpass ( auth_info ) ;
}
2008-04-10 23:41:03 +04:00
if ( ctx - > username & & ctx - > username [ 0 ] & &
2008-04-13 21:22:24 +04:00
ctx - > password & & ctx - > password [ 0 ] & &
ctx - > use_kerberos ) {
2009-03-18 00:53:06 +03:00
set_cmdline_auth_info_fallback_after_kerberos ( auth_info , true ) ;
2008-04-10 23:41:03 +04:00
}
2010-01-24 20:50:31 +03:00
if ( ctx - > use_ccache ) {
set_cmdline_auth_info_use_ccache ( auth_info , true ) ;
}
2011-07-03 21:59:37 +04:00
status = cli_cm_open ( ctx , NULL ,
server_name , " IPC$ " ,
auth_info ,
false , false ,
PROTOCOL_NT1 ,
0 , 0x20 , & cli_ipc ) ;
if ( NT_STATUS_IS_OK ( status ) ) {
2009-03-26 12:26:59 +03:00
cli_set_username ( cli_ipc , ctx - > username ) ;
cli_set_password ( cli_ipc , ctx - > password ) ;
cli_set_domain ( cli_ipc , ctx - > workgroup ) ;
2011-07-03 21:59:37 +04:00
} else {
cli_ipc = NULL ;
2009-03-26 12:26:59 +03:00
}
2009-03-18 00:53:06 +03:00
TALLOC_FREE ( auth_info ) ;
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 ) {
return WERR_NOMEM ;
}
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 ,
2008-07-20 19:59:30 +04:00
const struct ndr_syntax_id * interface ,
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
2008-04-20 16:05:25 +04:00
if ( ! rpc_pipe_np_smb_conn ( p - > pipe ) ) {
2008-07-20 19:59:30 +04:00
return NT_STATUS_PIPE_EMPTY ;
2008-04-11 00:42:07 +04:00
}
2011-07-22 18:19:00 +04:00
ipc_remote_name = cli_state_remote_name ( ipc - > cli ) ;
if ( strequal ( ipc_remote_name , p - > pipe - > desthost )
2008-07-20 19:59:30 +04:00
& & ndr_syntax_id_equal ( & p - > pipe - > abstract_syntax ,
interface ) ) {
* 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 ,
2008-07-20 19:59:30 +04:00
const struct ndr_syntax_id * interface ,
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
}
2010-09-21 08:05:37 +04:00
status = cli_rpc_pipe_open_noauth ( ipc - > cli , interface , & 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 ,
2008-07-20 19:59:30 +04:00
const struct ndr_syntax_id * interface ,
struct rpc_pipe_client * * presult )
2008-04-11 00:42:07 +04:00
{
2010-09-21 08:05:37 +04:00
if ( NT_STATUS_IS_OK ( pipe_cm_find ( ipc , interface , presult ) ) ) {
2008-07-20 19:59:30 +04:00
return NT_STATUS_OK ;
2008-04-11 00:42:07 +04:00
}
2010-09-21 08:05:37 +04:00
return pipe_cm_connect ( ctx , ipc , interface , 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 ,
2009-11-08 21:37:13 +03:00
const struct ndr_syntax_id * interface ,
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 ) {
2008-04-11 00:42:07 +04:00
return WERR_INVALID_PARAM ;
}
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 ;
}
2010-09-21 08:05:37 +04:00
status = pipe_cm_open ( ctx , ipc , interface , & 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 " ,
2009-11-08 21:37:13 +03:00
get_pipe_name_from_syntax ( talloc_tos ( ) , interface ) ,
2008-04-11 00:42:07 +04:00
get_friendly_nt_error_msg ( status ) ) ;
return WERR_DEST_NOT_FOUND ;
}
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 ,
const struct ndr_syntax_id * interface ,
struct dcerpc_binding_handle * * binding_handle )
{
struct rpc_pipe_client * pipe_cli ;
WERROR result ;
* binding_handle = NULL ;
result = libnetapi_open_pipe ( ctx , server_name , interface , & pipe_cli ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
return result ;
}
* binding_handle = pipe_cli - > binding_handle ;
return WERR_OK ;
}