"Fossies" - the Fresh Open Source Software Archive

Member "mod_ntlm2-0.1/smbval/smblib-util.inc.c" (21 Feb 2003, 9551 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: smblib-util.inc.c,v 1.2 2003/02/21 01:55:14 casz Exp $ */
    2 
    3 /* UNIX SMBlib NetBIOS implementation
    4  * 
    5  * Version 1.0 SMBlib 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 "smblib-priv.h"
   24 #include <malloc.h>
   25 
   26 #include "rfcnb.h"
   27 
   28 /* Figure out what protocol was accepted, given the list of dialect
   29  * strings.  We offered, and the index back from the server. We allow
   30  * for a user supplied list, and assume that it is a subset of our
   31  * list */
   32 static int 
   33 SMB_Figure_Protocol(char *dialects[], int prot_index)
   34 {
   35     int i;
   36 
   37     if (dialects == SMB_Prots) { /* The jobs is easy, just index
   38                                   * into table */
   39         return SMB_Types[prot_index];
   40     } else {                    /* Search through SMB_Prots looking
   41                                  * for a match */
   42         for (i = 0; SMB_Prots[i] != NULL; i++) {
   43             if (strcmp(dialects[prot_index], SMB_Prots[i]) == 0) {
   44                 /* A match */
   45                 return SMB_Types[i];
   46             }
   47         }
   48 
   49         /* If we got here, then we are in trouble, because the
   50          * protocol was not one we understand ... */
   51         return SMB_P_Unknown;
   52     }
   53 }
   54 
   55 /* Negotiate the protocol we will use from the list passed in Prots we
   56  * return the index of the accepted protocol in NegProt, -1 *indicates
   57  * none acceptible, and our return value is 0 if ok, <0 if problems */
   58 static int 
   59 SMB_Negotiate(SMB_Handle_Type Con_Handle, char *Prots[])
   60 {
   61     struct RFCNB_Pkt *pkt;
   62     int prots_len, i, pkt_len, prot, alloc_len;
   63     char *p;
   64 
   65     /* Figure out how long the prot list will be and allocate space
   66      * for it */
   67     prots_len = 0;
   68 
   69     for (i = 0; Prots[i] != NULL; i++) {
   70         prots_len = prots_len + strlen(Prots[i]) + 2;   /* Account for
   71                                                          * null etc */
   72     }
   73 
   74     /* The -1 accounts for the one byte smb_buf we have because some
   75      * systems don't like char msg_buf[] */
   76     pkt_len = SMB_negp_len + prots_len;
   77 
   78     /* Make sure that the pkt len is long enough for the max
   79      * response...  Which is a problem, because the encryption key len
   80      * eec may be long */
   81     if (pkt_len < (SMB_hdr_wct_offset + (19 * 2) + 40))
   82         alloc_len = SMB_hdr_wct_offset + (19 * 2) + 40;
   83     else
   84         alloc_len = pkt_len;
   85 
   86     pkt = (struct RFCNB_Pkt *) RFCNB_Alloc_Pkt(alloc_len);
   87     if (pkt == NULL) {
   88         SMBlib_errno = SMBlibE_NoSpace;
   89         return (SMBlibE_BAD);
   90     }
   91     /* Now plug in the bits we need */
   92     bzero(SMB_Hdr(pkt), SMB_negp_len);
   93     SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */
   94     *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBnegprot;
   95     SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle->pid);
   96     SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
   97     SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle->mid);
   98     SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle->uid);
   99     *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0;
  100 
  101     SSVAL(SMB_Hdr(pkt), SMB_negp_bcc_offset, prots_len);
  102 
  103     /* Now copy the prot strings in with the right stuff */
  104     p = (char *) (SMB_Hdr(pkt) + SMB_negp_buf_offset);
  105 
  106     for (i = 0; Prots[i] != NULL; i++) {
  107         *p = SMBdialectID;
  108         strcpy(p + 1, Prots[i]);
  109         p = p + strlen(Prots[i]) + 2;   /* Adjust len of p for null
  110                                          * plus dialectID */
  111     }
  112 
  113     /* Now send the packet and sit back ... */
  114     if (RFCNB_Send(Con_Handle->Trans_Connect, pkt, pkt_len) < 0) {
  115 #ifdef SMB_DEBUG
  116         fprintf(stderr, "Error sending negotiate protocol\n");
  117 #endif
  118         RFCNB_Free_Pkt(pkt);
  119         SMBlib_errno = -SMBlibE_SendFailed;     /* Failed, check lower
  120                                                  * layer errno */
  121         return (SMBlibE_BAD);
  122     }
  123     /* Now get the response ... */
  124     if (RFCNB_Recv(Con_Handle->Trans_Connect, pkt, alloc_len) < 0) {
  125 #ifdef SMB_DEBUG
  126         fprintf(stderr, "Error receiving response to negotiate\n");
  127 #endif
  128         RFCNB_Free_Pkt(pkt);
  129         SMBlib_errno = -SMBlibE_RecvFailed;     /* Failed, check lower
  130                                                  * layer errno */
  131         return (SMBlibE_BAD);
  132     }
  133     if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) {
  134         /* Process error */
  135 #ifdef SMB_DEBUG
  136         fprintf(stderr, "SMB_Negotiate failed with errorclass = %i, Error Code = %i\n",
  137                 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
  138                 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
  139 #endif
  140         SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
  141         RFCNB_Free_Pkt(pkt);
  142         SMBlib_errno = SMBlibE_Remote;
  143         return SMBlibE_BAD;
  144     }
  145     if (SVAL(SMB_Hdr(pkt), SMB_negrCP_idx_offset) == 0xFFFF) {
  146 #ifdef SMB_DEBUG
  147         fprintf(stderr, "None of our protocols was accepted ... ");
  148 #endif
  149         RFCNB_Free_Pkt(pkt);
  150         SMBlib_errno = SMBlibE_NegNoProt;
  151         return (SMBlibE_BAD);
  152     }
  153     /* Now, unpack the info from the response, if any and evaluate the
  154      * proto selected. We must make sure it is one we like... */
  155     Con_Handle->prot_IDX = prot = SVAL(SMB_Hdr(pkt), SMB_negrCP_idx_offset);
  156     Con_Handle->protocol = SMB_Figure_Protocol(Prots, prot);
  157 
  158     if (Con_Handle->protocol == SMB_P_Unknown) {        /* No good ... */
  159         RFCNB_Free_Pkt(pkt);
  160         SMBlib_errno = SMBlibE_ProtUnknown;
  161         return SMBlibE_BAD;
  162     }
  163     switch (CVAL(SMB_Hdr(pkt), SMB_hdr_wct_offset)) {
  164       case 0x01:                /* No more info ... */
  165           break;
  166 
  167       case 13:                  /* Up to and including LanMan 2.1 */
  168           Con_Handle->Security = SVAL(SMB_Hdr(pkt), SMB_negrLM_sec_offset);
  169           Con_Handle->encrypt_passwords
  170               = ((Con_Handle->Security & SMB_sec_encrypt_mask) != 0x00);
  171           Con_Handle->Security = Con_Handle->Security & SMB_sec_user_mask;
  172 
  173           Con_Handle->max_xmit = SVAL(SMB_Hdr(pkt), SMB_negrLM_mbs_offset);
  174           Con_Handle->MaxMPX = SVAL(SMB_Hdr(pkt), SMB_negrLM_mmc_offset);
  175           Con_Handle->MaxVC = SVAL(SMB_Hdr(pkt), SMB_negrLM_mnv_offset);
  176           Con_Handle->Raw_Support = SVAL(SMB_Hdr(pkt), SMB_negrLM_rm_offset);
  177           Con_Handle->SessionKey = IVAL(SMB_Hdr(pkt), SMB_negrLM_sk_offset);
  178           Con_Handle->SvrTZ = SVAL(SMB_Hdr(pkt), SMB_negrLM_stz_offset);
  179           Con_Handle->Encrypt_Key_Len
  180               = SVAL(SMB_Hdr(pkt), SMB_negrLM_ekl_offset);
  181 
  182           p = (SMB_Hdr(pkt) + SMB_negrLM_buf_offset);
  183 #ifdef SMB_DEBUG
  184           fprintf(stderr, "%s",
  185                   (char *) (SMB_Hdr(pkt) + SMB_negrLM_buf_offset));
  186 #endif
  187           memcpy(Con_Handle->Encrypt_Key, p, 8);
  188 
  189           p = (SMB_Hdr(pkt) + SMB_negrLM_buf_offset
  190                             + Con_Handle->Encrypt_Key_Len);
  191 
  192           strncpy(p, Con_Handle->Svr_PDom, sizeof(Con_Handle->Svr_PDom) - 1);
  193           break;
  194 
  195       case 17:                  /* NT LM 0.12 and LN LM 1.0 */
  196           Con_Handle->Security = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_sec_offset);
  197           Con_Handle->encrypt_passwords
  198               = ((Con_Handle->Security & SMB_sec_encrypt_mask) != 0x00);
  199           Con_Handle->Security = Con_Handle->Security & SMB_sec_user_mask;
  200 
  201           Con_Handle->max_xmit = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_mbs_offset);
  202           Con_Handle->MaxMPX = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_mmc_offset);
  203           Con_Handle->MaxVC = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_mnv_offset);
  204           Con_Handle->MaxRaw = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_mrs_offset);
  205           Con_Handle->SessionKey = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_sk_offset);
  206           Con_Handle->SvrTZ = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_stz_offset);
  207           Con_Handle->Encrypt_Key_Len = CVAL(SMB_Hdr(pkt),
  208                                              SMB_negrNTLM_ekl_offset);
  209 
  210           p = (SMB_Hdr(pkt) + SMB_negrNTLM_buf_offset);
  211           memcpy(Con_Handle->Encrypt_Key, p, 8);
  212           p = (SMB_Hdr(pkt) + SMB_negrNTLM_buf_offset
  213                             + Con_Handle->Encrypt_Key_Len);
  214 
  215           strncpy(p, Con_Handle->Svr_PDom, sizeof(Con_Handle->Svr_PDom) - 1);
  216           break;
  217 
  218       default:
  219 #ifdef SMB_DEBUG
  220           fprintf(stderr, "Unknown NegProt response format ... Ignored\n");
  221           fprintf(stderr, "  wct = %i\n", CVAL(SMB_Hdr(pkt), SMB_hdr_wct_offset));
  222 #endif
  223           break;
  224     }
  225 
  226 #ifdef SMB_DEBUG
  227     fprintf(stderr, "Protocol selected is: %i:%s\n", prot, Prots[prot]);
  228 #endif
  229 
  230     RFCNB_Free_Pkt(pkt);
  231     return 0;
  232 }
  233 
  234 /* Get our hostname */
  235 static void 
  236 SMB_Get_My_Name(char *name, int len)
  237 {
  238     if (gethostname(name, len) < 0) {   /* Error getting name */
  239         strncpy(name, "unknown", len);
  240 
  241         /* Should check the error */
  242 #ifdef SMB_DEBUG
  243         fprintf(stderr, "gethostname in SMB_Get_My_Name returned error:");
  244         perror("");
  245 #endif
  246     }
  247     /* only keep the portion up to the first "." */
  248 }