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 2 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, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "libmsrpc_internal.h"
24 #include "libsmbclient.h"
25 #include "libsmb_internal.h"
27 /*this function is based on code found in smbc_init_context() (libsmb/libsmbclient.c)*/
28 void cac_Init( int debug
)
30 if ( debug
< 0 || debug
> 99 )
35 setup_logging( "libmsrpc", True
);
38 int cac_InitHandleMem( CacServerHandle
* hnd
)
40 hnd
->username
= SMB_MALLOC_ARRAY( char, sizeof( fstring
) );
45 hnd
->username
[0] = '\0';
47 hnd
->domain
= SMB_MALLOC_ARRAY( char, sizeof( fstring
) );
51 hnd
->domain
[0] = '\0';
53 hnd
->netbios_name
= SMB_MALLOC_ARRAY( char, sizeof( fstring
) );
54 if ( !hnd
->netbios_name
)
57 hnd
->netbios_name
[0] = '\0';
59 hnd
->password
= SMB_MALLOC_ARRAY( char, sizeof( fstring
) );
63 hnd
->password
[0] = '\0';
65 hnd
->server
= SMB_MALLOC_ARRAY( char, sizeof( fstring
) );
69 hnd
->server
[0] = '\0';
74 CacServerHandle
*cac_NewServerHandle( BOOL allocate_fields
)
78 hnd
= SMB_MALLOC_P( CacServerHandle
);
87 if ( allocate_fields
== True
) {
88 if ( !cac_InitHandleMem( hnd
) ) {
94 hnd
->_internal
.ctx
= smbc_new_context( );
95 if ( !hnd
->_internal
.ctx
) {
96 cac_FreeHandle( hnd
);
100 hnd
->_internal
.ctx
->callbacks
.auth_fn
= cac_GetAuthDataFn
;
105 /*start at the highest and it will fall down after trying the functions */
106 hnd
->_internal
.srv_level
= SRV_WIN_2K3
;
108 hnd
->_internal
.user_supplied_ctx
= False
;
113 int cac_InitHandleData( CacServerHandle
* hnd
)
115 /*store any automatically initialized values */
116 if ( !hnd
->netbios_name
) {
118 SMB_STRDUP( hnd
->_internal
.ctx
->netbios_name
);
119 } else if ( hnd
->netbios_name
[0] == '\0' ) {
120 strncpy( hnd
->netbios_name
, hnd
->_internal
.ctx
->netbios_name
,
124 if ( !hnd
->username
) {
125 hnd
->username
= SMB_STRDUP( hnd
->_internal
.ctx
->user
);
126 } else if ( hnd
->username
[0] == '\0' ) {
127 strncpy( hnd
->username
, hnd
->_internal
.ctx
->user
,
131 if ( !hnd
->domain
) {
132 hnd
->domain
= SMB_STRDUP( hnd
->_internal
.ctx
->workgroup
);
133 } else if ( hnd
->domain
[0] == '\0' ) {
134 strncpy( hnd
->domain
, hnd
->_internal
.ctx
->workgroup
,
141 void cac_SetAuthDataFn( CacServerHandle
* hnd
, smbc_get_auth_data_fn auth_fn
)
143 hnd
->_internal
.ctx
->callbacks
.auth_fn
= auth_fn
;
146 void cac_SetSmbcContext( CacServerHandle
* hnd
, SMBCCTX
* ctx
)
149 SAFE_FREE( hnd
->_internal
.ctx
);
151 hnd
->_internal
.user_supplied_ctx
= True
;
153 hnd
->_internal
.ctx
= ctx
;
155 /*_try_ to avoid any problems that might occur if cac_Connect() isn't called*/
156 /*cac_InitHandleData(hnd); */
160 SMBCSRV
*cac_GetServer( CacServerHandle
* hnd
)
164 if ( !hnd
|| !hnd
->_internal
.ctx
) {
168 srv
= smbc_attr_server( hnd
->_internal
.ctx
, hnd
->server
, "IPC$",
169 hnd
->domain
, hnd
->username
, hnd
->password
,
172 hnd
->status
= NT_STATUS_UNSUCCESSFUL
;
174 ( "cac_GetServer: Could not find server connection.\n" ) );
181 int cac_Connect( CacServerHandle
* hnd
, const char *srv
)
187 /*these values should be initialized by the user */
188 if ( !hnd
->server
&& !srv
) {
193 /*change the server name in the server handle if necessary */
194 if ( srv
&& hnd
->server
&& strcmp( hnd
->server
, srv
) == 0 ) {
195 SAFE_FREE( hnd
->server
);
196 hnd
->server
= SMB_STRDUP( srv
);
200 /*first see if the context has already been setup */
201 if ( !( hnd
->_internal
.ctx
->internal
->_initialized
) ) {
202 hnd
->_internal
.ctx
->debug
= hnd
->debug
;
204 /*initialize the context */
205 if ( !smbc_init_context( hnd
->_internal
.ctx
) ) {
210 /*copy any uninitialized values out of the smbc context into the handle */
211 if ( !cac_InitHandleData( hnd
) ) {
215 DEBUG( 3, ( "cac_Connect: Username: %s\n", hnd
->username
) );
216 DEBUG( 3, ( "cac_Connect: Domain: %s\n", hnd
->domain
) );
217 DEBUG( 3, ( "cac_Connect: Netbios Name: %s\n", hnd
->netbios_name
) );
219 if ( !cac_GetServer( hnd
) ) {
228 void cac_FreeHandle( CacServerHandle
* hnd
)
233 /*only free the context if we created it */
234 if ( !hnd
->_internal
.user_supplied_ctx
) {
235 smbc_free_context( hnd
->_internal
.ctx
, True
);
238 SAFE_FREE( hnd
->netbios_name
);
239 SAFE_FREE( hnd
->domain
);
240 SAFE_FREE( hnd
->username
);
241 SAFE_FREE( hnd
->password
);
242 SAFE_FREE( hnd
->server
);
247 void cac_InitCacTime( CacTime
* cactime
, NTTIME nttime
)
255 ZERO_STRUCTP( cactime
);
257 /*this code is taken from display_time() found in rpcclient/cmd_samr.c */
261 if ( nttime
== 0x80000000000000LL
)
268 high
= high
* ( ~( nttime
>> 32 ) );
270 low
= ~( nttime
& 0xFFFFFFFF );
271 low
= low
/ ( 1000 * 1000 * 10 );
275 cactime
->days
= sec
/ ( 60 * 60 * 24 );
277 ( sec
- ( cactime
->days
* 60 * 60 * 24 ) ) / ( 60 * 60 );
279 ( sec
- ( cactime
->days
* 60 * 60 * 24 ) -
280 ( cactime
->hours
* 60 * 60 ) ) / 60;
282 sec
- ( cactime
->days
* 60 * 60 * 24 ) -
283 ( cactime
->hours
* 60 * 60 ) - ( cactime
->minutes
* 60 );
286 void cac_GetAuthDataFn( const char *pServer
,
292 char *pPassword
, int maxLenPassword
)
294 char temp
[sizeof( fstring
)];
296 static char authUsername
[sizeof( fstring
)];
297 static char authWorkgroup
[sizeof( fstring
)];
298 static char authPassword
[sizeof( fstring
)];
299 static char authSet
= 0;
305 strncpy( pWorkgroup
, authWorkgroup
, maxLenWorkgroup
- 1 );
306 strncpy( pUsername
, authUsername
, maxLenUsername
- 1 );
307 strncpy( pPassword
, authPassword
, maxLenPassword
- 1 );
309 d_printf( "Domain: [%s] ", pWorkgroup
);
310 fgets( temp
, sizeof( fstring
), stdin
);
312 if ( temp
[strlen( temp
) - 1] == '\n' ) { /* A new line? */
313 temp
[strlen( temp
) - 1] = '\0';
317 if ( temp
[0] != '\0' ) {
318 strncpy( pWorkgroup
, temp
, maxLenWorkgroup
- 1 );
319 strncpy( authWorkgroup
, temp
, maxLenWorkgroup
- 1 );
322 d_printf( "Username: [%s] ", pUsername
);
323 fgets( temp
, sizeof( fstring
), stdin
);
325 if ( temp
[strlen( temp
) - 1] == '\n' ) { /* A new line? */
326 temp
[strlen( temp
) - 1] = '\0';
329 if ( temp
[0] != '\0' ) {
330 strncpy( pUsername
, temp
, maxLenUsername
- 1 );
331 strncpy( authUsername
, pUsername
,
332 maxLenUsername
- 1 );
335 pass
= getpass( "Password: " );
337 fstrcpy( temp
, pass
);
338 if ( temp
[strlen( temp
) - 1] == '\n' ) { /* A new line? */
339 temp
[strlen( temp
) - 1] = '\0';
341 if ( temp
[0] != '\0' ) {
342 strncpy( pPassword
, temp
, maxLenPassword
- 1 );
343 strncpy( authPassword
, pPassword
,
344 maxLenPassword
- 1 );