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"
# include "lib/netapi/netapi.h"
2008-04-10 21:56:12 +02:00
# include "lib/netapi/netapi_private.h"
2008-04-10 21:41:03 +02:00
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-08-12 17:59:23 +02:00
static WERROR libnetapi_open_ipc_connection ( struct libnetapi_ctx * ctx ,
const char * server_name ,
struct cli_state * * cli )
2008-04-10 21:41:03 +02:00
{
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 ;
if ( ! ctx | | ! cli | | ! server_name ) {
return WERR_INVALID_PARAM ;
}
2009-03-17 14:53:06 -07:00
auth_info = user_auth_info_init ( NULL ) ;
if ( ! auth_info ) {
return WERR_NOMEM ;
2008-04-10 21:41:03 +02:00
}
2009-03-17 14:53:06 -07:00
auth_info - > signing_state = Undefined ;
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
}
cli_ipc = cli_cm_open ( ctx , NULL ,
2009-03-17 14:53:06 -07:00
server_name , " IPC$ " ,
auth_info ,
false , false ,
PROTOCOL_NT1 ,
0 , 0x20 ) ;
2009-03-26 10:26:59 +01:00
if ( cli_ipc ) {
cli_set_username ( cli_ipc , ctx - > username ) ;
cli_set_password ( cli_ipc , ctx - > password ) ;
cli_set_domain ( cli_ipc , ctx - > workgroup ) ;
}
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 ;
}
* cli = cli_ipc ;
return WERR_OK ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-04-10 22:42:07 +02:00
struct client_pipe_connection {
struct client_pipe_connection * prev , * next ;
struct rpc_pipe_client * pipe ;
2009-03-12 17:59:24 -07:00
struct cli_state * cli ;
2008-04-10 22:42:07 +02:00
} ;
static struct client_pipe_connection * pipe_connections ;
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-03-12 17:59:24 -07:00
WERROR libnetapi_shutdown_cm ( struct libnetapi_ctx * ctx )
{
struct client_pipe_connection * p ;
for ( p = pipe_connections ; p ; p = p - > next ) {
cli_shutdown ( p - > cli ) ;
}
return WERR_OK ;
}
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-07-20 17:59:30 +02:00
static NTSTATUS pipe_cm_find ( struct cli_state * cli ,
const struct ndr_syntax_id * interface ,
struct rpc_pipe_client * * presult )
2008-04-10 22:42:07 +02:00
{
struct client_pipe_connection * p ;
for ( p = pipe_connections ; p ; p = p - > next ) {
2008-04-20 14:05:25 +02:00
if ( ! rpc_pipe_np_smb_conn ( p - > pipe ) ) {
2008-07-20 17:59:30 +02:00
return NT_STATUS_PIPE_EMPTY ;
2008-04-10 22:42:07 +02:00
}
2008-07-20 17:59:30 +02:00
if ( strequal ( cli - > desthost , p - > pipe - > desthost )
& & ndr_syntax_id_equal ( & p - > pipe - > abstract_syntax ,
interface ) ) {
* 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 ,
struct cli_state * cli ,
const struct ndr_syntax_id * interface ,
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
p = TALLOC_ZERO_ARRAY ( mem_ctx , struct client_pipe_connection , 1 ) ;
if ( ! p ) {
2008-07-20 17:59:30 +02:00
return NT_STATUS_NO_MEMORY ;
2008-04-10 22:42:07 +02:00
}
2008-07-20 17:59:30 +02:00
status = cli_rpc_pipe_open_noauth ( cli , interface , & p - > pipe ) ;
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
}
2009-03-12 17:59:24 -07:00
p - > cli = cli ;
2008-04-10 22:42:07 +02:00
DLIST_ADD ( pipe_connections , p ) ;
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 ,
struct cli_state * cli ,
const struct ndr_syntax_id * interface ,
struct rpc_pipe_client * * presult )
2008-04-10 22:42:07 +02:00
{
2008-07-20 17:59:30 +02:00
if ( NT_STATUS_IS_OK ( pipe_cm_find ( cli , interface , presult ) ) ) {
return NT_STATUS_OK ;
2008-04-10 22:42:07 +02:00
}
2008-07-20 17:59:30 +02:00
return pipe_cm_connect ( ctx , cli , interface , 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 ,
2008-07-20 17:59:30 +02:00
const struct ndr_syntax_id * interface ,
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 ;
struct cli_state * cli = 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 ;
}
2008-08-12 17:59:23 +02:00
werr = libnetapi_open_ipc_connection ( ctx , server_name , & cli ) ;
if ( ! W_ERROR_IS_OK ( werr ) ) {
return werr ;
}
2008-07-20 17:59:30 +02:00
status = pipe_cm_open ( ctx , cli , interface , & result ) ;
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 " ,
2009-02-01 00:30:04 +01:00
get_pipe_name_from_iface ( interface ) ,
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 ;
}