"Fossies" - the Fresh Open Source Software Archive

Member "mod_ntlm2-0.1/smbval/rfcnb-util.inc.c" (21 Feb 2003, 7847 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: rfcnb-util.inc.c,v 1.2 2003/02/21 01:55:14 casz Exp $ */
    2 
    3 /* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation
    4  * 
    5  * Version 1.0 RFCNB Utility Routines ...
    6  * 
    7  * Copyright (C) Richard Sharpe 1996
    8  * 
    9  */
   10 
   11 /* 
   12  * This program is free software; you can redistribute it and/or modify it 
   13  * under the terms of the GNU General Public License as published by the
   14  * Free Software Foundation; either version 2 of the License, or (at your
   15  * option) any later version.  This program is distributed in the hope
   16  * that it will be useful, but WITHOUT ANY WARRANTY; without even the
   17  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
   18  * PURPOSE.  See the GNU General Public License for more details.  You
   19  * should have received a copy of the GNU General Public License along
   20  * with this program; if not, write to the Free Software Foundation, Inc., 
   21  * 675 Mass Ave, Cambridge, MA 02139, USA. */
   22 
   23 #include <string.h>
   24 #include <malloc.h>
   25 
   26 #include "std-includes.h"
   27 #include "rfcnb-priv.h"
   28 #include "rfcnb-util.h"
   29 #include "rfcnb-io.h"
   30 
   31 /* Convert name and pad to 16 chars as needed.  Name 1 is a C string
   32  * with null termination, name 2 may not be.  If SysName is true, then
   33  * put a <00> on end, else space> */
   34 static void 
   35 RFCNB_CvtPad_Name(char *name1, char *name2)
   36 {
   37     char c, c1, c2;
   38     int i, len;
   39 
   40     len = strlen(name1);
   41     for (i = 0; i < 16; i++) {
   42         if (i >= len) {
   43             c1 = 'C';
   44             c2 = 'A';           /* CA is a space */
   45         } else {
   46             c = name1[i];
   47             c1 = (char) ((int) c / 16 + (int) 'A');
   48             c2 = (char) ((int) c % 16 + (int) 'A');
   49         }
   50         name2[i * 2] = c1;
   51         name2[i * 2 + 1] = c2;
   52     }
   53     name2[32] = 0;              /* Put in the nll ... */
   54 }
   55 
   56 /* Get a packet of size n */
   57 static struct RFCNB_Pkt *
   58 RFCNB_Alloc_Pkt(int n)
   59 {
   60     RFCNB_Pkt *pkt;
   61 
   62     if ((pkt = (struct RFCNB_Pkt *) malloc(
   63                             sizeof(struct RFCNB_Pkt))) == NULL) {
   64         RFCNB_errno = RFCNBE_NoSpace;
   65         RFCNB_saved_errno = errno;
   66         return NULL;
   67     }
   68     pkt->next = NULL;
   69     pkt->len = n;
   70 
   71     if (n == 0)
   72         return pkt;
   73 
   74     if ((pkt->data = (char *) malloc(n)) == NULL) {
   75         RFCNB_errno = RFCNBE_NoSpace;
   76         RFCNB_saved_errno = errno;
   77         free(pkt);
   78         return (NULL);
   79     }
   80     return pkt;
   81 }
   82 
   83 /* Free up a packet */
   84 static void 
   85 RFCNB_Free_Pkt(struct RFCNB_Pkt *pkt)
   86 {
   87     struct RFCNB_Pkt *pkt_next;
   88     char *data_ptr;
   89 
   90     while (pkt != NULL) {
   91         pkt_next = pkt->next;
   92         data_ptr = pkt->data;
   93         if (data_ptr != NULL)
   94             free(data_ptr);
   95         free(pkt);
   96         pkt = pkt_next;
   97     }
   98 }
   99 
  100 /* Resolve a name into an address */
  101 static int 
  102 RFCNB_Name_To_IP(char *host, struct in_addr *Dest_IP)
  103 {
  104     int addr;                   /* Assumes IP4, 32 bit network addresses */
  105     struct hostent *hp;
  106 
  107     /* Use inet_addr to try to convert the address */
  108     if ((addr = inet_addr(host)) == INADDR_NONE) { /* a good try :-) */
  109         /* Now try a name look up with gethostbyname */
  110         if ((hp = gethostbyname(host)) == NULL) { /* Not in DNS */
  111             /* Try NetBIOS name lookup, how the hell do we do that? */
  112             RFCNB_errno = RFCNBE_BadName;         /* Is this right? */
  113             RFCNB_saved_errno = errno;
  114             return (RFCNBE_Bad);
  115         } else {                /* We got a name */
  116             memcpy((void *) Dest_IP, (void *) hp->h_addr_list[0],
  117                    sizeof(struct in_addr));
  118         }
  119     } else {                    /* It was an IP address */
  120         memcpy((void *) Dest_IP, (void *) &addr, sizeof(struct in_addr));
  121     }
  122     return 0;
  123 }
  124 
  125 /* Disconnect the TCP connection to the server */
  126 static int 
  127 RFCNB_Close(int socket)
  128 {
  129     close(socket);
  130     /* If we want to do error recovery, here is where we put it */
  131     return 0;
  132 }
  133 
  134 /* Connect to the server specified in the IP address. Not sure how to
  135  * handle socket options etc.  */
  136 static int 
  137 RFCNB_IP_Connect(struct in_addr Dest_IP, int port)
  138 {
  139     struct sockaddr_in Socket;
  140     int fd;
  141 
  142     /* Create a socket */
  143     if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { /* Handle the error */
  144         RFCNB_errno = RFCNBE_BadSocket;
  145         RFCNB_saved_errno = errno;
  146         return (RFCNBE_Bad);
  147     }
  148     bzero((char *) &Socket, sizeof(Socket));
  149     memcpy((char *) &Socket.sin_addr, (char *) &Dest_IP, sizeof(Dest_IP));
  150 
  151     Socket.sin_port = htons(port);
  152     Socket.sin_family = PF_INET;
  153 
  154     /* Now connect to the destination */
  155     if (connect(fd, (struct sockaddr *) &Socket, sizeof(Socket)) < 0) {
  156         /* Error */
  157         close(fd);
  158         RFCNB_errno = RFCNBE_ConnectFailed;
  159         RFCNB_saved_errno = errno;
  160         return (RFCNBE_Bad);
  161     }
  162     return fd;
  163 }
  164 
  165 /* handle the details of establishing the RFCNB session with remote end */
  166 static int 
  167 RFCNB_Session_Req(struct RFCNB_Con *con,
  168                   char *Called_Name,
  169                   char *Calling_Name,
  170                   BOOL * redirect,
  171                   struct in_addr *Dest_IP,
  172                   int *port)
  173 {
  174     char *sess_pkt;
  175 
  176     /* Response packet should be no more than 9 bytes, make 16 jic */
  177     char resp[16];
  178     int len;
  179     struct RFCNB_Pkt *pkt, res_pkt;
  180 
  181     /* We build and send the session request, then read the response */
  182     pkt = RFCNB_Alloc_Pkt(RFCNB_Pkt_Sess_Len);
  183     if (pkt == NULL) {
  184         return RFCNBE_Bad; /* Leave the error that RFCNB_Alloc_Pkt gives) */
  185     }
  186     sess_pkt = pkt->data;       /* Get pointer to packet proper */
  187 
  188     sess_pkt[RFCNB_Pkt_Type_Offset] = RFCNB_SESSION_REQUEST;
  189     RFCNB_Put_Pkt_Len(sess_pkt, RFCNB_Pkt_Sess_Len - RFCNB_Pkt_Hdr_Len);
  190     sess_pkt[RFCNB_Pkt_N1Len_Offset] = 32;
  191     sess_pkt[RFCNB_Pkt_N2Len_Offset] = 32;
  192 
  193     RFCNB_CvtPad_Name(Called_Name, (sess_pkt + RFCNB_Pkt_Called_Offset));
  194     RFCNB_CvtPad_Name(Calling_Name, (sess_pkt + RFCNB_Pkt_Calling_Offset));
  195 
  196     /* Now send the packet */
  197 #ifdef RFCNB_DEBUG
  198     fprintf(stderr, "Sending packet: ");
  199 #endif
  200     if ((len = RFCNB_Put_Pkt(con, pkt, RFCNB_Pkt_Sess_Len)) < 0)
  201         return RFCNBE_Bad;      /* Should be able to write that lot ... */
  202 #ifdef RFCNB_DEBUG
  203     fprintf(stderr, "Getting packet.\n");
  204 #endif
  205 
  206     res_pkt.data = resp;
  207     res_pkt.len = sizeof(resp);
  208     res_pkt.next = NULL;
  209 
  210     if ((len = RFCNB_Get_Pkt(con, &res_pkt, sizeof(resp))) < 0)
  211         return RFCNBE_Bad;
  212 
  213     /* Now analyze the packet ... */
  214     switch (RFCNB_Pkt_Type(resp)) {
  215       case RFCNB_SESSION_REJ:   /* Didnt like us ... too bad */
  216           /* Why did we get rejected ? */
  217           switch (CVAL(resp, RFCNB_Pkt_Error_Offset)) {
  218             case 0x80:
  219                 RFCNB_errno = RFCNBE_CallRejNLOCN;
  220                 break;
  221             case 0x81:
  222                 RFCNB_errno = RFCNBE_CallRejNLFCN;
  223                 break;
  224             case 0x82:
  225                 RFCNB_errno = RFCNBE_CallRejCNNP;
  226                 break;
  227             case 0x83:
  228                 RFCNB_errno = RFCNBE_CallRejInfRes;
  229                 break;
  230             case 0x8F:
  231                 RFCNB_errno = RFCNBE_CallRejUnSpec;
  232                 break;
  233             default:
  234                 RFCNB_errno = RFCNBE_ProtErr;
  235                 break;
  236           }
  237           return (RFCNBE_Bad);
  238           break;
  239 
  240       case RFCNB_SESSION_ACK:   /* Got what we wanted ...      */
  241           return (0);
  242           break;
  243 
  244       case RFCNB_SESSION_RETARGET:      /* Go elsewhere                */
  245           *redirect = TRUE;     /* Copy port and ip addr       */
  246           memcpy(Dest_IP, (resp + RFCNB_Pkt_IP_Offset),
  247                  sizeof(struct in_addr));
  248           *port = SVAL(resp, RFCNB_Pkt_Port_Offset);
  249           return 0;
  250           break;
  251       default:                  /* A protocol error */
  252           RFCNB_errno = RFCNBE_ProtErr;
  253           return (RFCNBE_Bad);
  254           break;
  255     }
  256 }