mirror of
https://github.com/samba-team/samba.git
synced 2025-01-13 13:18:06 +03:00
e59e787b48
more no previous prototype warnings
(This used to be commit 41be182f78
)
351 lines
8.1 KiB
C
351 lines
8.1 KiB
C
|
|
/*
|
|
* Unix SMB/CIFS implementation.
|
|
* MS-RPC client library implementation
|
|
* Copyright (C) Chris Nicholls 2005.
|
|
*
|
|
* 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 2 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, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
#include "libmsrpc.h"
|
|
#include "libmsrpc_internal.h"
|
|
#include "libsmbclient.h"
|
|
#include "libsmb_internal.h"
|
|
|
|
int cac_InitHandleData( CacServerHandle * hnd );
|
|
|
|
/*this function is based on code found in smbc_init_context() (libsmb/libsmbclient.c)*/
|
|
void cac_Init( int debug )
|
|
{
|
|
if ( debug < 0 || debug > 99 )
|
|
debug = 0;
|
|
|
|
DEBUGLEVEL = debug;
|
|
|
|
setup_logging( "libmsrpc", True );
|
|
}
|
|
|
|
int cac_InitHandleMem( CacServerHandle * hnd )
|
|
{
|
|
hnd->username = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
|
|
|
|
if ( !hnd->username )
|
|
return CAC_FAILURE;
|
|
|
|
hnd->username[0] = '\0';
|
|
|
|
hnd->domain = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
|
|
if ( !hnd->domain )
|
|
return CAC_FAILURE;
|
|
|
|
hnd->domain[0] = '\0';
|
|
|
|
hnd->netbios_name = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
|
|
if ( !hnd->netbios_name )
|
|
return CAC_FAILURE;
|
|
|
|
hnd->netbios_name[0] = '\0';
|
|
|
|
hnd->password = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
|
|
if ( !hnd->password )
|
|
return CAC_FAILURE;
|
|
|
|
hnd->password[0] = '\0';
|
|
|
|
hnd->server = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
|
|
if ( !hnd->server )
|
|
return CAC_FAILURE;
|
|
|
|
hnd->server[0] = '\0';
|
|
|
|
return CAC_SUCCESS;
|
|
}
|
|
|
|
CacServerHandle *cac_NewServerHandle( BOOL allocate_fields )
|
|
{
|
|
CacServerHandle *hnd;
|
|
|
|
hnd = SMB_MALLOC_P( CacServerHandle );
|
|
|
|
if ( !hnd ) {
|
|
errno = ENOMEM;
|
|
return NULL;
|
|
}
|
|
|
|
ZERO_STRUCTP( hnd );
|
|
|
|
if ( allocate_fields == True ) {
|
|
if ( !cac_InitHandleMem( hnd ) ) {
|
|
SAFE_FREE( hnd );
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
hnd->_internal.ctx = smbc_new_context( );
|
|
if ( !hnd->_internal.ctx ) {
|
|
cac_FreeHandle( hnd );
|
|
return NULL;
|
|
}
|
|
|
|
hnd->_internal.ctx->callbacks.auth_fn = cac_GetAuthDataFn;
|
|
|
|
/*add defaults */
|
|
hnd->debug = 0;
|
|
|
|
/*start at the highest and it will fall down after trying the functions */
|
|
hnd->_internal.srv_level = SRV_WIN_2K3;
|
|
|
|
hnd->_internal.user_supplied_ctx = False;
|
|
|
|
return hnd;
|
|
}
|
|
|
|
int cac_InitHandleData( CacServerHandle * hnd )
|
|
{
|
|
/*store any automatically initialized values */
|
|
if ( !hnd->netbios_name ) {
|
|
hnd->netbios_name =
|
|
SMB_STRDUP( hnd->_internal.ctx->netbios_name );
|
|
} else if ( hnd->netbios_name[0] == '\0' ) {
|
|
strncpy( hnd->netbios_name, hnd->_internal.ctx->netbios_name,
|
|
sizeof( fstring ) );
|
|
}
|
|
|
|
if ( !hnd->username ) {
|
|
hnd->username = SMB_STRDUP( hnd->_internal.ctx->user );
|
|
} else if ( hnd->username[0] == '\0' ) {
|
|
strncpy( hnd->username, hnd->_internal.ctx->user,
|
|
sizeof( fstring ) );
|
|
}
|
|
|
|
if ( !hnd->domain ) {
|
|
hnd->domain = SMB_STRDUP( hnd->_internal.ctx->workgroup );
|
|
} else if ( hnd->domain[0] == '\0' ) {
|
|
strncpy( hnd->domain, hnd->_internal.ctx->workgroup,
|
|
sizeof( fstring ) );
|
|
}
|
|
|
|
return CAC_SUCCESS;
|
|
}
|
|
|
|
void cac_SetAuthDataFn( CacServerHandle * hnd, smbc_get_auth_data_fn auth_fn )
|
|
{
|
|
hnd->_internal.ctx->callbacks.auth_fn = auth_fn;
|
|
}
|
|
|
|
void cac_SetSmbcContext( CacServerHandle * hnd, SMBCCTX * ctx )
|
|
{
|
|
|
|
SAFE_FREE( hnd->_internal.ctx );
|
|
|
|
hnd->_internal.user_supplied_ctx = True;
|
|
|
|
hnd->_internal.ctx = ctx;
|
|
|
|
/*_try_ to avoid any problems that might occur if cac_Connect() isn't called*/
|
|
/*cac_InitHandleData(hnd); */
|
|
}
|
|
|
|
/*used internally*/
|
|
SMBCSRV *cac_GetServer( CacServerHandle * hnd )
|
|
{
|
|
SMBCSRV *srv;
|
|
|
|
if ( !hnd || !hnd->_internal.ctx ) {
|
|
return NULL;
|
|
}
|
|
|
|
srv = smbc_attr_server( hnd->_internal.ctx, hnd->server, "IPC$",
|
|
hnd->domain, hnd->username, hnd->password,
|
|
NULL );
|
|
if ( !srv ) {
|
|
hnd->status = NT_STATUS_UNSUCCESSFUL;
|
|
DEBUG( 1,
|
|
( "cac_GetServer: Could not find server connection.\n" ) );
|
|
}
|
|
|
|
return srv;
|
|
}
|
|
|
|
|
|
int cac_Connect( CacServerHandle * hnd, const char *srv )
|
|
{
|
|
if ( !hnd ) {
|
|
return CAC_FAILURE;
|
|
}
|
|
|
|
/*these values should be initialized by the user */
|
|
if ( !hnd->server && !srv ) {
|
|
return CAC_FAILURE;
|
|
}
|
|
|
|
|
|
/*change the server name in the server handle if necessary */
|
|
if ( srv && hnd->server && strcmp( hnd->server, srv ) == 0 ) {
|
|
SAFE_FREE( hnd->server );
|
|
hnd->server = SMB_STRDUP( srv );
|
|
}
|
|
|
|
|
|
/*first see if the context has already been setup */
|
|
if ( !( hnd->_internal.ctx->internal->_initialized ) ) {
|
|
hnd->_internal.ctx->debug = hnd->debug;
|
|
|
|
/*initialize the context */
|
|
if ( !smbc_init_context( hnd->_internal.ctx ) ) {
|
|
return CAC_FAILURE;
|
|
}
|
|
}
|
|
|
|
/*copy any uninitialized values out of the smbc context into the handle */
|
|
if ( !cac_InitHandleData( hnd ) ) {
|
|
return CAC_FAILURE;
|
|
}
|
|
|
|
DEBUG( 3, ( "cac_Connect: Username: %s\n", hnd->username ) );
|
|
DEBUG( 3, ( "cac_Connect: Domain: %s\n", hnd->domain ) );
|
|
DEBUG( 3, ( "cac_Connect: Netbios Name: %s\n", hnd->netbios_name ) );
|
|
|
|
if ( !cac_GetServer( hnd ) ) {
|
|
return CAC_FAILURE;
|
|
}
|
|
|
|
return CAC_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
void cac_FreeHandle( CacServerHandle * hnd )
|
|
{
|
|
if ( !hnd )
|
|
return;
|
|
|
|
/*only free the context if we created it */
|
|
if ( !hnd->_internal.user_supplied_ctx ) {
|
|
smbc_free_context( hnd->_internal.ctx, True );
|
|
}
|
|
|
|
SAFE_FREE( hnd->netbios_name );
|
|
SAFE_FREE( hnd->domain );
|
|
SAFE_FREE( hnd->username );
|
|
SAFE_FREE( hnd->password );
|
|
SAFE_FREE( hnd->server );
|
|
SAFE_FREE( hnd );
|
|
|
|
}
|
|
|
|
void cac_InitCacTime( CacTime * cactime, NTTIME nttime )
|
|
{
|
|
float high, low;
|
|
uint32 sec;
|
|
|
|
if ( !cactime )
|
|
return;
|
|
|
|
ZERO_STRUCTP( cactime );
|
|
|
|
/*this code is taken from display_time() found in rpcclient/cmd_samr.c */
|
|
if ( nttime == 0 )
|
|
return;
|
|
|
|
if ( nttime == 0x80000000000000LL )
|
|
return;
|
|
|
|
high = 65536;
|
|
high = high / 10000;
|
|
high = high * 65536;
|
|
high = high / 1000;
|
|
high = high * ( ~( nttime >> 32 ) );
|
|
|
|
low = ~( nttime & 0xFFFFFFFF );
|
|
low = low / ( 1000 * 1000 * 10 );
|
|
|
|
sec = high + low;
|
|
|
|
cactime->days = sec / ( 60 * 60 * 24 );
|
|
cactime->hours =
|
|
( sec - ( cactime->days * 60 * 60 * 24 ) ) / ( 60 * 60 );
|
|
cactime->minutes =
|
|
( sec - ( cactime->days * 60 * 60 * 24 ) -
|
|
( cactime->hours * 60 * 60 ) ) / 60;
|
|
cactime->seconds =
|
|
sec - ( cactime->days * 60 * 60 * 24 ) -
|
|
( cactime->hours * 60 * 60 ) - ( cactime->minutes * 60 );
|
|
}
|
|
|
|
void cac_GetAuthDataFn( const char *pServer,
|
|
const char *pShare,
|
|
char *pWorkgroup,
|
|
int maxLenWorkgroup,
|
|
char *pUsername,
|
|
int maxLenUsername,
|
|
char *pPassword, int maxLenPassword )
|
|
{
|
|
char temp[sizeof( fstring )];
|
|
|
|
static char authUsername[sizeof( fstring )];
|
|
static char authWorkgroup[sizeof( fstring )];
|
|
static char authPassword[sizeof( fstring )];
|
|
static char authSet = 0;
|
|
|
|
char *pass = NULL;
|
|
|
|
|
|
if ( authSet ) {
|
|
strncpy( pWorkgroup, authWorkgroup, maxLenWorkgroup - 1 );
|
|
strncpy( pUsername, authUsername, maxLenUsername - 1 );
|
|
strncpy( pPassword, authPassword, maxLenPassword - 1 );
|
|
} else {
|
|
d_printf( "Domain: [%s] ", pWorkgroup );
|
|
fgets( temp, sizeof( fstring ), stdin );
|
|
|
|
if ( temp[strlen( temp ) - 1] == '\n' ) { /* A new line? */
|
|
temp[strlen( temp ) - 1] = '\0';
|
|
}
|
|
|
|
|
|
if ( temp[0] != '\0' ) {
|
|
strncpy( pWorkgroup, temp, maxLenWorkgroup - 1 );
|
|
strncpy( authWorkgroup, temp, maxLenWorkgroup - 1 );
|
|
}
|
|
|
|
d_printf( "Username: [%s] ", pUsername );
|
|
fgets( temp, sizeof( fstring ), stdin );
|
|
|
|
if ( temp[strlen( temp ) - 1] == '\n' ) { /* A new line? */
|
|
temp[strlen( temp ) - 1] = '\0';
|
|
}
|
|
|
|
if ( temp[0] != '\0' ) {
|
|
strncpy( pUsername, temp, maxLenUsername - 1 );
|
|
strncpy( authUsername, pUsername,
|
|
maxLenUsername - 1 );
|
|
}
|
|
|
|
pass = getpass( "Password: " );
|
|
if ( pass )
|
|
fstrcpy( temp, pass );
|
|
if ( temp[strlen( temp ) - 1] == '\n' ) { /* A new line? */
|
|
temp[strlen( temp ) - 1] = '\0';
|
|
}
|
|
if ( temp[0] != '\0' ) {
|
|
strncpy( pPassword, temp, maxLenPassword - 1 );
|
|
strncpy( authPassword, pPassword,
|
|
maxLenPassword - 1 );
|
|
}
|
|
authSet = 1;
|
|
}
|
|
}
|