"Fossies" - the Fresh Open Source Software Archive

Member "mod_ntlm2-0.1/smbval/smblib.inc.c" (21 Feb 2003, 12570 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.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 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 #include <stdio.h>
   23 #include <malloc.h>
   24 
   25 static int SMBlib_errno;
   26 static int SMBlib_SMB_Error;
   27 #define SMBLIB_ERRNO
   28 #define uchar unsigned char
   29 #include "smblib-priv.h"
   30 
   31 #include "rfcnb.h"
   32 
   33 #include <signal.h>
   34 
   35 static SMB_State_Types SMBlib_State;
   36 
   37 /* Initialize the SMBlib package     */
   38 static int 
   39 SMB_Init()
   40 {
   41     SMBlib_State = SMB_State_Started;
   42     signal(SIGPIPE, SIG_IGN);   /* Ignore these ... */
   43 
   44 /* If SMBLIB_Instrument is defines, turn on the instrumentation stuff */
   45 #ifdef SMBLIB_INSTRUMENT
   46     SMBlib_Instrument_Init();
   47 #endif
   48 
   49     return 0;
   50 }
   51 
   52 /* SMB_Connect_Server: Connect to a server, but don't negotiate protocol */
   53 /* or anything else ...                                                  */
   54 static SMB_Handle_Type 
   55 SMB_Connect_Server(SMB_Handle_Type Con_Handle,
   56                    char *server, char *NTdomain)
   57 {
   58     SMB_Handle_Type con;
   59     char called[80], calling[80], *address;
   60     int i;
   61 
   62     /* Get a connection structure if one does not exist */
   63     con = Con_Handle;
   64     if (Con_Handle == NULL) {
   65         if ((con = (struct SMB_Connect_Def *) malloc(
   66                                    sizeof(struct SMB_Connect_Def))) == NULL) {
   67             SMBlib_errno = SMBlibE_NoSpace;
   68             return NULL;
   69         }
   70     }
   71     /* Init some things ... */
   72 
   73     strcpy(con->service, "");
   74     strcpy(con->username, "");
   75     strcpy(con->password, "");
   76     strcpy(con->sock_options, "");
   77     strcpy(con->address, "");
   78     strcpy(con->desthost, server);
   79     strcpy(con->PDomain, NTdomain);
   80     strcpy(con->OSName, SMBLIB_DEFAULT_OSNAME);
   81     strcpy(con->LMType, SMBLIB_DEFAULT_LMTYPE);
   82     con->first_tree = con->last_tree = NULL;
   83 
   84     SMB_Get_My_Name(con->myname, sizeof(con->myname));
   85 
   86     con->port = 0;              /* No port selected */
   87 
   88     /* Get some things we need for the SMB Header */
   89     con->pid = getpid();
   90     con->mid = con->pid;        /* This will do for now ... */
   91     con->uid = 0;               /* Until we have done a logon, no uid ... */
   92     con->gid = getgid();
   93 
   94     /* Now connect to the remote end, but first upper case the name of
   95      * the service we are going to call, sine some servers want it in
   96      * uppercase */
   97     for (i = 0; i < strlen(server); i++)
   98         called[i] = toupper(server[i]);
   99 
  100     called[strlen(server)] = 0; /* Make it a string */
  101 
  102     for (i = 0; i < strlen(con->myname); i++)
  103         calling[i] = toupper(con->myname[i]);
  104 
  105     calling[strlen(con->myname)] = 0;   /* Make it a string */
  106 
  107     if (strcmp(con->address, "") == 0)
  108         address = con->desthost;
  109     else
  110         address = con->address;
  111 
  112     con->Trans_Connect = RFCNB_Call(called,
  113                                     calling,
  114                                     address,    /* Protocol specific */
  115                                     con->port);
  116 
  117     /* Did we get one? */
  118     if (con->Trans_Connect == NULL) {
  119         if (Con_Handle == NULL) {
  120             Con_Handle = NULL;
  121             free(con);
  122         }
  123         SMBlib_errno = -SMBlibE_CallFailed;
  124         return NULL;
  125     }
  126     return (con);
  127 }
  128 
  129 /* Logon to the server. That is, do a session setup if we can. We do
  130  * not do Unicode yet! */
  131 static int 
  132 SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName,
  133                  char *PassWord, int precrypted)
  134 {
  135     struct RFCNB_Pkt *pkt;
  136     int param_len, pkt_len, pass_len;
  137     char *p, pword[128];
  138 
  139     /* First we need a packet etc ... but we need to know what
  140      * protocol has been negotiated to figure out if we can do it and
  141      * what SMB format to use ... */
  142     if (Con_Handle->protocol < SMB_P_LanMan1) {
  143 #ifdef LOG
  144     flog("SMB_Logon_Server: bad protocol");
  145 #endif
  146         SMBlib_errno = SMBlibE_ProtLow;
  147         return (SMBlibE_BAD);
  148     }
  149     if (precrypted) {
  150         pass_len = 24;
  151         memcpy(pword, PassWord, 24);
  152     } else {
  153         strcpy(pword, PassWord);
  154         if (Con_Handle->encrypt_passwords) {
  155             pass_len = 24;
  156             SMBencrypt((uchar *) PassWord,
  157                        (uchar *) Con_Handle->Encrypt_Key, (uchar *) pword);
  158         } else
  159             pass_len = strlen(pword);
  160     }
  161 
  162     /* Now build the correct structure */
  163     if (Con_Handle->protocol < SMB_P_NT1) {
  164 #ifdef LOG
  165     flog("SMB_Logon_Server: type is LM (%d)", Con_Handle->protocol);
  166 #endif
  167         param_len = strlen(UserName) + 1 + pass_len + 1 +
  168             strlen(Con_Handle->PDomain) + 1 +
  169             strlen(Con_Handle->OSName) + 1;
  170 
  171         pkt_len = SMB_ssetpLM_len + param_len;
  172 
  173         pkt = (struct RFCNB_Pkt *) RFCNB_Alloc_Pkt(pkt_len);
  174 
  175         if (pkt == NULL) {
  176 #ifdef LOG
  177     flog("SMB_Logon_Server: pkt == NULL");
  178 #endif
  179             SMBlib_errno = SMBlibE_NoSpace;
  180             return (SMBlibE_BAD);       /* Should handle the error */
  181         }
  182         bzero(SMB_Hdr(pkt), SMB_ssetpLM_len);
  183         SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF);   /* Plunk
  184                                                                  * in IDF */
  185         *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX;
  186         SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle->pid);
  187         SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
  188         SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle->mid);
  189         SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle->uid);
  190         *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 10;
  191         *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF;    /* No extra
  192                                                          * command */
  193         SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0);
  194 
  195         SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mbs_offset, SMBLIB_MAX_XMIT);
  196         SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mmc_offset, 2);
  197         SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_vcn_offset, Con_Handle->pid);
  198         SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_snk_offset, 0);
  199         SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_pwl_offset, pass_len + 1);
  200         SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_res_offset, 0);
  201         SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_bcc_offset, param_len);
  202 
  203         /* Now copy the param strings in with the right stuff */
  204         p = (char *) (SMB_Hdr(pkt) + SMB_ssetpLM_buf_offset);
  205 
  206         /* Copy in password, then the rest. Password has a null at end */
  207         memcpy(p, pword, pass_len);
  208 
  209         p = p + pass_len + 1;
  210 
  211         strcpy(p, UserName);
  212         p = p + strlen(UserName);
  213         *p = 0;
  214 
  215         p = p + 1;
  216 
  217         strcpy(p, Con_Handle->PDomain);
  218         p = p + strlen(Con_Handle->PDomain);
  219         *p = 0;
  220         p = p + 1;
  221 
  222         strcpy(p, Con_Handle->OSName);
  223         p = p + strlen(Con_Handle->OSName);
  224         *p = 0;
  225     } else {
  226 #ifdef LOG
  227     flog("SMB_Logon_Server: type is NTLM (%d)", Con_Handle->protocol);
  228 #endif
  229         /* We don't admit to UNICODE support ... */
  230         param_len = strlen(UserName) + 1 + pass_len +
  231             strlen(Con_Handle->PDomain) + 1 +
  232             strlen(Con_Handle->OSName) + 1 +
  233             strlen(Con_Handle->LMType) + 1;
  234 
  235         pkt_len = SMB_ssetpNTLM_len + param_len;
  236 
  237         pkt = (struct RFCNB_Pkt *) RFCNB_Alloc_Pkt(pkt_len);
  238 
  239         if (pkt == NULL) {
  240 #ifdef LOG
  241     flog("SMB_Logon_Server: pkt == NULL, second check");
  242 #endif
  243             SMBlib_errno = SMBlibE_NoSpace;
  244             return (-1);        /* Should handle the error */
  245         }
  246         bzero(SMB_Hdr(pkt), SMB_ssetpNTLM_len);
  247         SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF);   /* Plunk
  248                                                                  * in IDF */
  249         *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX;
  250         SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle->pid);
  251         SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0);
  252         SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle->mid);
  253         SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle->uid);
  254         *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 13;
  255         *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF;    /* No extra
  256                                                          * command */
  257         SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0);
  258 
  259         SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mbs_offset, SMBLIB_MAX_XMIT);
  260         SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mmc_offset, 0);
  261         SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_vcn_offset, 0);
  262         SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_snk_offset, 0);
  263         SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cipl_offset, pass_len);
  264         SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cspl_offset, 0);
  265         SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_res_offset, 0);
  266         SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cap_offset, 0);
  267         SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_bcc_offset, param_len);
  268 
  269         /* Now copy the param strings in with the right stuff */
  270         p = (char *) (SMB_Hdr(pkt) + SMB_ssetpNTLM_buf_offset);
  271 
  272         /* Copy  in password, then the rest. Password has no null at end */
  273         memcpy(p, pword, pass_len);
  274 
  275         p = p + pass_len;
  276 
  277         strcpy(p, UserName);
  278         p = p + strlen(UserName);
  279         *p = 0;
  280 
  281         p = p + 1;
  282 
  283         strcpy(p, Con_Handle->PDomain);
  284         p = p + strlen(Con_Handle->PDomain);
  285         *p = 0;
  286         p = p + 1;
  287 
  288         strcpy(p, Con_Handle->OSName);
  289         p = p + strlen(Con_Handle->OSName);
  290         *p = 0;
  291         p = p + 1;
  292 
  293         strcpy(p, Con_Handle->LMType);
  294         p = p + strlen(Con_Handle->LMType);
  295         *p = 0;
  296     }
  297 
  298     /* Now send it and get a response */
  299     if (RFCNB_Send(Con_Handle->Trans_Connect, pkt, pkt_len) < 0) {
  300 #ifdef LOG
  301     flog("SMB_Logon_Server: Error sending SessSetupX request");
  302 #endif
  303 #ifdef SMB_DEBUG
  304         fprintf(stderr, "Error sending SessSetupX request\n");
  305 #endif
  306         RFCNB_Free_Pkt(pkt);
  307         SMBlib_errno = SMBlibE_SendFailed;
  308         return (SMBlibE_BAD);
  309     }
  310 
  311     /* Now get the response ... */
  312     if (RFCNB_Recv(Con_Handle->Trans_Connect, pkt, pkt_len) < 0) {
  313 #ifdef LOG
  314     flog("SMB_Logon_Server: Error receiving response to SessSetupAndX");
  315 #endif
  316 #ifdef SMB_DEBUG
  317         fprintf(stderr, "Error receiving response to SessSetupAndX\n");
  318 #endif
  319         RFCNB_Free_Pkt(pkt);
  320         SMBlib_errno = SMBlibE_RecvFailed;
  321         return (SMBlibE_BAD);
  322     }
  323     /* Check out the response type ... */
  324 
  325     if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) {
  326         /* Process error */
  327 #ifdef LOG
  328     flog("SMB_Logon_Server: SMB_SessSetupAndX failed; errorclass = %i, Error Code = %i\n",
  329          CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
  330          SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
  331 #endif
  332 #ifdef SMB_DEBUG
  333         fprintf(stderr,
  334                 "SMB_SessSetupAndX failed; errorclass = %i, Error Code = %i\n",
  335                 CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset),
  336                 SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset));
  337 #endif
  338         SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset);
  339         RFCNB_Free_Pkt(pkt);
  340         SMBlib_errno = SMBlibE_Remote;
  341         return (SMBlibE_BAD);
  342     }
  343 /** @@@ mdz: check for guest login { **/
  344     if (SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset) & 0x1) {
  345         /* do we allow guest login? NO! */
  346 #ifdef LOG
  347     flog("SMB_Logon_Server: no guest login");
  348 #endif
  349         return (SMBlibE_BAD);
  350     }
  351 /** @@@ mdz: } **/
  352 
  353 #ifdef SMB_DEBUG
  354     fprintf(stderr, "SessSetupAndX response. Action = %i\n",
  355             SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset));
  356 #endif
  357 
  358     /* Now pick up the UID for future reference ... */
  359     Con_Handle->uid = SVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset);
  360     RFCNB_Free_Pkt(pkt);
  361 
  362 #ifdef LOG
  363     flog("SMB_Logon_Server: login OK");
  364 #endif
  365     return 0;
  366 }
  367 
  368 /* Disconnect from the server, and disconnect all tree connects */
  369 static int 
  370 SMB_Discon(SMB_Handle_Type Con_Handle, BOOL KeepHandle)
  371 {
  372     /* We just disconnect the connection for now ... */
  373     RFCNB_Hangup(Con_Handle->Trans_Connect);
  374 
  375     if (!KeepHandle)
  376         free(Con_Handle);
  377 
  378     return 0;
  379 }