r25598: Add missing become_root/unbecome_root around calls of add_aliases.
[sfrench/samba-autobuild/.git] / source3 / libmsrpc / libmsrpc.c
1
2 /* 
3  *  Unix SMB/CIFS implementation.
4  *  MS-RPC client library implementation
5  *  Copyright (C) Chris Nicholls              2005.
6  *  
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.
11  *  
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.
16  *  
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/>.
19  */
20
21 #include "libmsrpc.h"
22 #include "libmsrpc_internal.h"
23 #include "libsmbclient.h"
24 #include "libsmb_internal.h"
25
26 int cac_InitHandleData( CacServerHandle * hnd );
27
28 /*this function is based on code found in smbc_init_context() (libsmb/libsmbclient.c)*/
29 void cac_Init( int debug )
30 {
31         if ( debug < 0 || debug > 99 )
32                 debug = 0;
33
34         DEBUGLEVEL = debug;
35
36         setup_logging( "libmsrpc", True );
37 }
38
39 int cac_InitHandleMem( CacServerHandle * hnd )
40 {
41         hnd->username = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
42
43         if ( !hnd->username )
44                 return CAC_FAILURE;
45
46         hnd->username[0] = '\0';
47
48         hnd->domain = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
49         if ( !hnd->domain )
50                 return CAC_FAILURE;
51
52         hnd->domain[0] = '\0';
53
54         hnd->netbios_name = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
55         if ( !hnd->netbios_name )
56                 return CAC_FAILURE;
57
58         hnd->netbios_name[0] = '\0';
59
60         hnd->password = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
61         if ( !hnd->password )
62                 return CAC_FAILURE;
63
64         hnd->password[0] = '\0';
65
66         hnd->server = SMB_MALLOC_ARRAY( char, sizeof( fstring ) );
67         if ( !hnd->server )
68                 return CAC_FAILURE;
69
70         hnd->server[0] = '\0';
71
72         return CAC_SUCCESS;
73 }
74
75 CacServerHandle *cac_NewServerHandle( BOOL allocate_fields )
76 {
77         CacServerHandle *hnd;
78
79         hnd = SMB_MALLOC_P( CacServerHandle );
80
81         if ( !hnd ) {
82                 errno = ENOMEM;
83                 return NULL;
84         }
85
86         ZERO_STRUCTP( hnd );
87
88         if ( allocate_fields == True ) {
89                 if ( !cac_InitHandleMem( hnd ) ) {
90                         SAFE_FREE( hnd );
91                         return NULL;
92                 }
93         }
94
95         hnd->_internal.ctx = smbc_new_context(  );
96         if ( !hnd->_internal.ctx ) {
97                 cac_FreeHandle( hnd );
98                 return NULL;
99         }
100
101         hnd->_internal.ctx->callbacks.auth_fn = cac_GetAuthDataFn;
102
103         /*add defaults */
104         hnd->debug = 0;
105
106         /*start at the highest and it will fall down after trying the functions */
107         hnd->_internal.srv_level = SRV_WIN_2K3;
108
109         hnd->_internal.user_supplied_ctx = False;
110
111         return hnd;
112 }
113
114 int cac_InitHandleData( CacServerHandle * hnd )
115 {
116         /*store any automatically initialized values */
117         if ( !hnd->netbios_name ) {
118                 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,
122                          sizeof( fstring ) );
123         }
124
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,
129                          sizeof( fstring ) );
130         }
131
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,
136                          sizeof( fstring ) );
137         }
138
139         return CAC_SUCCESS;
140 }
141
142 void cac_SetAuthDataFn( CacServerHandle * hnd, smbc_get_auth_data_fn auth_fn )
143 {
144         hnd->_internal.ctx->callbacks.auth_fn = auth_fn;
145 }
146
147 void cac_SetSmbcContext( CacServerHandle * hnd, SMBCCTX * ctx )
148 {
149
150         SAFE_FREE( hnd->_internal.ctx );
151
152         hnd->_internal.user_supplied_ctx = True;
153
154         hnd->_internal.ctx = ctx;
155
156    /*_try_ to avoid any problems that might occur if cac_Connect() isn't called*/
157         /*cac_InitHandleData(hnd); */
158 }
159
160 /*used internally*/
161 SMBCSRV *cac_GetServer( CacServerHandle * hnd )
162 {
163         SMBCSRV *srv;
164
165         if ( !hnd || !hnd->_internal.ctx ) {
166                 return NULL;
167         }
168
169         srv = smbc_attr_server( hnd->_internal.ctx, hnd->server, "IPC$",
170                                 hnd->domain, hnd->username, hnd->password,
171                                 NULL );
172         if ( !srv ) {
173                 hnd->status = NT_STATUS_UNSUCCESSFUL;
174                 DEBUG( 1,
175                        ( "cac_GetServer: Could not find server connection.\n" ) );
176         }
177
178         return srv;
179 }
180
181
182 int cac_Connect( CacServerHandle * hnd, const char *srv )
183 {
184         if ( !hnd ) {
185                 return CAC_FAILURE;
186         }
187
188         /*these values should be initialized by the user */
189         if ( !hnd->server && !srv ) {
190                 return CAC_FAILURE;
191         }
192
193
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 );
198         }
199
200
201         /*first see if the context has already been setup */
202         if ( !( hnd->_internal.ctx->internal->_initialized ) ) {
203                 hnd->_internal.ctx->debug = hnd->debug;
204
205                 /*initialize the context */
206                 if ( !smbc_init_context( hnd->_internal.ctx ) ) {
207                         return CAC_FAILURE;
208                 }
209         }
210
211         /*copy any uninitialized values out of the smbc context into the handle */
212         if ( !cac_InitHandleData( hnd ) ) {
213                 return CAC_FAILURE;
214         }
215
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 ) );
219
220         if ( !cac_GetServer( hnd ) ) {
221                 return CAC_FAILURE;
222         }
223
224         return CAC_SUCCESS;
225
226 }
227
228
229 void cac_FreeHandle( CacServerHandle * hnd )
230 {
231         if ( !hnd )
232                 return;
233
234         /*only free the context if we created it */
235         if ( !hnd->_internal.user_supplied_ctx ) {
236                 smbc_free_context( hnd->_internal.ctx, True );
237         }
238
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 );
244         SAFE_FREE( hnd );
245
246 }
247
248 void cac_InitCacTime( CacTime * cactime, NTTIME nttime )
249 {
250         float high, low;
251         uint32 sec;
252
253         if ( !cactime )
254                 return;
255
256         ZERO_STRUCTP( cactime );
257
258         /*this code is taken from display_time() found in rpcclient/cmd_samr.c */
259         if ( nttime == 0 )
260                 return;
261
262         if ( nttime == 0x80000000000000LL )
263                 return;
264
265         high = 65536;
266         high = high / 10000;
267         high = high * 65536;
268         high = high / 1000;
269         high = high * ( ~( nttime >> 32 ) );
270
271         low = ~( nttime & 0xFFFFFFFF );
272         low = low / ( 1000 * 1000 * 10 );
273
274         sec = high + low;
275
276         cactime->days = sec / ( 60 * 60 * 24 );
277         cactime->hours =
278                 ( sec - ( cactime->days * 60 * 60 * 24 ) ) / ( 60 * 60 );
279         cactime->minutes =
280                 ( sec - ( cactime->days * 60 * 60 * 24 ) -
281                   ( cactime->hours * 60 * 60 ) ) / 60;
282         cactime->seconds =
283                 sec - ( cactime->days * 60 * 60 * 24 ) -
284                 ( cactime->hours * 60 * 60 ) - ( cactime->minutes * 60 );
285 }
286
287 void cac_GetAuthDataFn( const char *pServer,
288                         const char *pShare,
289                         char *pWorkgroup,
290                         int maxLenWorkgroup,
291                         char *pUsername,
292                         int maxLenUsername,
293                         char *pPassword, int maxLenPassword )
294 {
295         char temp[sizeof( fstring )];
296
297         static char authUsername[sizeof( fstring )];
298         static char authWorkgroup[sizeof( fstring )];
299         static char authPassword[sizeof( fstring )];
300         static char authSet = 0;
301
302         char *pass = NULL;
303
304
305         if ( authSet ) {
306                 strncpy( pWorkgroup, authWorkgroup, maxLenWorkgroup - 1 );
307                 strncpy( pUsername, authUsername, maxLenUsername - 1 );
308                 strncpy( pPassword, authPassword, maxLenPassword - 1 );
309         } else {
310                 d_printf( "Domain: [%s] ", pWorkgroup );
311                 fgets( temp, sizeof( fstring ), stdin );
312
313                 if ( temp[strlen( temp ) - 1] == '\n' ) {       /* A new line? */
314                         temp[strlen( temp ) - 1] = '\0';
315                 }
316
317
318                 if ( temp[0] != '\0' ) {
319                         strncpy( pWorkgroup, temp, maxLenWorkgroup - 1 );
320                         strncpy( authWorkgroup, temp, maxLenWorkgroup - 1 );
321                 }
322
323                 d_printf( "Username: [%s] ", pUsername );
324                 fgets( temp, sizeof( fstring ), stdin );
325
326                 if ( temp[strlen( temp ) - 1] == '\n' ) {       /* A new line? */
327                         temp[strlen( temp ) - 1] = '\0';
328                 }
329
330                 if ( temp[0] != '\0' ) {
331                         strncpy( pUsername, temp, maxLenUsername - 1 );
332                         strncpy( authUsername, pUsername,
333                                  maxLenUsername - 1 );
334                 }
335
336                 pass = getpass( "Password: " );
337                 if ( pass )
338                         fstrcpy( temp, pass );
339                 if ( temp[strlen( temp ) - 1] == '\n' ) {       /* A new line? */
340                         temp[strlen( temp ) - 1] = '\0';
341                 }
342                 if ( temp[0] != '\0' ) {
343                         strncpy( pPassword, temp, maxLenPassword - 1 );
344                         strncpy( authPassword, pPassword,
345                                  maxLenPassword - 1 );
346                 }
347                 authSet = 1;
348         }
349 }