summaryrefslogtreecommitdiff
path: root/source3/libmsrpc/libmsrpc.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libmsrpc/libmsrpc.c')
-rw-r--r--source3/libmsrpc/libmsrpc.c352
1 files changed, 352 insertions, 0 deletions
diff --git a/source3/libmsrpc/libmsrpc.c b/source3/libmsrpc/libmsrpc.c
new file mode 100644
index 0000000000..05f2dfe627
--- /dev/null
+++ b/source3/libmsrpc/libmsrpc.c
@@ -0,0 +1,352 @@
+/*
+ * 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"
+
+/*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) {
+ SMBCSRV *srv = NULL;
+ uint32 i = 0;
+
+ if(!hnd)
+ return;
+
+ /*see if there are any sessions*/
+ while(i <= PI_MAX_PIPES && hnd->_internal.pipes[i] == False)
+ i++;
+
+ if(i < PI_MAX_PIPES) {
+ /*then one or more sessions are open*/
+ srv = cac_GetServer(hnd);
+
+ if(srv)
+ cli_nt_session_close(&(srv->cli));
+ }
+
+ /*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.high==0 && nttime.low==0)
+ return;
+
+ if (nttime.high==0x80000000 && nttime.low==0)
+ return;
+
+ high = 65536;
+ high = high/10000;
+ high = high*65536;
+ high = high/1000;
+ high = high * (~nttime.high);
+
+ low = ~nttime.low;
+ 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;
+ }
+}
+