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"
2010-08-05 10:49:53 +02:00
# include "popt_common.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"
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 ;
} ;
static struct client_ipc_connection * ipc_connections = NULL ;
/********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static struct client_ipc_connection * ipc_cm_find ( const char * server_name )
{
struct client_ipc_connection * p ;
for ( p = ipc_connections ; p ; p = p - > next ) {
if ( strequal ( p - > cli - > desthost , server_name ) ) {
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
{
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 ;
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 ;
}
2010-09-20 21:05:37 -07:00
p = ipc_cm_find ( server_name ) ;
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
}
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
}
2010-01-24 18:50:31 +01:00
if ( ctx - > use_ccache ) {
set_cmdline_auth_info_use_ccache ( 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 ;
}
2010-09-20 21:05:37 -07:00
p = TALLOC_ZERO_P ( ctx , struct client_ipc_connection ) ;
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 ;
DLIST_ADD ( 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-20 21:05:37 -07:00
struct client_ipc_connection * p ;
2009-03-12 17:59:24 -07:00
2010-09-20 21:05:37 -07:00
for ( p = 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 ,
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
{
struct client_pipe_connection * p ;
2010-09-20 21:05:37 -07:00
for ( p = ipc - > pipe_connections ; p ; p = p - > next ) {
2008-04-10 22:42:07 +02:00
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
}
2010-09-20 21:05:37 -07:00
if ( strequal ( ipc - > cli - > desthost , p - > pipe - > desthost )
2008-07-20 17:59:30 +02:00
& & 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 ,
2010-09-20 21:05:37 -07:00
struct client_ipc_connection * ipc ,
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
{
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
}
2010-09-20 21:05:37 -07:00
status = cli_rpc_pipe_open_noauth ( ipc - > cli , interface , & 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 ,
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
{
2010-09-20 21:05:37 -07:00
if ( NT_STATUS_IS_OK ( pipe_cm_find ( ipc , interface , presult ) ) ) {
2008-07-20 17:59:30 +02:00
return NT_STATUS_OK ;
2008-04-10 22:42:07 +02:00
}
2010-09-20 21:05:37 -07:00
return pipe_cm_connect ( ctx , ipc , 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 ,
2009-11-08 19:37:13 +01:00
const struct ndr_syntax_id * interface ,
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 ;
}
2010-09-20 21:05:37 -07:00
status = pipe_cm_open ( ctx , ipc , interface , & 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 " ,
2009-11-08 19:37:13 +01:00
get_pipe_name_from_syntax ( talloc_tos ( ) , 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 ;
}