Initial import
[samba] / source / libmsrpc / libmsrpc.c
diff --git a/source/libmsrpc/libmsrpc.c b/source/libmsrpc/libmsrpc.c
new file mode 100644 (file)
index 0000000..036798b
--- /dev/null
@@ -0,0 +1,346 @@
+/* 
+ *  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;
+
+   if(!hnd)
+      return;
+
+
+   if(srv) {
+      /*close all pipe sessions*/
+      cli_nt_pipes_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;
+    }
+}
+