3 * Unix SMB/CIFS implementation.
4 * MS-RPC client library implementation
5 * Copyright (C) Chris Nicholls 2005.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
22 #include "libmsrpc_internal.h"
23 #include "libsmbclient.h"
24 #include "libsmb_internal.h"
26 int cac_InitHandleData( CacServerHandle * hnd );
28 /*this function is based on code found in smbc_init_context() (libsmb/libsmbclient.c)*/
29 void cac_Init( int debug )
31 if ( debug < 0 || debug > 99 )
36 setup_logging( "libmsrpc", True );
39 int cac_InitHandleMem( CacServerHandle * hnd )
41 hnd->username = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
46 hnd->username[0] = '\0';
48 hnd->domain = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
52 hnd->domain[0] = '\0';
54 hnd->netbios_name = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
55 if ( !hnd->netbios_name )
58 hnd->netbios_name[0] = '\0';
60 hnd->password = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
64 hnd->password[0] = '\0';
66 hnd->server = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
70 hnd->server[0] = '\0';
75 CacServerHandle *cac_NewServerHandle( BOOL allocate_fields )
79 hnd = SMB_MALLOC_P( CacServerHandle );
88 if ( allocate_fields == True ) {
89 if ( !cac_InitHandleMem( hnd ) ) {
95 hnd->_internal.ctx = smbc_new_context( );
96 if ( !hnd->_internal.ctx ) {
97 cac_FreeHandle( hnd );
101 hnd->_internal.ctx->callbacks.auth_fn = cac_GetAuthDataFn;
106 /*start at the highest and it will fall down after trying the functions */
107 hnd->_internal.srv_level = SRV_WIN_2K3;
109 hnd->_internal.user_supplied_ctx = False;
114 int cac_InitHandleData( CacServerHandle * hnd )
116 /*store any automatically initialized values */
117 if ( !hnd->netbios_name ) {
119 SMB_STRDUP( hnd->_internal.ctx->netbios_name );
120 } else if ( hnd->netbios_name[0] == '\0' ) {
121 strncpy( hnd->netbios_name, hnd->_internal.ctx->netbios_name,
125 if ( !hnd->username ) {
126 hnd->username = SMB_STRDUP( hnd->_internal.ctx->user );
127 } else if ( hnd->username[0] == '\0' ) {
128 strncpy( hnd->username, hnd->_internal.ctx->user,
132 if ( !hnd->domain ) {
133 hnd->domain = SMB_STRDUP( hnd->_internal.ctx->workgroup );
134 } else if ( hnd->domain[0] == '\0' ) {
135 strncpy( hnd->domain, hnd->_internal.ctx->workgroup,
142 void cac_SetAuthDataFn( CacServerHandle * hnd, smbc_get_auth_data_fn auth_fn )
144 hnd->_internal.ctx->callbacks.auth_fn = auth_fn;
147 void cac_SetSmbcContext( CacServerHandle * hnd, SMBCCTX * ctx )
150 SAFE_FREE( hnd->_internal.ctx );
152 hnd->_internal.user_supplied_ctx = True;
154 hnd->_internal.ctx = ctx;
156 /*_try_ to avoid any problems that might occur if cac_Connect() isn't called*/
157 /*cac_InitHandleData(hnd); */
161 SMBCSRV *cac_GetServer( CacServerHandle * hnd )
165 if ( !hnd || !hnd->_internal.ctx ) {
169 srv = smbc_attr_server( hnd->_internal.ctx, hnd->server, "IPC$",
170 hnd->domain, hnd->username, hnd->password,
173 hnd->status = NT_STATUS_UNSUCCESSFUL;
175 ( "cac_GetServer: Could not find server connection.\n" ) );
182 int cac_Connect( CacServerHandle * hnd, const char *srv )
188 /*these values should be initialized by the user */
189 if ( !hnd->server && !srv ) {
194 /*change the server name in the server handle if necessary */
195 if ( srv && hnd->server && strcmp( hnd->server, srv ) == 0 ) {
196 SAFE_FREE( hnd->server );
197 hnd->server = SMB_STRDUP( srv );
201 /*first see if the context has already been setup */
202 if ( !( hnd->_internal.ctx->internal->_initialized ) ) {
203 hnd->_internal.ctx->debug = hnd->debug;
205 /*initialize the context */
206 if ( !smbc_init_context( hnd->_internal.ctx ) ) {
211 /*copy any uninitialized values out of the smbc context into the handle */
212 if ( !cac_InitHandleData( hnd ) ) {
216 DEBUG( 3, ( "cac_Connect: Username: %s\n", hnd->username ) );
217 DEBUG( 3, ( "cac_Connect: Domain: %s\n", hnd->domain ) );
218 DEBUG( 3, ( "cac_Connect: Netbios Name: %s\n", hnd->netbios_name ) );
220 if ( !cac_GetServer( hnd ) ) {
229 void cac_FreeHandle( CacServerHandle * hnd )
234 /*only free the context if we created it */
235 if ( !hnd->_internal.user_supplied_ctx ) {
236 smbc_free_context( hnd->_internal.ctx, True );
239 SAFE_FREE( hnd->netbios_name );
240 SAFE_FREE( hnd->domain );
241 SAFE_FREE( hnd->username );
242 SAFE_FREE( hnd->password );
243 SAFE_FREE( hnd->server );
248 void cac_InitCacTime( CacTime * cactime, NTTIME nttime )
256 ZERO_STRUCTP( cactime );
258 /*this code is taken from display_time() found in rpcclient/cmd_samr.c */
262 if ( nttime == 0x80000000000000LL )
269 high = high * ( ~( nttime >> 32 ) );
271 low = ~( nttime & 0xFFFFFFFF );
272 low = low / ( 1000 * 1000 * 10 );
276 cactime->days = sec / ( 60 * 60 * 24 );
278 ( sec - ( cactime->days * 60 * 60 * 24 ) ) / ( 60 * 60 );
280 ( sec - ( cactime->days * 60 * 60 * 24 ) -
281 ( cactime->hours * 60 * 60 ) ) / 60;
283 sec - ( cactime->days * 60 * 60 * 24 ) -
284 ( cactime->hours * 60 * 60 ) - ( cactime->minutes * 60 );
287 void cac_GetAuthDataFn( const char *pServer,
293 char *pPassword, int maxLenPassword )
295 char temp[sizeof( fstring )];
297 static char authUsername[sizeof( fstring )];
298 static char authWorkgroup[sizeof( fstring )];
299 static char authPassword[sizeof( fstring )];
300 static char authSet = 0;
306 strncpy( pWorkgroup, authWorkgroup, maxLenWorkgroup - 1 );
307 strncpy( pUsername, authUsername, maxLenUsername - 1 );
308 strncpy( pPassword, authPassword, maxLenPassword - 1 );
310 d_printf( "Domain: [%s] ", pWorkgroup );
311 fgets( temp, sizeof( fstring ), stdin );
313 if ( temp[strlen( temp ) - 1] == '\n' ) { /* A new line? */
314 temp[strlen( temp ) - 1] = '\0';
318 if ( temp[0] != '\0' ) {
319 strncpy( pWorkgroup, temp, maxLenWorkgroup - 1 );
320 strncpy( authWorkgroup, temp, maxLenWorkgroup - 1 );
323 d_printf( "Username: [%s] ", pUsername );
324 fgets( temp, sizeof( fstring ), stdin );
326 if ( temp[strlen( temp ) - 1] == '\n' ) { /* A new line? */
327 temp[strlen( temp ) - 1] = '\0';
330 if ( temp[0] != '\0' ) {
331 strncpy( pUsername, temp, maxLenUsername - 1 );
332 strncpy( authUsername, pUsername,
333 maxLenUsername - 1 );
336 pass = getpass( "Password: " );
338 fstrcpy( temp, pass );
339 if ( temp[strlen( temp ) - 1] == '\n' ) { /* A new line? */
340 temp[strlen( temp ) - 1] = '\0';
342 if ( temp[0] != '\0' ) {
343 strncpy( pPassword, temp, maxLenPassword - 1 );
344 strncpy( authPassword, pPassword,
345 maxLenPassword - 1 );