summaryrefslogtreecommitdiff
path: root/daemon/smbval/session.inc.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/smbval/session.inc.c')
-rw-r--r--daemon/smbval/session.inc.c221
1 files changed, 221 insertions, 0 deletions
diff --git a/daemon/smbval/session.inc.c b/daemon/smbval/session.inc.c
new file mode 100644
index 0000000..1ed4732
--- /dev/null
+++ b/daemon/smbval/session.inc.c
@@ -0,0 +1,221 @@
+/* mod_ntlm file: $Id: session.inc.c,v 1.2 2003/02/21 01:55:14 casz Exp $ */
+
+
+/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
+ *
+ * Version 1.0 Session Routines ...
+ *
+ * Copyright (C) Richard Sharpe 1996
+ *
+ */
+
+/*
+ * 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 <malloc.h>
+#include <string.h>
+
+static int RFCNB_errno = 0;
+static int RFCNB_saved_errno = 0;
+#define RFCNB_ERRNO
+
+#include "std-includes.h"
+#include <netinet/tcp.h>
+#include "rfcnb-priv.h"
+#include "rfcnb-util.h"
+
+/* Set up a session with a remote name. We are passed Called_Name as a
+ * string which we convert to a NetBIOS name, ie space terminated, up to
+ * 16 characters only if we need to. If Called_Address is not empty, then
+ * we use it to connect to the remote end, but put in Called_Name ...
+ * Called Address can be a DNS based name, or a TCP/IP address ... */
+static void *
+RFCNB_Call(char *Called_Name, char *Calling_Name, char *Called_Address,
+ int port)
+{
+ struct RFCNB_Con *con;
+ struct in_addr Dest_IP;
+ int Client;
+ BOOL redirect;
+ struct redirect_addr *redir_addr;
+ char *Service_Address;
+
+ /* Now, we really should look up the port in /etc/services ... */
+ if (port == 0)
+ port = RFCNB_Default_Port;
+
+ /* Create a connection structure first */
+ if ((con = (struct RFCNB_Con *) malloc(
+ sizeof(struct RFCNB_Con))) == NULL) {
+ /* Error in size */
+ RFCNB_errno = RFCNBE_NoSpace;
+ RFCNB_saved_errno = errno;
+ return NULL;
+ }
+ con->fd = -0; /* no descriptor yet */
+ con->rfc_errno = 0; /* no error yet */
+ con->timeout = 0; /* no timeout */
+ con->redirects = 0;
+ con->redirect_list = NULL; /* Fix bug still in version 0.50 */
+
+ /* Resolve that name into an IP address */
+ Service_Address = Called_Name;
+ if (strcmp(Called_Address, "") != 0)
+ Service_Address = Called_Address;
+ if ((errno = RFCNB_Name_To_IP(Service_Address, &Dest_IP)) < 0) {
+ /* Error */
+ /* No need to modify RFCNB_errno as it was done by
+ * RFCNB_Name_To_IP */
+ return NULL;
+ }
+ /* Now connect to the remote end */
+ redirect = TRUE; /* Fudge this one so we go once through */
+ while (redirect) { /* Connect and get session info etc */
+ redirect = FALSE; /* Assume all OK */
+ /* Build the redirect info. First one is first addr called */
+ /* And tack it onto the list of addresses we called */
+ if ((redir_addr = (struct redirect_addr *) malloc(
+ sizeof(struct redirect_addr))) == NULL) {
+ /* Could not get space */
+ RFCNB_errno = RFCNBE_NoSpace;
+ RFCNB_saved_errno = errno;
+ return (NULL);
+ }
+ memcpy((char *) &(redir_addr->ip_addr),
+ (char *) &Dest_IP, sizeof(Dest_IP));
+ redir_addr->port = port;
+ redir_addr->next = NULL;
+
+ if (con->redirect_list == NULL) { /* Stick on head */
+ con->redirect_list = con->last_addr = redir_addr;
+ } else {
+ con->last_addr->next = redir_addr;
+ con->last_addr = redir_addr;
+ }
+
+ /* Now, make that connection */
+ if ((Client = RFCNB_IP_Connect(Dest_IP, port)) < 0) { /* Error */
+ /* No need to modify RFCNB_errno as it was done by
+ * RFCNB_IP_Connect */
+ return NULL;
+ }
+ con->fd = Client;
+
+ /* Now send and handle the RFCNB session request */
+ /* If we get a redirect, we will comeback with redirect true and
+ * a new IP address in DEST_IP */
+ if ((errno = RFCNB_Session_Req(con,
+ Called_Name,
+ Calling_Name,
+ &redirect, &Dest_IP, &port)) < 0) {
+ /* No need to modify RFCNB_errno as it was done by
+ * RFCNB_Session.. */
+ return NULL;
+ }
+ if (redirect) {
+ /* We have to close the connection, and then try again */
+ (con->redirects)++;
+ RFCNB_Close(con->fd); /* Close it */
+ }
+ }
+ return con;
+}
+
+/* We send a packet to the other end ... for the moment, we treat the
+ * data as a series of pointers to blocks of data ... we should check the
+ * length ... */
+static int
+RFCNB_Send(struct RFCNB_Con *Con_Handle, struct RFCNB_Pkt *udata, int Length)
+{
+ struct RFCNB_Pkt *pkt;
+ char *hdr;
+ int len;
+
+ /* Plug in the header and send the data */
+ pkt = RFCNB_Alloc_Pkt(RFCNB_Pkt_Hdr_Len);
+ if (pkt == NULL) {
+ RFCNB_errno = RFCNBE_NoSpace;
+ RFCNB_saved_errno = errno;
+ return (RFCNBE_Bad);
+ }
+ pkt->next = udata; /* The user data we want to send */
+ hdr = pkt->data;
+
+ /* Following crap is for portability across multiple UNIX machines */
+ *(hdr + RFCNB_Pkt_Type_Offset) = RFCNB_SESSION_MESSAGE;
+ RFCNB_Put_Pkt_Len(hdr, Length);
+
+#ifdef RFCNB_DEBUG
+ fprintf(stderr, "Sending packet: ");
+#endif
+
+ if ((len = RFCNB_Put_Pkt(Con_Handle, pkt,
+ Length + RFCNB_Pkt_Hdr_Len)) < 0) {
+ /* No need to change RFCNB_errno as it was done by put_pkt ... */
+ return RFCNBE_Bad; /* Should be able to write that lot ... */
+ }
+ /* Now we have sent that lot, let's get rid of the RFCNB Header
+ * and return */
+ pkt->next = NULL;
+
+ RFCNB_Free_Pkt(pkt);
+ return len;
+}
+
+/* We pick up a message from the internet ... We have to worry about
+ * non-message packets ... */
+static int
+RFCNB_Recv(void *con_Handle, struct RFCNB_Pkt *Data, int Length)
+{
+ struct RFCNB_Pkt *pkt;
+ int ret_len;
+
+ if (con_Handle == NULL) {
+ RFCNB_errno = RFCNBE_BadHandle;
+ RFCNB_saved_errno = errno;
+ return (RFCNBE_Bad);
+ }
+ /* Now get a packet from below. We allocate a header first */
+ /* Plug in the header and send the data */
+ pkt = RFCNB_Alloc_Pkt(RFCNB_Pkt_Hdr_Len);
+
+ if (pkt == NULL) {
+ RFCNB_errno = RFCNBE_NoSpace;
+ RFCNB_saved_errno = errno;
+ return (RFCNBE_Bad);
+ }
+ pkt->next = Data; /* Plug in the data portion */
+
+ if ((ret_len = RFCNB_Get_Pkt(con_Handle, pkt,
+ Length + RFCNB_Pkt_Hdr_Len)) < 0) {
+#ifdef RFCNB_DEBUG
+ fprintf(stderr, "Bad packet return in RFCNB_Recv... \n");
+#endif
+ return RFCNBE_Bad;
+ }
+ /* We should check that we go a message and not a keep alive */
+ pkt->next = NULL;
+ RFCNB_Free_Pkt(pkt);
+ return ret_len;
+}
+
+/* We just disconnect from the other end, as there is nothing in the
+ * RFCNB protocol that specifies any exchange as far as I can see*/
+static int
+RFCNB_Hangup(struct RFCNB_Con *con_Handle)
+{
+ if (con_Handle != NULL) {
+ RFCNB_Close(con_Handle->fd); /* Could this fail? */
+ free(con_Handle);
+ }
+ return 0;
+}