"Fossies" - the Fresh Open Source Software Archive

Member "mod_ntlm2-0.1/smbval/session.inc.c" (21 Feb 2003, 7722 Bytes) of package /linux/www/apache_httpd_modules/old/mod_ntlm2-0.1.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /* mod_ntlm file: $Id: session.inc.c,v 1.2 2003/02/21 01:55:14 casz Exp $ */
    2 
    3 
    4 /* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
    5  * 
    6  * Version 1.0 Session Routines ...
    7  * 
    8  * Copyright (C) Richard Sharpe 1996
    9  * 
   10  */
   11 
   12 /* 
   13  * This program is free software; you can redistribute it and/or modify it 
   14  * under the terms of the GNU General Public License as published by the
   15  * Free Software Foundation; either version 2 of the License, or (at your
   16  * option) any later version.  This program is distributed in the hope
   17  * that it will be useful, but WITHOUT ANY WARRANTY; without even the
   18  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
   19  * PURPOSE.  See the GNU General Public License for more details.  You
   20  * should have received a copy of the GNU General Public License along
   21  * with this program; if not, write to the Free Software Foundation, Inc., 
   22  * 675 Mass Ave, Cambridge, MA 02139, USA. */
   23 
   24 #include <malloc.h>
   25 #include <string.h>
   26 
   27 static int RFCNB_errno = 0;
   28 static int RFCNB_saved_errno = 0;
   29 #define RFCNB_ERRNO
   30 
   31 #include "std-includes.h"
   32 #include <netinet/tcp.h>
   33 #include "rfcnb-priv.h"
   34 #include "rfcnb-util.h"
   35 
   36 /* Set up a session with a remote name. We are passed Called_Name as a
   37  * string which we convert to a NetBIOS name, ie space terminated, up to
   38  * 16 characters only if we need to. If Called_Address is not empty, then
   39  * we use it to connect to the remote end, but put in Called_Name ...
   40  * Called  Address can be a DNS based name, or a TCP/IP address ... */
   41 static void *
   42 RFCNB_Call(char *Called_Name, char *Calling_Name, char *Called_Address,
   43            int port)
   44 {
   45     struct RFCNB_Con *con;
   46     struct in_addr Dest_IP;
   47     int Client;
   48     BOOL redirect;
   49     struct redirect_addr *redir_addr;
   50     char *Service_Address;
   51 
   52     /* Now, we really should look up the port in /etc/services ... */
   53     if (port == 0)
   54         port = RFCNB_Default_Port;
   55 
   56     /* Create a connection structure first */
   57     if ((con = (struct RFCNB_Con *) malloc(
   58                                     sizeof(struct RFCNB_Con))) == NULL) {
   59         /* Error in size */
   60         RFCNB_errno = RFCNBE_NoSpace;
   61         RFCNB_saved_errno = errno;
   62         return NULL;
   63     }
   64     con->fd = -0;               /* no descriptor yet */
   65     con->rfc_errno = 0;         /* no error yet */
   66     con->timeout = 0;           /* no timeout   */
   67     con->redirects = 0;
   68     con->redirect_list = NULL;  /* Fix bug still in version 0.50 */
   69 
   70     /* Resolve that name into an IP address */
   71     Service_Address = Called_Name;
   72     if (strcmp(Called_Address, "") != 0)
   73         Service_Address = Called_Address;
   74     if ((errno = RFCNB_Name_To_IP(Service_Address, &Dest_IP)) < 0) {
   75         /* Error */
   76         /* No need to modify RFCNB_errno as it was done by
   77          * RFCNB_Name_To_IP */
   78         return NULL;
   79     }
   80     /* Now connect to the remote end */
   81     redirect = TRUE;            /* Fudge this one so we go once through */
   82     while (redirect) {          /* Connect and get session info etc */
   83         redirect = FALSE;       /* Assume all OK */
   84         /* Build the redirect info. First one is first addr called */
   85         /* And tack it onto the list of addresses we called        */
   86         if ((redir_addr = (struct redirect_addr *) malloc(
   87                                     sizeof(struct redirect_addr))) == NULL) {
   88             /* Could not get space */
   89             RFCNB_errno = RFCNBE_NoSpace;
   90             RFCNB_saved_errno = errno;
   91             return (NULL);
   92         }
   93         memcpy((char *) &(redir_addr->ip_addr),
   94                (char *) &Dest_IP, sizeof(Dest_IP));
   95         redir_addr->port = port;
   96         redir_addr->next = NULL;
   97 
   98         if (con->redirect_list == NULL) {       /* Stick on head */
   99             con->redirect_list = con->last_addr = redir_addr;
  100         } else {
  101             con->last_addr->next = redir_addr;
  102             con->last_addr = redir_addr;
  103         }
  104 
  105         /* Now, make that connection */
  106         if ((Client = RFCNB_IP_Connect(Dest_IP, port)) < 0) {   /* Error */
  107             /* No need to modify RFCNB_errno as it was done by
  108              * RFCNB_IP_Connect */
  109             return NULL;
  110         }
  111         con->fd = Client;
  112 
  113         /* Now send and handle the RFCNB session request              */
  114         /* If we get a redirect, we will comeback with redirect true  and
  115          * a new IP address in DEST_IP                            */
  116         if ((errno = RFCNB_Session_Req(con,
  117                                        Called_Name,
  118                                        Calling_Name,
  119                                        &redirect, &Dest_IP, &port)) < 0) {
  120             /* No need to modify RFCNB_errno as it was done by
  121              * RFCNB_Session.. */
  122             return NULL;
  123         }
  124         if (redirect) {
  125             /* We have to close the connection, and then try again */
  126             (con->redirects)++;
  127             RFCNB_Close(con->fd);       /* Close it */
  128         }
  129     }
  130     return con;
  131 }
  132 
  133 /* We send a packet to the other end ... for the moment, we treat the 
  134  * data as a series of pointers to blocks of data ... we should check the
  135  * length ... */
  136 static int 
  137 RFCNB_Send(struct RFCNB_Con *Con_Handle, struct RFCNB_Pkt *udata, int Length)
  138 {
  139     struct RFCNB_Pkt *pkt;
  140     char *hdr;
  141     int len;
  142 
  143     /* Plug in the header and send the data */
  144     pkt = RFCNB_Alloc_Pkt(RFCNB_Pkt_Hdr_Len);
  145     if (pkt == NULL) {
  146         RFCNB_errno = RFCNBE_NoSpace;
  147         RFCNB_saved_errno = errno;
  148         return (RFCNBE_Bad);
  149     }
  150     pkt->next = udata;          /* The user data we want to send */
  151     hdr = pkt->data;
  152 
  153     /* Following crap is for portability across multiple UNIX machines */
  154     *(hdr + RFCNB_Pkt_Type_Offset) = RFCNB_SESSION_MESSAGE;
  155     RFCNB_Put_Pkt_Len(hdr, Length);
  156 
  157 #ifdef RFCNB_DEBUG
  158     fprintf(stderr, "Sending packet: ");
  159 #endif
  160 
  161     if ((len = RFCNB_Put_Pkt(Con_Handle, pkt,
  162                              Length + RFCNB_Pkt_Hdr_Len)) < 0) {
  163         /* No need to change RFCNB_errno as it was done by put_pkt ... */
  164         return RFCNBE_Bad;      /* Should be able to write that lot ... */
  165     }
  166     /* Now we have sent that lot, let's get rid of the RFCNB Header
  167      * and return */
  168     pkt->next = NULL;
  169 
  170     RFCNB_Free_Pkt(pkt);
  171     return len;
  172 }
  173 
  174 /* We pick up a message from the internet ... We have to worry about 
  175  * non-message packets ...                                           */
  176 static int 
  177 RFCNB_Recv(void *con_Handle, struct RFCNB_Pkt *Data, int Length)
  178 {
  179     struct RFCNB_Pkt *pkt;
  180     int ret_len;
  181 
  182     if (con_Handle == NULL) {
  183         RFCNB_errno = RFCNBE_BadHandle;
  184         RFCNB_saved_errno = errno;
  185         return (RFCNBE_Bad);
  186     }
  187     /* Now get a packet from below. We allocate a header first */
  188     /* Plug in the header and send the data */
  189     pkt = RFCNB_Alloc_Pkt(RFCNB_Pkt_Hdr_Len);
  190 
  191     if (pkt == NULL) {
  192         RFCNB_errno = RFCNBE_NoSpace;
  193         RFCNB_saved_errno = errno;
  194         return (RFCNBE_Bad);
  195     }
  196     pkt->next = Data;           /* Plug in the data portion */
  197 
  198     if ((ret_len = RFCNB_Get_Pkt(con_Handle, pkt,
  199                                  Length + RFCNB_Pkt_Hdr_Len)) < 0) {
  200 #ifdef RFCNB_DEBUG
  201         fprintf(stderr, "Bad packet return in RFCNB_Recv... \n");
  202 #endif
  203         return RFCNBE_Bad;
  204     }
  205     /* We should check that we go a message and not a keep alive */
  206     pkt->next = NULL;
  207     RFCNB_Free_Pkt(pkt);
  208     return ret_len;
  209 }
  210 
  211 /* We just disconnect from the other end, as there is nothing in the
  212  * RFCNB protocol that specifies any exchange as far as I can see*/
  213 static int 
  214 RFCNB_Hangup(struct RFCNB_Con *con_Handle)
  215 {
  216     if (con_Handle != NULL) {
  217         RFCNB_Close(con_Handle->fd);    /* Could this fail? */
  218         free(con_Handle);
  219     }
  220     return 0;
  221 }