From: Amos Jeffries Date: Sat, 16 Oct 2010 23:19:46 +0000 (-0600) Subject: basic_msnt_auth helper and NTLM/SMBLIB/RFCNB library polish. X-Git-Tag: take1~183 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7c16470cc2d053ea2c540459843227dea08e8b40;p=thirdparty%2Fsquid.git basic_msnt_auth helper and NTLM/SMBLIB/RFCNB library polish. Samba smblib/rfcnb code: * Import the latest copy which I could find a download link to. This source is from 1997 so I suspect there is something even newer we should be using. Time was tight is the only excuse for using these sources. Our originals were from 1995 and 1996 depending on the helper using it, with a mix of patches. * These two directories are in ours sources as lib/smblib and lib/rfcnb. Each has its own convenience library. Kept separate with original filenames to simplify future upgrades or removal. * Samba sources have been diffed and compared function by function against the copies previously in our sources. Functionality extensions we use have been grafted back on top of the new(er) Samba sources. - this was mostly around passing extra Unicode, DC hints and pre-crypted passwords to the login checks. - some files from libntlmauth have yet to be compared in fine detail, that will be completed today before merge. - some basic API function and struct definitions had to be moved to the API headers to prevent needing to include the *-priv.h private definitions externally to the library. * the Samba API headers have been wrapped with #ifndef safety wrappers * compile errors and include changes required to compile have been made (code stays C) * duplicate code in helpers/basic_auth/MSNT/* and libntlmauth/* is removed. * abuse of the smblib-priv.h and rfcnb-priv.h headers and all local re-definitions has been erased from our code. Replaced by includes of the library API headers: rfcnb/rfcnb.h smblib/smblib.h libntlmauth: * smblib/rfcnb bits erased * moved to lib/ntlmauth in its much reduced form * built as a convenience library instead of full library --- diff --git a/Makefile.am b/Makefile.am index ddec8d2feb..344cc3c975 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,14 +2,11 @@ # AUTOMAKE_OPTIONS = dist-bzip2 subdir-objects 1.5 foreign -DIST_SUBDIRS = compat lib libltdl libntlmauth snmplib scripts src icons errors contrib doc helpers test-suite tools +DIST_SUBDIRS = compat lib libltdl snmplib scripts src icons errors contrib doc helpers test-suite tools SUBDIRS = compat lib $(makesnmplib) if USE_LOADABLE_MODULES SUBDIRS += libltdl endif -if ENABLE_AUTH_NTLM -SUBDIRS += libntlmauth -endif SUBDIRS += scripts src icons errors doc helpers test-suite tools DISTCLEANFILES = include/stamp-h include/stamp-h[0-9]* diff --git a/configure.in b/configure.in index 510c8f8f61..3ea7d60d94 100644 --- a/configure.in +++ b/configure.in @@ -3265,7 +3265,9 @@ AC_CONFIG_FILES([\ Makefile \ compat/Makefile \ lib/Makefile \ - libntlmauth/Makefile \ + lib/ntlmauth/Makefile \ + lib/rfcnb/Makefile \ + lib/smblib/Makefile \ scripts/Makefile \ src/Makefile \ src/base/Makefile \ diff --git a/doc/release-notes/release-3.2.sgml b/doc/release-notes/release-3.2.sgml index b5b8e9e673..09d58142ed 100644 --- a/doc/release-notes/release-3.2.sgml +++ b/doc/release-notes/release-3.2.sgml @@ -172,10 +172,11 @@ Most user-facing changes are reflected in squid.conf (see below). getpwnam_auth - basic_getpwname_auth - Authenticate with local system user accounts. squid_ldap_auth - basic_ldap_auth - Authenticate with LDAP user accounts. MSNT-multi-domain - basic_msnt_multi_domain_auth - Authenticate with any one of multiple Windows Domain Controllers. + msnt_auth - basic_msnt_auth - Authenticate with Windows Domain Controllers selected by username. ncsa_auth - basic_ncsa_auth - Authenticate with NCSA httpd-style password file. yp_auth - basic_nis_auth - Authenticate with NIS security system. pam_auth - basic_pam_auth - Authenticate with the system PAM infrastructure. - pop3.pl - basic_pop3_auth - Authenticate with a mail server POP3/SMTP credentials + pop3.pl - basic_pop3_auth - Authenticate with a mail server POP3/SMTP credentials. squid_radius_auth - basic_radius_auth - Authenticate with RADIUS. squid_sasl_auth - basic_sasl_auth - Authenticate with SASL. smb_auth - basic_smb_auth - Authenticate with Samba SMB. diff --git a/helpers/basic_auth/MSNT/Makefile.am b/helpers/basic_auth/MSNT/Makefile.am index 9cc4faa475..6d74bd6472 100644 --- a/helpers/basic_auth/MSNT/Makefile.am +++ b/helpers/basic_auth/MSNT/Makefile.am @@ -2,16 +2,18 @@ include $(top_srcdir)/src/Common.am MSNTAUTH_CONF = $(sysconfdir)/msntauth.conf -libexec_PROGRAMS = msnt_auth - -msnt_auth_SOURCES = md4.c rfcnb-io.c rfcnb-util.c session.c msntauth.c \ - msntauth.h smbdes.c smbencrypt.c smblib-util.c smblib.c \ - valid.c denyusers.c allowusers.c confload.c \ - usersfile.c \ - byteorder.h rfcnb-common.h rfcnb-error.h rfcnb.h \ - rfcnb-io.h rfcnb-priv.h rfcnb-util.h smblib-common.h \ - smblib.h smblib-priv.h std-defines.h std-includes.h valid.h \ - md4.h smbdes.h smbencrypt.h usersfile.h +libexec_PROGRAMS = basic_msnt_auth + +basic_msnt_auth_SOURCES = \ + allowusers.cc \ + confload.cc \ + denyusers.cc \ + msntauth.cc \ + msntauth.h \ + usersfile.cc \ + usersfile.h \ + valid.cc \ + valid.h EXTRA_DIST = \ msntauth.conf.default \ @@ -22,13 +24,17 @@ EXTRA_DIST = \ sysconf_DATA = \ msntauth.conf.default -LDADD = $(COMPAT_LIB) $(XTRA_LIBS) +CFLAGS += -DSYSCONFDIR=\"$(sysconfdir)\" +CXXFLAGS += -DSYSCONFDIR=\"$(sysconfdir)\" +LDADD = \ + $(top_builddir)/lib/smblib/libsmblib.la \ + $(top_builddir)/lib/rfcnb/librfcnb.la \ + $(COMPAT_LIB) \ + $(XTRA_LIBS) ## we need our local files too (but avoid -I. at all costs) -INCLUDES += -I$(srcdir) +INCLUDES += -I$(srcdir) -I$(top_srcdir)/lib -confload.o: confload.c - $(COMPILE) -DSYSCONFDIR=\"$(sysconfdir)\" -c $(srcdir)/confload.c -o $@ install-data-local: msntauth.conf.default @if test -f $(DESTDIR)$(MSNTAUTH_CONF) ; then \ diff --git a/helpers/basic_auth/MSNT/allowusers.c b/helpers/basic_auth/MSNT/allowusers.cc similarity index 100% rename from helpers/basic_auth/MSNT/allowusers.c rename to helpers/basic_auth/MSNT/allowusers.cc diff --git a/helpers/basic_auth/MSNT/confload.c b/helpers/basic_auth/MSNT/confload.cc similarity index 100% rename from helpers/basic_auth/MSNT/confload.c rename to helpers/basic_auth/MSNT/confload.cc diff --git a/helpers/basic_auth/MSNT/denyusers.c b/helpers/basic_auth/MSNT/denyusers.cc similarity index 100% rename from helpers/basic_auth/MSNT/denyusers.c rename to helpers/basic_auth/MSNT/denyusers.cc diff --git a/helpers/basic_auth/MSNT/md4.h b/helpers/basic_auth/MSNT/md4.h deleted file mode 100644 index b9c6a78089..0000000000 --- a/helpers/basic_auth/MSNT/md4.h +++ /dev/null @@ -1,2 +0,0 @@ -/* md4.c */ -void mdfour(unsigned char *out, unsigned char *in, int n); diff --git a/helpers/basic_auth/MSNT/msntauth.c b/helpers/basic_auth/MSNT/msntauth.cc similarity index 100% rename from helpers/basic_auth/MSNT/msntauth.c rename to helpers/basic_auth/MSNT/msntauth.cc diff --git a/helpers/basic_auth/MSNT/rfcnb-common.h b/helpers/basic_auth/MSNT/rfcnb-common.h deleted file mode 100644 index 45c223b5f4..0000000000 --- a/helpers/basic_auth/MSNT/rfcnb-common.h +++ /dev/null @@ -1,40 +0,0 @@ -/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation - * - * Version 1.0 - * RFCNB Common Structures etc Defines - * - * 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. - */ - -#ifndef _RFCNB_COMMON_H_ -#define _RFCNB_COMMON_H_ - -/* A data structure we need */ - -typedef struct RFCNB_Pkt { - - char *data; /* The data in this portion */ - int len; - struct RFCNB_Pkt *next; - -} RFCNB_Pkt; - - -#endif /* _RFCNB_COMMON_H_ */ diff --git a/helpers/basic_auth/MSNT/rfcnb-error.h b/helpers/basic_auth/MSNT/rfcnb-error.h deleted file mode 100644 index 60d36b555c..0000000000 --- a/helpers/basic_auth/MSNT/rfcnb-error.h +++ /dev/null @@ -1,57 +0,0 @@ -/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation - * - * Version 1.0 - * RFCNB Error Response Defines - * - * 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. - */ - -#ifndef _RFCNB_ERROR_H_ -#define _RFCNB_ERROR_H_ - -/* Error responses */ - -#define RFCNBE_Bad -1 /* Bad response */ -#define RFCNBE_OK 0 - -/* these should follow the spec ... is there one ? */ - -#define RFCNBE_NoSpace 1 /* Could not allocate space for a struct */ -#define RFCNBE_BadName 2 /* Could not translate a name */ -#define RFCNBE_BadRead 3 /* Read sys call failed */ -#define RFCNBE_BadWrite 4 /* Write Sys call failed */ -#define RFCNBE_ProtErr 5 /* Protocol Error */ -#define RFCNBE_ConGone 6 /* Connection dropped */ -#define RFCNBE_BadHandle 7 /* Handle passed was bad */ -#define RFCNBE_BadSocket 8 /* Problems creating socket */ -#define RFCNBE_ConnectFailed 9 /* Connect failed */ -#define RFCNBE_CallRejNLOCN 10 /* Call rejected, not listening on CN */ -#define RFCNBE_CallRejNLFCN 11 /* Call rejected, not listening for CN */ -#define RFCNBE_CallRejCNNP 12 /* Call rejected, called name not present */ -#define RFCNBE_CallRejInfRes 13 /* Call rejetced, name ok, no resources */ -#define RFCNBE_CallRejUnSpec 14 /* Call rejected, unspecified error */ -#define RFCNBE_BadParam 15 /* Bad parameters passed ... */ -#define RFCNBE_Timeout 16 /* IO Timed out */ - -/* Text strings for the error responses */ - -extern const char *RFCNB_Error_Strings[]; - -#endif /* _RFCNB_ERROR_H_ */ diff --git a/helpers/basic_auth/MSNT/rfcnb-io.c b/helpers/basic_auth/MSNT/rfcnb-io.c deleted file mode 100644 index 939b13d85e..0000000000 --- a/helpers/basic_auth/MSNT/rfcnb-io.c +++ /dev/null @@ -1,397 +0,0 @@ -/* UNIX RFCNB (RFC1001/RFC1002) NEtBIOS implementation - * - * Version 1.0 - * RFCNB IO 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 */ -#include "std-includes.h" -#include "rfcnb-priv.h" -#include "rfcnb-util.h" -#include "rfcnb-io.h" -#include -#include -#include -#include -#include - - -int RFCNB_Timeout = 0; /* Timeout in seconds ... */ - -#ifdef NOT_USED -static void -rfcnb_alarm(int sig) -{ - syslog(LOG_ERR, "%s:%d: IO Timed out ...\n", __FILE__, __LINE__); -} -#endif - -/* Set timeout value and setup signal handling */ - -#ifdef NOT_USED -static int -RFCNB_Set_Timeout(int seconds) -{ -#ifdef SA_RESTART - struct sigaction sa; -#endif - int x; - RFCNB_Timeout = seconds; - if (RFCNB_Timeout <= 0) - return 0; -#ifdef SA_RESTART - sa.sa_handler = rfcnb_alarm; - sa.sa_flags = 0; - sigemptyset(&sa.sa_mask); - x = sigaction(SIGALRM, &sa, NULL); - ; -#else - signal(SIGALRM, rfcnb_alarm); -#endif - if (x < 0) { - syslog(LOG_ERR, "%s:%d: signal/sigaction: %s", __FILE__, __LINE__, strerror(errno)); - return -1; - } - return 0; -} -#endif - - -/* - * Discard the rest of an incoming packet as we do not have space for it - * in the buffer we allocated or were passed ... - */ - -static int -RFCNB_Discard_Rest(struct RFCNB_Con *con, int len) -{ - char temp[100]; /* Read into here */ - int rest; - int this_read; - int bytes_read; - - /* len is the amount we should read */ - -#ifdef RFCNB_DEBUG - fprintf(stderr, "Discard_Rest called to discard: %i\n", len); -#endif - - rest = len; - - while (rest > 0) { - - this_read = (rest > sizeof(temp) ? sizeof(temp) : rest); - - bytes_read = read(con->fd, temp, this_read); - - if (bytes_read <= 0) { /* Error so return */ - - if (bytes_read < 0) - RFCNB_errno = RFCNBE_BadRead; - else - RFCNB_errno = RFCNBE_ConGone; - - RFCNB_saved_errno = errno; - return (RFCNBE_Bad); - - } - rest = rest - bytes_read; - - } - - return (0); - -} - - -/* Send an RFCNB packet to the connection. - * - * We just send each of the blocks linked together ... - * - * If we can, try to send it as one iovec ... - * - */ - -int -RFCNB_Put_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len) -{ - int len_sent = 0; - int tot_sent = 0; - int this_len; - int i = 0; - struct RFCNB_Pkt *pkt_ptr = pkt; - char *this_data; - struct iovec io_list[10]; /* We should never have more */ - /* If we do, this will blow up ... */ - - /* Try to send the data ... We only send as many bytes as len claims */ - /* We should try to stuff it into an IOVEC and send as one write */ - - while ((pkt_ptr != NULL) & (i < 10)) { /* Watch that magic number! */ - - this_len = pkt_ptr->len; - this_data = pkt_ptr->data; - if ((tot_sent + this_len) > len) - this_len = len - tot_sent; /* Adjust so we don't send too much */ - - /* Now plug into the iovec ... */ - - io_list[i].iov_len = this_len; - io_list[i].iov_base = this_data; - i++; - - tot_sent += this_len; - - if (tot_sent == len) - break; /* Let's not send too much */ - - pkt_ptr = pkt_ptr->next; - - } - -#ifdef RFCNB_DEBUG - fprintf(stderr, "Frags = %i, tot_sent = %i\n", i, tot_sent); -#endif - - /* Set up an alarm if timeouts are set ... */ - - if (RFCNB_Timeout > 0) - alarm(RFCNB_Timeout); - - if ((len_sent = writev(con->fd, io_list, i)) < 0) { /* An error */ - - con->rfc_errno = errno; - if (errno == EINTR) /* We were interrupted ... */ - RFCNB_errno = RFCNBE_Timeout; - else - RFCNB_errno = RFCNBE_BadWrite; - RFCNB_saved_errno = errno; - return (RFCNBE_Bad); - - } - if (len_sent < tot_sent) { /* Less than we wanted */ - if (errno == EINTR) /* We were interrupted */ - RFCNB_errno = RFCNBE_Timeout; - else - RFCNB_errno = RFCNBE_BadWrite; - RFCNB_saved_errno = errno; - return (RFCNBE_Bad); - } - if (RFCNB_Timeout > 0) - alarm(0); /* Reset that sucker */ - -#ifdef RFCNB_DEBUG - - fprintf(stderr, "Len sent = %i ...\n", len_sent); - RFCNB_Print_Pkt(stderr, "sent", pkt, len_sent); /* Print what send ... */ - -#endif - - return (len_sent); - -} - -/* Read an RFCNB packet off the connection. - * - * We read the first 4 bytes, that tells us the length, then read the - * rest. We should implement a timeout, but we don't just yet - * - */ - - -int -RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len) -{ - int read_len, pkt_len; - char hdr[RFCNB_Pkt_Hdr_Len]; /* Local space for the header */ - struct RFCNB_Pkt *pkt_frag; - int more, this_time, offset, frag_len, this_len; - BOOL seen_keep_alive = TRUE; - - /* Read that header straight into the buffer */ - - if (len < RFCNB_Pkt_Hdr_Len) { /* What a bozo */ - -#ifdef RFCNB_DEBUG - fprintf(stderr, "Trying to read less than a packet:"); - perror(""); -#endif - RFCNB_errno = RFCNBE_BadParam; - return (RFCNBE_Bad); - - } - /* We discard keep alives here ... */ - - if (RFCNB_Timeout > 0) - alarm(RFCNB_Timeout); - - while (seen_keep_alive) { - - if ((read_len = read(con->fd, hdr, sizeof(hdr))) < 0) { /* Problems */ -#ifdef RFCNB_DEBUG - fprintf(stderr, "Reading the packet, we got:"); - perror(""); -#endif - if (errno == EINTR) - RFCNB_errno = RFCNBE_Timeout; - else - RFCNB_errno = RFCNBE_BadRead; - RFCNB_saved_errno = errno; - return (RFCNBE_Bad); - - } - /* Now we check out what we got */ - - if (read_len == 0) { /* Connection closed, send back eof? */ - -#ifdef RFCNB_DEBUG - fprintf(stderr, "Connection closed reading\n"); -#endif - - if (errno == EINTR) - RFCNB_errno = RFCNBE_Timeout; - else - RFCNB_errno = RFCNBE_ConGone; - RFCNB_saved_errno = errno; - return (RFCNBE_Bad); - - } - if (RFCNB_Pkt_Type(hdr) == RFCNB_SESSION_KEEP_ALIVE) { - -#ifdef RFCNB_DEBUG - fprintf(stderr, "RFCNB KEEP ALIVE received\n"); -#endif - - } else { - seen_keep_alive = FALSE; - } - - } - - /* What if we got less than or equal to a hdr size in bytes? */ - - if (read_len < sizeof(hdr)) { /* We got a small packet */ - - /* Now we need to copy the hdr portion we got into the supplied packet */ - - memcpy(pkt->data, hdr, read_len); /*Copy data */ - -#ifdef RFCNB_DEBUG - RFCNB_Print_Pkt(stderr, "rcvd", pkt, read_len); -#endif - - return (read_len); - - } - /* Now, if we got at least a hdr size, alloc space for rest, if we need it */ - - pkt_len = RFCNB_Pkt_Len(hdr); - -#ifdef RFCNB_DEBUG - fprintf(stderr, "Reading Pkt: Length = %i\n", pkt_len); -#endif - - /* Now copy in the hdr */ - - memcpy(pkt->data, hdr, sizeof(hdr)); - - /* Get the rest of the packet ... first figure out how big our buf is? */ - /* And make sure that we handle the fragments properly ... Sure should */ - /* use an iovec ... */ - - if (len < pkt_len) /* Only get as much as we have space for */ - more = len - RFCNB_Pkt_Hdr_Len; - else - more = pkt_len; - - this_time = 0; - - /* We read for each fragment ... */ - - if (pkt->len == read_len) { /* If this frag was exact size */ - pkt_frag = pkt->next; /* Stick next lot in next frag */ - offset = 0; /* then we start at 0 in next */ - } else { - pkt_frag = pkt; /* Otherwise use rest of this frag */ - offset = RFCNB_Pkt_Hdr_Len; /* Otherwise skip the header */ - } - - frag_len = pkt_frag->len; - - if (more <= frag_len) /* If len left to get less than frag space */ - this_len = more; /* Get the rest ... */ - else - this_len = frag_len - offset; - - while (more > 0) { - - if ((this_time = read(con->fd, (pkt_frag->data) + offset, this_len)) <= 0) { /* Problems */ - - if (errno == EINTR) { - - RFCNB_errno = RFCNB_Timeout; - - } else { - if (this_time < 0) - RFCNB_errno = RFCNBE_BadRead; - else - RFCNB_errno = RFCNBE_ConGone; - } - - RFCNB_saved_errno = errno; - return (RFCNBE_Bad); - - } -#ifdef RFCNB_DEBUG - fprintf(stderr, "Frag_Len = %i, this_time = %i, this_len = %i, more = %i\n", frag_len, - this_time, this_len, more); -#endif - - read_len = read_len + this_time; /* How much have we read ... */ - - /* Now set up the next part */ - - if (pkt_frag->next == NULL) - break; /* That's it here */ - - pkt_frag = pkt_frag->next; - this_len = pkt_frag->len; - offset = 0; - - more = more - this_time; - - } - -#ifdef RFCNB_DEBUG - fprintf(stderr, "Pkt Len = %i, read_len = %i\n", pkt_len, read_len); - RFCNB_Print_Pkt(stderr, "rcvd", pkt, read_len + sizeof(hdr)); -#endif - - if (read_len < (pkt_len + sizeof(hdr))) { /* Discard the rest */ - - return (RFCNB_Discard_Rest(con, (pkt_len + sizeof(hdr)) - read_len)); - - } - if (RFCNB_Timeout > 0) - alarm(0); /* Reset that sucker */ - - return (read_len + sizeof(RFCNB_Hdr)); -} diff --git a/helpers/basic_auth/MSNT/rfcnb-io.h b/helpers/basic_auth/MSNT/rfcnb-io.h deleted file mode 100644 index 6b54e86e05..0000000000 --- a/helpers/basic_auth/MSNT/rfcnb-io.h +++ /dev/null @@ -1,28 +0,0 @@ -/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation - * - * Version 1.0 - * RFCNB IO Routines Defines - * - * 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. - */ - -int RFCNB_Put_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len); - -int RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len); diff --git a/helpers/basic_auth/MSNT/rfcnb-priv.h b/helpers/basic_auth/MSNT/rfcnb-priv.h deleted file mode 100644 index d847b3c877..0000000000 --- a/helpers/basic_auth/MSNT/rfcnb-priv.h +++ /dev/null @@ -1,150 +0,0 @@ -/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation - * - * Version 1.0 - * RFCNB Defines - * - * 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. - */ - -/* Defines we need */ - - -#define GLOBAL extern - -#include "rfcnb-error.h" -#include "rfcnb-common.h" -#include "byteorder.h" - -#ifdef RFCNB_PORT -#define RFCNB_Default_Port RFCNB_PORT -#else -#define RFCNB_Default_Port 139 -#endif - -#define RFCNB_MAX_STATS 1 - -/* Protocol defines we need */ - -#define RFCNB_SESSION_MESSAGE 0 -#define RFCNB_SESSION_REQUEST 0x81 -#define RFCNB_SESSION_ACK 0x82 -#define RFCNB_SESSION_REJ 0x83 -#define RFCNB_SESSION_RETARGET 0x84 -#define RFCNB_SESSION_KEEP_ALIVE 0x85 - -/* Structures */ - -typedef struct redirect_addr *redirect_ptr; - -struct redirect_addr { - - struct in_addr ip_addr; - int port; - redirect_ptr next; - -}; - -typedef struct RFCNB_Con { - - int fd; /* File descripter for TCP/IP connection */ - int rfc_errno; /* last error */ - int timeout; /* How many milli-secs before IO times out */ - int redirects; /* How many times we were redirected */ - struct redirect_addr *redirect_list; /* First is first address */ - struct redirect_addr *last_addr; - -} RFCNB_Con; - -typedef char RFCNB_Hdr[4]; /* The header is 4 bytes long with */ -/* char[0] as the type, char[1] the */ -/* flags, and char[2..3] the length */ - -/* Macros to extract things from the header. These are for portability - * between architecture types where we are worried about byte order */ - -#define RFCNB_Pkt_Hdr_Len 4 -#define RFCNB_Pkt_Sess_Len 72 -#define RFCNB_Pkt_Retarg_Len 10 -#define RFCNB_Pkt_Nack_Len 5 -#define RFCNB_Pkt_Type_Offset 0 -#define RFCNB_Pkt_Flags_Offset 1 -#define RFCNB_Pkt_Len_Offset 2 /* Length is 2 bytes plus a flag bit */ -#define RFCNB_Pkt_N1Len_Offset 4 -#define RFCNB_Pkt_Called_Offset 5 -#define RFCNB_Pkt_N2Len_Offset 38 -#define RFCNB_Pkt_Calling_Offset 39 -#define RFCNB_Pkt_Error_Offset 4 -#define RFCNB_Pkt_IP_Offset 4 -#define RFCNB_Pkt_Port_Offset 8 - -/* The next macro isolates the length of a packet, including the bit in the - * flags */ - -#define RFCNB_Pkt_Len(p) (PVAL(p, 3) | (PVAL(p, 2) << 8) | \ - ((PVAL(p, RFCNB_Pkt_Flags_Offset) & 0x01) << 16)) - -#define RFCNB_Put_Pkt_Len(p, v) (p[1] = ((v >> 16) & 1)); \ - (p[2] = ((v >> 8) & 0xFF)); \ - (p[3] = (v & 0xFF)); - -#define RFCNB_Pkt_Type(p) (CVAL(p, RFCNB_Pkt_Type_Offset)) - -/*typedef struct RFCNB_Hdr { - * - * unsigned char type; - * unsigned char flags; - * int16 len; - * - * } RFCNB_Hdr; - * - * typedef struct RFCNB_Sess_Pkt { - * unsigned char type; - * unsigned char flags; - * int16 length; - * unsigned char n1_len; - * char called_name[33]; - * unsigned char n2_len; - * char calling_name[33]; - * } RFCNB_Sess_Pkt; - * - * - * typedef struct RFCNB_Nack_Pkt { - * - * struct RFCNB_Hdr hdr; - * unsigned char error; - * - * } RFCNB_Nack_Pkt; - * - * typedef struct RFCNB_Retarget_Pkt { - * - * struct RFCNB_Hdr hdr; - * int dest_ip; - * unsigned char port; - * - * } RFCNB_Redir_Pkt; */ - -/* Static variables */ - -/* Only declare this if not defined */ - -#ifndef RFCNB_ERRNO -extern int RFCNB_errno; -extern int RFCNB_saved_errno; /* Save this from point of error */ -#endif diff --git a/helpers/basic_auth/MSNT/rfcnb-util.h b/helpers/basic_auth/MSNT/rfcnb-util.h deleted file mode 100644 index e6de08390c..0000000000 --- a/helpers/basic_auth/MSNT/rfcnb-util.h +++ /dev/null @@ -1,51 +0,0 @@ -/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation - * - * Version 1.0 - * RFCNB Utility Defines - * - * 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. - */ - -void RFCNB_CvtPad_Name(char *name1, char *name2); - -void RFCNB_AName_To_NBName(char *AName, char *NBName); - -void RFCNB_NBName_To_AName(char *NBName, char *AName); - -void RFCNB_Print_Hex(FILE * fd, struct RFCNB_Pkt *pkt, int Offset, int Len); - -struct RFCNB_Pkt *RFCNB_Alloc_Pkt(int n); - -void RFCNB_Print_Pkt(FILE * fd, char *dirn, struct RFCNB_Pkt *pkt, int len); - -int RFCNB_Name_To_IP(char *host, struct in_addr *Dest_IP); - -int RFCNB_Close(int socket); - -int RFCNB_IP_Connect(struct in_addr Dest_IP, int port); - -int RFCNB_Session_Req(RFCNB_Con * con, - char *Called_Name, - char *Calling_Name, - BOOL * redirect, - struct in_addr *Dest_IP, - int *port); - -void RFCNB_Free_Pkt(struct RFCNB_Pkt *pkt); diff --git a/helpers/basic_auth/MSNT/rfcnb.h b/helpers/basic_auth/MSNT/rfcnb.h deleted file mode 100644 index b1baa0b008..0000000000 --- a/helpers/basic_auth/MSNT/rfcnb.h +++ /dev/null @@ -1,52 +0,0 @@ -/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation - * - * Version 1.0 - * RFCNB Defines - * - * 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. - */ - -/* Error responses */ - -#include "rfcnb-error.h" -#include "rfcnb-common.h" - -/* Defines we need */ - -#define RFCNB_Default_Port 139 - -/* Definition of routines we define */ - -struct RFCNB_Con; - -void *RFCNB_Call(char *Called_Name, char *Calling_Name, char *Called_Address, - int port); - -int RFCNB_Send(struct RFCNB_Con *Con_Handle, struct RFCNB_Pkt *Data, int Length); - -int RFCNB_Recv(struct RFCNB_Con *Con_Handle, struct RFCNB_Pkt *Data, int Length); - -int RFCNB_Hangup(struct RFCNB_Con *Con_Handle); - -void RFCNB_Get_Error(char *buffer, int buf_len); -int RFCNB_Get_Last_Error(void); -int RFCNB_Get_Last_Errno(void); -void RFCNB_Get_Error_Msg(int code, char *msg_buf, int len); - diff --git a/helpers/basic_auth/MSNT/session.c b/helpers/basic_auth/MSNT/session.c deleted file mode 100644 index fc2a95141c..0000000000 --- a/helpers/basic_auth/MSNT/session.c +++ /dev/null @@ -1,345 +0,0 @@ -/* 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. - */ - -int RFCNB_errno = 0; -int RFCNB_saved_errno = 0; -#define RFCNB_ERRNO - -#include "std-includes.h" -#include -#include "rfcnb-priv.h" -#include "rfcnb-util.h" -#include "rfcnb-io.h" -#include "rfcnb.h" - -#include -#include -#include - -int RFCNB_Stats[RFCNB_MAX_STATS]; - -#ifdef RFCNB_DEBUG -void (*Prot_Print_Routine) () = NULL; /* Pointer to print routine */ -#endif - -/* 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 ... - */ - -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) { /* If the Called Address = "" */ - 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 */ - free(con); - 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; - free(con); - 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 */ - free(con); - 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.. */ - RFCNB_Close(con->fd); /* Close it */ - free(con); - 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 ... */ - -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 ... */ - -int -RFCNB_Recv(struct RFCNB_Con *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 */ - -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; - - -} - -/* Pick up the last error response as a string, hmmm, this routine should */ -/* have been different ... */ - -void -RFCNB_Get_Error(char *buffer, int buf_len) -{ - if (RFCNB_saved_errno <= 0) { - snprintf(buffer, (buf_len-1) ,"%s", RFCNB_Error_Strings[RFCNB_errno]); - } else { - snprintf(buffer, (buf_len-1), "%s\n\terrno:%s", RFCNB_Error_Strings[RFCNB_errno], - strerror(RFCNB_saved_errno)); - } -} - -/* Pick up the last error response and returns as a code */ - -int -RFCNB_Get_Last_Error(void) -{ - return (RFCNB_errno); -} - -/* Pick up saved errno as well */ - -int -RFCNB_Get_Last_Errno(void) -{ - - return (RFCNB_saved_errno); - -} - -/* Pick up the last error response and return in string ... */ - -void -RFCNB_Get_Error_Msg(int code, char *msg_buf, int len) -{ - - strncpy(msg_buf, RFCNB_Error_Strings[abs(code)], len); - -} - -/* Register a higher level protocol print routine */ - -#ifdef RFCNB_DEBUG -void -RFCNB_Register_Print_Routine(void (*fn) ()) -{ - - Prot_Print_Routine = fn; - -} -#endif diff --git a/helpers/basic_auth/MSNT/smblib-common.h b/helpers/basic_auth/MSNT/smblib-common.h deleted file mode 100644 index df6c74de92..0000000000 --- a/helpers/basic_auth/MSNT/smblib-common.h +++ /dev/null @@ -1,189 +0,0 @@ -/* UNIX SMBlib NetBIOS implementation - * - * Version 1.0 - * SMBlib Common Defines - * - * 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. - */ - -/* To get the error class we want the first 8 bits */ -/* Because we just grab 4bytes from the SMB header, we have to re-order */ -/* here, but it makes the NtStatus part easier in future */ - -#ifndef _SMBLIB_COMMON_H_ -#define _SMBLIB_COMMON_H_ - -#define SMBlib_Error_Class(p) (p & 0x000000FF) - -/* To get the error code, we want the bottom 16 bits */ - -#define SMBlib_Error_Code(p) (((unsigned int)p & 0xFFFF0000) >>16) - -/* Error CLASS codes and etc ... */ - -#define SMBC_SUCCESS 0 -#define SMBC_ERRDOS 0x01 -#define SMBC_ERRSRV 0x02 -#define SMBC_ERRHRD 0x03 -#define SMBC_ERRCMD 0xFF - -/* Success error codes */ - -#define SMBS_BUFFERED 0x54 -#define SMBS_LOGGED 0x55 -#define SMBS_DISPLAYED 0x56 - -/* ERRDOS Error codes */ - -#define SMBD_badfunc 0x01 -#define SMBD_badfile 0x02 -#define SMBD_badpath 0x03 -#define SMBD_nofids 0x04 -#define SMBD_noaccess 0x05 -#define SMBD_badfid 0x06 -#define SMBD_badmcb 0x07 -#define SMBD_nomem 0x08 -#define SMBD_badmem 0x09 -#define SMBD_badenv 0x0A -#define SMBD_badformat 0x0B -#define SMBD_badaccess 0x0C -#define SMBD_baddata 0x0D -#define SMBD_reserved 0x0E -#define SMBD_baddrive 0x0F -#define SMBD_remcd 0x10 -#define SMBD_diffdevice 0x11 -#define SMBD_nofiles 0x12 -#define SMBD_badshare 0x20 -#define SMBD_errlock 0x21 -#define SMBD_filexists 0x50 - -/* Server errors ... */ - -#define SMBV_error 0x01 /* Generic error */ -#define SMBV_badpw 0x02 -#define SMBV_badtype 0x03 -#define SMBV_access 0x04 -#define SMBV_invnid 0x05 -#define SMBV_invnetname 0x06 -#define SMBV_invdevice 0x07 -#define SMBV_qfull 0x31 -#define SMBV_qtoobig 0x32 -#define SMBV_qeof 0x33 -#define SMBV_invpfid 0x34 -#define SMBV_paused 0x51 -#define SMBV_msgoff 0x52 -#define SMBV_noroom 0x53 -#define SMBV_rmuns 0x57 -#define SMBV_nosupport 0xFFFF - -/* Hardware error codes ... */ - -#define SMBH_nowrite 0x13 -#define SMBH_badunit 0x14 -#define SMBH_notready 0x15 -#define SMBH_badcmd 0x16 -#define SMBH_data 0x17 -#define SMBH_badreq 0x18 -#define SMBH_seek 0x19 -#define SMBH_badmedia 0x1A -#define SMBH_badsector 0x1B -#define SMBH_nopaper 0x1C -#define SMBH_write 0x1D -#define SMBH_read 0x1E -#define SMBH_general 0x1F -#define SMBH_badshare 0x20 - -/* Access mode defines ... */ - -#define SMB_AMODE_WTRU 0x4000 -#define SMB_AMODE_NOCACHE 0x1000 -#define SMB_AMODE_COMPAT 0x0000 -#define SMB_AMODE_DENYRWX 0x0010 -#define SMB_AMODE_DENYW 0x0020 -#define SMB_AMODE_DENYRX 0x0030 -#define SMB_AMODE_DENYNONE 0x0040 -#define SMB_AMODE_OPENR 0x0000 -#define SMB_AMODE_OPENW 0x0001 -#define SMB_AMODE_OPENRW 0x0002 -#define SMB_AMODE_OPENX 0x0003 -#define SMB_AMODE_FCBOPEN 0x00FF -#define SMB_AMODE_LOCUNKN 0x0000 -#define SMB_AMODE_LOCMSEQ 0x0100 -#define SMB_AMODE_LOCMRAN 0x0200 -#define SMB_AMODE_LOCRAL 0x0300 - -/* File attribute encoding ... */ - -#define SMB_FA_ORD 0x00 -#define SMB_FA_ROF 0x01 -#define SMB_FA_HID 0x02 -#define SMB_FA_SYS 0x04 -#define SMB_FA_VOL 0x08 -#define SMB_FA_DIR 0x10 -#define SMB_FA_ARC 0x20 - -/* Define the protocol types ... */ - -#define SMB_P_Unknown -1 /* Hmmm, is this smart? */ -#define SMB_P_Core 0 -#define SMB_P_CorePlus 1 -#define SMB_P_DOSLanMan1 2 -#define SMB_P_LanMan1 3 -#define SMB_P_DOSLanMan2 4 -#define SMB_P_LanMan2 5 -#define SMB_P_DOSLanMan2_1 6 -#define SMB_P_LanMan2_1 7 -#define SMB_P_NT1 8 - -/* SMBlib return codes */ -/* We want something that indicates whether or not the return code was a */ -/* remote error, a local error in SMBlib or returned from lower layer ... */ -/* Wonder if this will work ... */ -/* SMBlibE_Remote = 1 indicates remote error */ -/* SMBlibE_ values < 0 indicate local error with more info available */ -/* SMBlibE_ values >1 indicate local from SMBlib code errors? */ - -#define SMBlibE_Success 0 -#define SMBlibE_Remote 1 /* Remote error, get more info from con */ -#define SMBlibE_BAD -1 -#define SMBlibE_LowerLayer 2 /* Lower layer error */ -#define SMBlibE_NotImpl 3 /* Function not yet implemented */ -#define SMBlibE_ProtLow 4 /* Protocol negotiated does not support req */ -#define SMBlibE_NoSpace 5 /* No space to allocate a structure */ -#define SMBlibE_BadParam 6 /* Bad parameters */ -#define SMBlibE_NegNoProt 7 /* None of our protocols was liked */ -#define SMBlibE_SendFailed 8 /* Sending an SMB failed */ -#define SMBlibE_RecvFailed 9 /* Receiving an SMB failed */ -#define SMBlibE_GuestOnly 10 /* Logged in as guest */ -#define SMBlibE_CallFailed 11 /* Call remote end failed */ -#define SMBlibE_ProtUnknown 12 /* Protocol unknown */ -#define SMBlibE_NoSuchMsg 13 /* Keep this up to date */ - -typedef struct { /* A structure for a Dirent */ - - unsigned char resume_key[21]; /* Don't touch this */ - unsigned char file_attributes; /* Attributes of file */ - unsigned int date_time; /* date and time of last mod */ - unsigned int size; - char filename[13]; /* The name of the file */ - -} SMB_CP_dirent; - -#endif /* _SMBLIB_COMMON_H_ */ diff --git a/helpers/basic_auth/MSNT/smblib-priv.h b/helpers/basic_auth/MSNT/smblib-priv.h deleted file mode 100644 index 66c99dbc31..0000000000 --- a/helpers/basic_auth/MSNT/smblib-priv.h +++ /dev/null @@ -1,606 +0,0 @@ -/* UNIX SMBlib NetBIOS implementation - * - * Version 1.0 - * SMBlib private Defines - * - * 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. - */ - -#ifndef _SMBLIB_PRIV_H_ -#define _SMBLIB_PRIV_H_ - -#include "std-defines.h" -#include "smblib-common.h" -#include -#include - -#include "byteorder.h" /* Hmmm ... hot good */ - -#ifndef max -#define max(a,b) ((a) < (b) ? (b) : (a)) -#endif - -#define SMB_DEF_IDF 0x424D53FF /* "\377SMB" */ - -/* Core protocol commands */ - -#define SMBmkdir 0x00 /* create directory */ -#define SMBrmdir 0x01 /* delete directory */ -#define SMBopen 0x02 /* open file */ -#define SMBcreate 0x03 /* create file */ -#define SMBclose 0x04 /* close file */ -#define SMBflush 0x05 /* flush file */ -#define SMBunlink 0x06 /* delete file */ -#define SMBmv 0x07 /* rename file */ -#define SMBgetatr 0x08 /* get file attributes */ -#define SMBsetatr 0x09 /* set file attributes */ -#define SMBread 0x0A /* read from file */ -#define SMBwrite 0x0B /* write to file */ -#define SMBlock 0x0C /* lock byte range */ -#define SMBunlock 0x0D /* unlock byte range */ -#define SMBctemp 0x0E /* create temporary file */ -#define SMBmknew 0x0F /* make new file */ -#define SMBchkpth 0x10 /* check directory path */ -#define SMBexit 0x11 /* process exit */ -#define SMBlseek 0x12 /* seek */ -#define SMBtcon 0x70 /* tree connect */ -#define SMBtdis 0x71 /* tree disconnect */ -#define SMBnegprot 0x72 /* negotiate protocol */ -#define SMBdskattr 0x80 /* get disk attributes */ -#define SMBsearch 0x81 /* search directory */ -#define SMBsplopen 0xC0 /* open print spool file */ -#define SMBsplwr 0xC1 /* write to print spool file */ -#define SMBsplclose 0xC2 /* close print spool file */ -#define SMBsplretq 0xC3 /* return print queue */ -#define SMBsends 0xD0 /* send single block message */ -#define SMBsendb 0xD1 /* send broadcast message */ -#define SMBfwdname 0xD2 /* forward user name */ -#define SMBcancelf 0xD3 /* cancel forward */ -#define SMBgetmac 0xD4 /* get machine name */ -#define SMBsendstrt 0xD5 /* send start of multi-block message */ -#define SMBsendend 0xD6 /* send end of multi-block message */ -#define SMBsendtxt 0xD7 /* send text of multi-block message */ - -/* CorePlus protocol */ - -#define SMBlockread 0x13 /* Lock a range and read it */ -#define SMBwriteunlock 0x14 /* Unlock a range and then write */ -#define SMBreadbraw 0x1a /* read a block of data without smb header ohead */ -#define SMBwritebraw 0x1d /* write a block of data without smb header ohead */ -#define SMBwritec 0x20 /* secondary write request */ -#define SMBwriteclose 0x2c /* write a file and then close it */ - -/* DOS Extended Protocol */ - -#define SMBreadBraw 0x1A /* read block raw */ -#define SMBreadBmpx 0x1B /* read block multiplexed */ -#define SMBreadBs 0x1C /* read block (secondary response) */ -#define SMBwriteBraw 0x1D /* write block raw */ -#define SMBwriteBmpx 0x1E /* write block multiplexed */ -#define SMBwriteBs 0x1F /* write block (secondary request) */ -#define SMBwriteC 0x20 /* write complete response */ -#define SMBsetattrE 0x22 /* set file attributes expanded */ -#define SMBgetattrE 0x23 /* get file attributes expanded */ -#define SMBlockingX 0x24 /* lock/unlock byte ranges and X */ -#define SMBtrans 0x25 /* transaction - name, bytes in/out */ -#define SMBtranss 0x26 /* transaction (secondary request/response) */ -#define SMBioctl 0x27 /* IOCTL */ -#define SMBioctls 0x28 /* IOCTL (secondary request/response) */ -#define SMBcopy 0x29 /* copy */ -#define SMBmove 0x2A /* move */ -#define SMBecho 0x2B /* echo */ -#define SMBopenX 0x2D /* open and X */ -#define SMBreadX 0x2E /* read and X */ -#define SMBwriteX 0x2F /* write and X */ -#define SMBsesssetupX 0x73 /* Session Set Up & X (including User Logon) */ -#define SMBtconX 0x75 /* tree connect and X */ -#define SMBffirst 0x82 /* find first */ -#define SMBfunique 0x83 /* find unique */ -#define SMBfclose 0x84 /* find close */ -#define SMBinvalid 0xFE /* invalid command */ - -/* Any more ? */ - -#define SMBdatablockID 0x01 /* A data block identifier */ -#define SMBdialectID 0x02 /* A dialect id */ -#define SMBpathnameID 0x03 /* A pathname ID */ -#define SMBasciiID 0x04 /* An ascii string ID */ -#define SMBvariableblockID 0x05 /* A variable block ID */ - -/* some other defines we need */ - -/* Flags defines ... */ - -#define SMB_FLG2_NON_DOS 0x01 /* We know non dos names */ -#define SMB_FLG2_EXT_ATR 0x02 /* We know about Extended Attributes */ -#define SMB_FLG2_LNG_NAM 0x04 /* Long names ? */ - -typedef unsigned short WORD; -typedef unsigned short UWORD; -typedef unsigned int ULONG; -typedef unsigned char BYTE; -typedef unsigned char UCHAR; - -/* Some macros to allow access to actual packet data so that we */ -/* can change the underlying representation of packets. */ -/* */ -/* The current formats vying for attention are a fragment */ -/* approach where the SMB header is a fragment linked to the */ -/* data portion with the transport protocol (rfcnb or whatever) */ -/* being linked on the front. */ -/* */ -/* The other approach is where the whole packet is one array */ -/* of bytes with space allowed on the front for the packet */ -/* headers. */ - -#define SMB_Hdr(p) (char *)(p -> data) - -/* SMB Hdr def for File Sharing Protocol? From MS and Intel, */ -/* Intel PN 138446 Doc Version 2.0, Nov 7, 1988. This def also */ -/* applies to LANMAN1.0 as well as the Core Protocol */ -/* The spec states that wct and bcc must be present, even if 0 */ - -/* We define these as offsets into a char SMB[] array for the */ -/* sake of portability */ - -/* NOTE!. Some of the lenght defines, SMB__len do not include */ -/* the data that follows in the SMB packet, so the code will have to */ -/* take that into account. */ - -#define SMB_hdr_idf_offset 0 /* 0xFF,'SMB' 0-3 */ -#define SMB_hdr_com_offset 4 /* BYTE 4 */ -#define SMB_hdr_rcls_offset 5 /* BYTE 5 */ -#define SMB_hdr_reh_offset 6 /* BYTE 6 */ -#define SMB_hdr_err_offset 7 /* WORD 7 */ -#define SMB_hdr_reb_offset 9 /* BYTE 9 */ -#define SMB_hdr_flg_offset 9 /* same as reb ... */ -#define SMB_hdr_res_offset 10 /* 7 WORDs 10 */ -#define SMB_hdr_res0_offset 10 /* WORD 10 */ -#define SMB_hdr_flg2_offset 10 /* WORD */ -#define SMB_hdr_res1_offset 12 /* WORD 12 */ -#define SMB_hdr_res2_offset 14 -#define SMB_hdr_res3_offset 16 -#define SMB_hdr_res4_offset 18 -#define SMB_hdr_res5_offset 20 -#define SMB_hdr_res6_offset 22 -#define SMB_hdr_tid_offset 24 -#define SMB_hdr_pid_offset 26 -#define SMB_hdr_uid_offset 28 -#define SMB_hdr_mid_offset 30 -#define SMB_hdr_wct_offset 32 - -#define SMB_hdr_len 33 /* 33 byte header? */ - -#define SMB_hdr_axc_offset 33 /* AndX Command */ -#define SMB_hdr_axr_offset 34 /* AndX Reserved */ -#define SMB_hdr_axo_offset 35 /* Offset from start to WCT of AndX cmd */ - -/* Format of the Negotiate Protocol SMB */ - -#define SMB_negp_bcc_offset 33 -#define SMB_negp_buf_offset 35 /* Where the buffer starts */ -#define SMB_negp_len 35 /* plus the data */ - -/* Format of the Negotiate Response SMB, for CoreProtocol, LM1.2 and */ -/* NT LM 0.12. wct will be 1 for CoreProtocol, 13 for LM 1.2, and 17 */ -/* for NT LM 0.12 */ - -#define SMB_negrCP_idx_offset 33 /* Response to the neg req */ -#define SMB_negrCP_bcc_offset 35 -#define SMB_negrLM_idx_offset 33 /* dialect index */ -#define SMB_negrLM_sec_offset 35 /* Security mode */ -#define SMB_sec_user_mask 0x01 /* 0 = share, 1 = user */ -#define SMB_sec_encrypt_mask 0x02 /* pick out encrypt */ -#define SMB_negrLM_mbs_offset 37 /* max buffer size */ -#define SMB_negrLM_mmc_offset 39 /* max mpx count */ -#define SMB_negrLM_mnv_offset 41 /* max number of VCs */ -#define SMB_negrLM_rm_offset 43 /* raw mode support bit vec */ -#define SMB_read_raw_mask 0x01 -#define SMB_write_raw_mask 0x02 -#define SMB_negrLM_sk_offset 45 /* session key, 32 bits */ -#define SMB_negrLM_st_offset 49 /* Current server time */ -#define SMB_negrLM_sd_offset 51 /* Current server date */ -#define SMB_negrLM_stz_offset 53 /* Server Time Zone */ -#define SMB_negrLM_ekl_offset 55 /* encryption key length */ -#define SMB_negrLM_res_offset 57 /* reserved */ -#define SMB_negrLM_bcc_offset 59 /* bcc */ -#define SMB_negrLM_len 61 /* 61 bytes ? */ -#define SMB_negrLM_buf_offset 61 /* Where the fun begins */ - -#define SMB_negrNTLM_idx_offset 33 /* Selected protocol */ -#define SMB_negrNTLM_sec_offset 35 /* Security more */ -#define SMB_negrNTLM_mmc_offset 36 /* Different format above */ -#define SMB_negrNTLM_mnv_offset 38 /* Max VCs */ -#define SMB_negrNTLM_mbs_offset 40 /* MBS now a long */ -#define SMB_negrNTLM_mrs_offset 44 /* Max raw size */ -#define SMB_negrNTLM_sk_offset 48 /* Session Key */ -#define SMB_negrNTLM_cap_offset 52 /* Capabilities */ -#define SMB_negrNTLM_stl_offset 56 /* Server time low */ -#define SMB_negrNTLM_sth_offset 60 /* Server time high */ -#define SMB_negrNTLM_stz_offset 64 /* Server time zone */ -#define SMB_negrNTLM_ekl_offset 66 /* Encrypt key len */ -#define SMB_negrNTLM_bcc_offset 67 /* Bcc */ -#define SMB_negrNTLM_len 69 -#define SMB_negrNTLM_buf_offset 69 - -/* Offsets related to Tree Connect */ - -#define SMB_tcon_bcc_offset 33 -#define SMB_tcon_buf_offset 35 /* where the data is for tcon */ -#define SMB_tcon_len 35 /* plus the data */ - -#define SMB_tconr_mbs_offset 33 /* max buffer size */ -#define SMB_tconr_tid_offset 35 /* returned tree id */ -#define SMB_tconr_bcc_offset 37 -#define SMB_tconr_len 39 - -#define SMB_tconx_axc_offset 33 /* And X Command */ -#define SMB_tconx_axr_offset 34 /* reserved */ -#define SMB_tconx_axo_offset 35 /* Next command offset */ -#define SMB_tconx_flg_offset 37 /* Flags, bit0=1 means disc TID */ -#define SMB_tconx_pwl_offset 39 /* Password length */ -#define SMB_tconx_bcc_offset 41 /* bcc */ -#define SMB_tconx_buf_offset 43 /* buffer */ -#define SMB_tconx_len 43 /* up to data ... */ - -#define SMB_tconxr_axc_offset 33 /* Where the AndX Command is */ -#define SMB_tconxr_axr_offset 34 /* Reserved */ -#define SMB_tconxr_axo_offset 35 /* AndX offset location */ - -/* Offsets related to tree_disconnect */ - -#define SMB_tdis_bcc_offset 33 /* bcc */ -#define SMB_tdis_len 35 /* total len */ - -#define SMB_tdisr_bcc_offset 33 /* bcc */ -#define SMB_tdisr_len 35 - -/* Offsets related to Open Request */ - -#define SMB_open_mod_offset 33 /* Mode to open with */ -#define SMB_open_atr_offset 35 /* Attributes of file */ -#define SMB_open_bcc_offset 37 /* bcc */ -#define SMB_open_buf_offset 39 /* File name */ -#define SMB_open_len 39 /* Plus the file name */ - -#define SMB_openx_axc_offset 33 /* Next command */ -#define SMB_openx_axr_offset 34 /* Reserved */ -#define SMB_openx_axo_offset 35 /* offset of next wct */ -#define SMB_openx_flg_offset 37 /* Flags, bit0 = need more info */ -/* bit1 = exclusive oplock */ -/* bit2 = batch oplock */ -#define SMB_openx_mod_offset 39 /* mode to open with */ -#define SMB_openx_atr_offset 41 /* search attributes */ -#define SMB_openx_fat_offset 43 /* File attributes */ -#define SMB_openx_tim_offset 45 /* time and date of creat */ -#define SMB_openx_ofn_offset 49 /* Open function */ -#define SMB_openx_als_offset 51 /* Space to allocate on */ -#define SMB_openx_res_offset 55 /* reserved */ -#define SMB_openx_bcc_offset 63 /* bcc */ -#define SMB_openx_buf_offset 65 /* Where file name goes */ -#define SMB_openx_len 65 - -#define SMB_openr_fid_offset 33 /* FID returned */ -#define SMB_openr_atr_offset 35 /* Attributes opened with */ -#define SMB_openr_tim_offset 37 /* Last mod time of file */ -#define SMB_openr_fsz_offset 41 /* File size 4 bytes */ -#define SMB_openr_acc_offset 45 /* Access allowed */ -#define SMB_openr_bcc_offset 47 -#define SMB_openr_len 49 - -#define SMB_openxr_axc_offset 33 /* And X command */ -#define SMB_openxr_axr_offset 34 /* reserved */ -#define SMB_openxr_axo_offset 35 /* offset to next command */ -#define SMB_openxr_fid_offset 37 /* FID returned */ -#define SMB_openxr_fat_offset 39 /* File attributes returned */ -#define SMB_openxr_tim_offset 41 /* File creation date etc */ -#define SMB_openxr_fsz_offset 45 /* Size of file */ -#define SMB_openxr_acc_offset 49 /* Access granted */ - -#define SMB_clos_fid_offset 33 /* FID to close */ -#define SMB_clos_tim_offset 35 /* Last mod time */ -#define SMB_clos_bcc_offset 39 /* bcc */ -#define SMB_clos_len 41 - -/* Offsets related to Write requests */ - -#define SMB_write_fid_offset 33 /* FID to write */ -#define SMB_write_cnt_offset 35 /* bytes to write */ -#define SMB_write_ofs_offset 37 /* location to write to */ -#define SMB_write_clf_offset 41 /* advisory count left */ -#define SMB_write_bcc_offset 43 /* bcc = data bytes + 3 */ -#define SMB_write_buf_offset 45 /* Data=0x01, len, data */ -#define SMB_write_len 45 /* plus the data ... */ - -#define SMB_writr_cnt_offset 33 /* Count of bytes written */ -#define SMB_writr_bcc_offset 35 /* bcc */ -#define SMB_writr_len 37 - -/* Offsets related to read requests */ - -#define SMB_read_fid_offset 33 /* FID of file to read */ -#define SMB_read_cnt_offset 35 /* count of words to read */ -#define SMB_read_ofs_offset 37 /* Where to read from */ -#define SMB_read_clf_offset 41 /* Advisory count to go */ -#define SMB_read_bcc_offset 43 -#define SMB_read_len 45 - -#define SMB_readr_cnt_offset 33 /* Count of bytes returned */ -#define SMB_readr_res_offset 35 /* 4 shorts reserved, 8 bytes */ -#define SMB_readr_bcc_offset 43 /* bcc */ -#define SMB_readr_bff_offset 45 /* buffer format char = 0x01 */ -#define SMB_readr_len_offset 46 /* buffer len */ -#define SMB_readr_len 45 /* length of the readr before data */ - -/* Offsets for Create file */ - -#define SMB_creat_atr_offset 33 /* Attributes of new file ... */ -#define SMB_creat_tim_offset 35 /* Time of creation */ -#define SMB_creat_dat_offset 37 /* 4004BCE :-) */ -#define SMB_creat_bcc_offset 39 /* bcc */ -#define SMB_creat_buf_offset 41 -#define SMB_creat_len 41 /* Before the data */ - -#define SMB_creatr_fid_offset 33 /* FID of created file */ - -/* Offsets for Delete file */ - -#define SMB_delet_sat_offset 33 /* search attribites */ -#define SMB_delet_bcc_offset 35 /* bcc */ -#define SMB_delet_buf_offset 37 -#define SMB_delet_len 37 - -/* Offsets for SESSION_SETUP_ANDX for both LM and NT LM protocols */ - -#define SMB_ssetpLM_mbs_offset 37 /* Max buffer Size, allow for AndX */ -#define SMB_ssetpLM_mmc_offset 39 /* max multiplex count */ -#define SMB_ssetpLM_vcn_offset 41 /* VC number if new VC */ -#define SMB_ssetpLM_snk_offset 43 /* Session Key */ -#define SMB_ssetpLM_pwl_offset 47 /* password length */ -#define SMB_ssetpLM_res_offset 49 /* reserved */ -#define SMB_ssetpLM_bcc_offset 53 /* bcc */ -#define SMB_ssetpLM_len 55 /* before data ... */ -#define SMB_ssetpLM_buf_offset 55 - -#define SMB_ssetpNTLM_mbs_offset 37 /* Max Buffer Size for NT LM 0.12 */ -/* and above */ -#define SMB_ssetpNTLM_mmc_offset 39 /* Max Multiplex count */ -#define SMB_ssetpNTLM_vcn_offset 41 /* VC Number */ -#define SMB_ssetpNTLM_snk_offset 43 /* Session key */ -#define SMB_ssetpNTLM_cipl_offset 47 /* Case Insensitive PW Len */ -#define SMB_ssetpNTLM_cspl_offset 49 /* Unicode pw len */ -#define SMB_ssetpNTLM_res_offset 51 /* reserved */ -#define SMB_ssetpNTLM_cap_offset 55 /* server capabilities */ -#define SMB_ssetpNTLM_bcc_offset 59 /* bcc */ -#define SMB_ssetpNTLM_len 61 /* before data */ -#define SMB_ssetpNTLM_buf_offset 61 - -#define SMB_ssetpr_axo_offset 35 /* Offset of next response ... */ -#define SMB_ssetpr_act_offset 37 /* action, bit 0 = 1 => guest */ -#define SMB_ssetpr_bcc_offset 39 /* bcc */ -#define SMB_ssetpr_buf_offset 41 /* Native OS etc */ - -/* Offsets for SMB create directory */ - -#define SMB_creatdir_bcc_offset 33 /* only a bcc here */ -#define SMB_creatdir_buf_offset 35 /* Where things start */ -#define SMB_creatdir_len 35 - -/* Offsets for SMB delete directory */ - -#define SMB_deletdir_bcc_offset 33 /* only a bcc here */ -#define SMB_deletdir_buf_offset 35 /* where things start */ -#define SMB_deletdir_len 35 - -/* Offsets for SMB check directory */ - -#define SMB_checkdir_bcc_offset 33 /* Only a bcc here */ -#define SMB_checkdir_buf_offset 35 /* where things start */ -#define SMB_checkdir_len 35 - -/* Offsets for SMB search */ - -#define SMB_search_mdc_offset 33 /* Max Dir ents to return */ -#define SMB_search_atr_offset 35 /* Search attributes */ -#define SMB_search_bcc_offset 37 /* bcc */ -#define SMB_search_buf_offset 39 /* where the action is */ -#define SMB_search_len 39 - -#define SMB_searchr_dec_offset 33 /* Dir ents returned */ -#define SMB_searchr_bcc_offset 35 /* bcc */ -#define SMB_searchr_buf_offset 37 /* Where the action starts */ -#define SMB_searchr_len 37 /* before the dir ents */ - -#define SMB_searchr_dirent_len 43 /* 53 bytes */ - -/* Defines for SMB transact and transact2 calls */ - -#define SMB_trans_tpc_offset 33 /* Total param count */ -#define SMB_trans_tdc_offset 35 /* total Data count */ -#define SMB_trans_mpc_offset 37 /* Max params bytes to return */ -#define SMB_trans_mdc_offset 39 /* Max data bytes to return */ -#define SMB_trans_msc_offset 41 /* Max setup words to return */ -#define SMB_trans_rs1_offset 42 /* Reserved byte */ -#define SMB_trans_flg_offset 43 /* flags */ -#define SMB_trans_tmo_offset 45 /* Timeout, long */ -#define SMB_trans_rs2_offset 49 /* Next reserved */ -#define SMB_trans_pbc_offset 51 /* Param Byte count in buf */ -#define SMB_trans_pbo_offset 53 /* Offset to param bytes */ -#define SMB_trans_dbc_offset 55 /* Data byte count in buf */ -#define SMB_trans_dbo_offset 57 /* Data byte offset */ -#define SMB_trans_suc_offset 59 /* Setup count - byte */ -#define SMB_trans_rs3_offset 60 /* Reserved to pad ... */ -#define SMB_trans_len 61 /* Up to setup, still need bcc */ - -#define SMB_transr_tpc_offset 33 /* Total param bytes returned */ -#define SMB_transr_tdc_offset 35 -#define SMB_transr_rs1_offset 37 -#define SMB_transr_pbc_offset 39 -#define SMB_transr_pbo_offset 41 -#define SMB_transr_pdi_offset 43 /* parameter displacement */ -#define SMB_transr_dbc_offset 45 -#define SMB_transr_dbo_offset 47 -#define SMB_transr_ddi_offset 49 -#define SMB_transr_suc_offset 51 -#define SMB_transr_rs2_offset 52 -#define SMB_transr_len 53 - -/* Bit masks for SMB Capabilities ... */ - -#define SMB_cap_raw_mode 0x0001 -#define SMB_cap_mpx_mode 0x0002 -#define SMB_cap_unicode 0x0004 -#define SMB_cap_large_files 0x0008 -#define SMB_cap_nt_smbs 0x0010 -#define SMB_rpc_remote_apis 0x0020 -#define SMB_cap_nt_status 0x0040 -#define SMB_cap_level_II_oplocks 0x0080 -#define SMB_cap_lock_and_read 0x0100 -#define SMB_cap_nt_find 0x0200 - -/* SMB LANMAN api call defines */ - -#define SMB_LMapi_SetUserInfo 0x0072 -#define SMB_LMapi_UserPasswordSet 0x0073 - -/* Structures and defines we use in the client interface */ - -/* The protocols we might support. Perhaps a bit ambitious, as only RFCNB */ -/* has any support so far 0(sometimes called NBT) */ - -typedef enum { - SMB_RFCNB, SMB_IPXNB, SMB_NETBEUI, SMB_X25 -} SMB_Transport_Types; - -typedef enum { - SMB_Con_FShare, SMB_Con_PShare, SMB_Con_IPC -} SMB_Con_Types; - -typedef enum { - SMB_State_NoState, SMB_State_Stopped, SMB_State_Started -} SMB_State_Types; - -/* The following two arrays need to be in step! */ -/* We must make it possible for callers to specify these ... */ - - -extern const char *SMB_Prots[]; -extern int SMB_Types[]; - -typedef struct SMB_Status { - - union { - struct { - unsigned char ErrorClass; - unsigned char Reserved; - unsigned short Error; - } DosError; - unsigned int NtStatus; - } status; -} SMB_Status; - -typedef struct SMB_Tree_Structure *SMB_Tree_Handle; - -typedef struct SMB_Connect_Def *SMB_Handle_Type; - -struct SMB_Connect_Def { - - SMB_Handle_Type Next_Con, Prev_Con; /* Next and previous conn */ - int protocol; /* What is the protocol */ - int prot_IDX; /* And what is the index */ - void *Trans_Connect; /* The connection */ - - /* All these strings should be malloc'd */ - - char service[80], username[80], password[80], desthost[80], sock_options[80]; - char address[80], myname[80]; - - SMB_Tree_Handle first_tree, last_tree; /* List of trees on this server */ - - int gid; /* Group ID, do we need it? */ - int mid; /* Multiplex ID? We might need one per con */ - int pid; /* Process ID */ - - int uid; /* Authenticated user id. */ - - /* It is pretty clear that we need to bust some of */ - /* these out into a per TCon record, as there may */ - /* be multiple TCon's per server, etc ... later */ - - int port; /* port to use in case not default, this is a TCPism! */ - - int max_xmit; /* Max xmit permitted by server */ - int Security; /* 0 = share, 1 = user */ - int Raw_Support; /* bit 0 = 1 = Read Raw supported, 1 = 1 Write raw */ - BOOL encrypt_passwords; /* FALSE = don't */ - int MaxMPX, MaxVC, MaxRaw; - unsigned int SessionKey, Capabilities; - int SvrTZ; /* Server Time Zone */ - int Encrypt_Key_Len; - char Encrypt_Key[80], Domain[80], PDomain[80], OSName[80], LMType[40]; - char Svr_OS[80], Svr_LMType[80], Svr_PDom[80]; - -}; - -#define SMBLIB_DEFAULT_DOMAIN "STAFF" -#define SMBLIB_DEFAULT_OSNAME "UNIX of some type" -#define SMBLIB_DEFAULT_LMTYPE "SMBlib LM2.1 minus a bit" -#define SMBLIB_MAX_XMIT 65535 - -#define SMB_Sec_Mode_Share 0 -#define SMB_Sec_Mode_User 1 - -/* A Tree_Structure */ - -struct SMB_Tree_Structure { - - SMB_Tree_Handle next, prev; - SMB_Handle_Type con; - char path[129]; - char device_type[20]; - int mbs; /* Local MBS */ - int tid; - -}; - -typedef struct SMB_File_Def SMB_File; - -struct SMB_File_Def { - - SMB_Tree_Handle tree; - char filename[256]; /* We should malloc this ... */ - UWORD fid; - unsigned int lastmod; - unsigned int size; /* Could blow up if 64bit files supported */ - UWORD access; - off_t fileloc; - -}; - -/* global Variables for the library */ - -extern SMB_State_Types SMBlib_State; - -#ifndef SMBLIB_ERRNO -extern int SMBlib_errno; -extern int SMBlib_SMB_Error; /* last Error */ -#endif - -#endif /* _SMBLIB_PRIV_H_ */ diff --git a/helpers/basic_auth/MSNT/smblib-util.c b/helpers/basic_auth/MSNT/smblib-util.c deleted file mode 100644 index 417b2f07a3..0000000000 --- a/helpers/basic_auth/MSNT/smblib-util.c +++ /dev/null @@ -1,577 +0,0 @@ -/* UNIX SMBlib NetBIOS implementation - * - * Version 1.0 - * SMBlib Utility 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 "std-includes.h" -#include "smblib-priv.h" -#include "smblib.h" - -#include "rfcnb.h" -#include "rfcnb-priv.h" -#include "rfcnb-util.h" - -#include -#include -#include - -const char *SMB_Prots[] = {"PC NETWORK PROGRAM 1.0", - "MICROSOFT NETWORKS 1.03", - "MICROSOFT NETWORKS 3.0", - "DOS LANMAN1.0", - "LANMAN1.0", - "DOS LM1.2X002", - "LM1.2X002", - "DOS LANMAN2.1", - "LANMAN2.1", - "Samba", - "NT LM 0.12", - "NT LANMAN 1.0", - NULL - }; - -int SMB_Types[] = {SMB_P_Core, - SMB_P_CorePlus, - SMB_P_DOSLanMan1, - SMB_P_DOSLanMan1, - SMB_P_LanMan1, - SMB_P_DOSLanMan2, - SMB_P_LanMan2, - SMB_P_LanMan2_1, - SMB_P_LanMan2_1, - SMB_P_NT1, - SMB_P_NT1, - SMB_P_NT1, - -1 - }; - -/* Figure out what protocol was accepted, given the list of dialect strings */ -/* We offered, and the index back from the server. We allow for a user */ -/* supplied list, and assume that it is a subset of our list */ - -static int -SMB_Figure_Protocol(const char *dialects[], int prot_index) -{ - int i; - - if (dialects == SMB_Prots) { /* The jobs is easy, just index into table */ - - return (SMB_Types[prot_index]); - } else { /* Search through SMB_Prots looking for a match */ - - for (i = 0; SMB_Prots[i] != NULL; i++) { - - if (strcmp(dialects[prot_index], SMB_Prots[i]) == 0) { /* A match */ - - return (SMB_Types[i]); - - } - } - - /* If we got here, then we are in trouble, because the protocol was not */ - /* One we understand ... */ - - return (SMB_P_Unknown); - - } - -} - - -/* Negotiate the protocol we will use from the list passed in Prots */ -/* we return the index of the accepted protocol in NegProt, -1 indicates */ -/* none acceptible, and our return value is 0 if ok, <0 if problems */ - -int -SMB_Negotiate(SMB_Handle_Type Con_Handle, const char *Prots[]) -{ - struct RFCNB_Pkt *pkt; - int prots_len, i, pkt_len, prot, alloc_len; - char *p; - - /* Figure out how long the prot list will be and allocate space for it */ - - prots_len = 0; - - for (i = 0; Prots[i] != NULL; i++) { - - prots_len = prots_len + strlen(Prots[i]) + 2; /* Account for null etc */ - - } - - /* The -1 accounts for the one byte smb_buf we have because some systems */ - /* don't like char msg_buf[] */ - - pkt_len = SMB_negp_len + prots_len; - - /* Make sure that the pkt len is long enough for the max response ... */ - /* Which is a problem, because the encryption key len eec may be long */ - - if (pkt_len < (SMB_hdr_wct_offset + (19 * 2) + 40)) { - - alloc_len = SMB_hdr_wct_offset + (19 * 2) + 40; - - } else { - - alloc_len = pkt_len; - - } - - pkt = (struct RFCNB_Pkt *) RFCNB_Alloc_Pkt(alloc_len); - - if (pkt == NULL) { - - SMBlib_errno = SMBlibE_NoSpace; - return (SMBlibE_BAD); - - } - /* Now plug in the bits we need */ - - memset(SMB_Hdr(pkt), 0, SMB_negp_len); - SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ - *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBnegprot; - SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle->pid); - SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0); - SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle->mid); - SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle->uid); - *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0; - - SSVAL(SMB_Hdr(pkt), SMB_negp_bcc_offset, prots_len); - - /* Now copy the prot strings in with the right stuff */ - - p = (char *) (SMB_Hdr(pkt) + SMB_negp_buf_offset); - - for (i = 0; Prots[i] != NULL; i++) { - - *p = SMBdialectID; - strcpy(p + 1, Prots[i]); - p = p + strlen(Prots[i]) + 2; /* Adjust len of p for null plus dialectID */ - - } - - /* Now send the packet and sit back ... */ - - if (RFCNB_Send(Con_Handle->Trans_Connect, pkt, pkt_len) < 0) { - - -#ifdef DEBUG - fprintf(stderr, "Error sending negotiate protocol\n"); -#endif - - RFCNB_Free_Pkt(pkt); - SMBlib_errno = -SMBlibE_SendFailed; /* Failed, check lower layer errno */ - return (SMBlibE_BAD); - - } - /* Now get the response ... */ - - if (RFCNB_Recv(Con_Handle->Trans_Connect, pkt, alloc_len) < 0) { - -#ifdef DEBUG - fprintf(stderr, "Error receiving response to negotiate\n"); -#endif - - RFCNB_Free_Pkt(pkt); - SMBlib_errno = -SMBlibE_RecvFailed; /* Failed, check lower layer errno */ - return (SMBlibE_BAD); - - } - if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ - -#ifdef DEBUG - fprintf(stderr, "SMB_Negotiate failed with errorclass = %i, Error Code = %i\n", - CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), - SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); -#endif - - SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); - RFCNB_Free_Pkt(pkt); - SMBlib_errno = SMBlibE_Remote; - return (SMBlibE_BAD); - - } - if (SVAL(SMB_Hdr(pkt), SMB_negrCP_idx_offset) == 0xFFFF) { - -#ifdef DEBUG - fprintf(stderr, "None of our protocols was accepted ... "); -#endif - - RFCNB_Free_Pkt(pkt); - SMBlib_errno = SMBlibE_NegNoProt; - return (SMBlibE_BAD); - - } - /* Now, unpack the info from the response, if any and evaluate the proto */ - /* selected. We must make sure it is one we like ... */ - - Con_Handle->prot_IDX = prot = SVAL(SMB_Hdr(pkt), SMB_negrCP_idx_offset); - Con_Handle->protocol = SMB_Figure_Protocol(Prots, prot); - - if (Con_Handle->protocol == SMB_P_Unknown) { /* No good ... */ - - RFCNB_Free_Pkt(pkt); - SMBlib_errno = SMBlibE_ProtUnknown; - return (SMBlibE_BAD); - - } - switch (CVAL(SMB_Hdr(pkt), SMB_hdr_wct_offset)) { - - case 0x01: /* No more info ... */ - - break; - - case 13: /* Up to and including LanMan 2.1 */ - - Con_Handle->Security = SVAL(SMB_Hdr(pkt), SMB_negrLM_sec_offset); - Con_Handle->encrypt_passwords = ((Con_Handle->Security & SMB_sec_encrypt_mask) != 0x00); - Con_Handle->Security = Con_Handle->Security & SMB_sec_user_mask; - - Con_Handle->max_xmit = SVAL(SMB_Hdr(pkt), SMB_negrLM_mbs_offset); - Con_Handle->MaxMPX = SVAL(SMB_Hdr(pkt), SMB_negrLM_mmc_offset); - Con_Handle->MaxVC = SVAL(SMB_Hdr(pkt), SMB_negrLM_mnv_offset); - Con_Handle->Raw_Support = SVAL(SMB_Hdr(pkt), SMB_negrLM_rm_offset); - Con_Handle->SessionKey = IVAL(SMB_Hdr(pkt), SMB_negrLM_sk_offset); - Con_Handle->SvrTZ = SVAL(SMB_Hdr(pkt), SMB_negrLM_stz_offset); - Con_Handle->Encrypt_Key_Len = SVAL(SMB_Hdr(pkt), SMB_negrLM_ekl_offset); - - p = (SMB_Hdr(pkt) + SMB_negrLM_buf_offset); - memcpy(Con_Handle->Encrypt_Key, p, 8); - - p = (SMB_Hdr(pkt) + SMB_negrLM_buf_offset + Con_Handle->Encrypt_Key_Len); - - strncpy(p, Con_Handle->Svr_PDom, sizeof(Con_Handle->Svr_PDom) - 1); - - break; - - case 17: /* NT LM 0.12 and LN LM 1.0 */ - - Con_Handle->Security = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_sec_offset); - Con_Handle->encrypt_passwords = ((Con_Handle->Security & SMB_sec_encrypt_mask) != 0x00); - Con_Handle->Security = Con_Handle->Security & SMB_sec_user_mask; - - Con_Handle->max_xmit = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_mbs_offset); - Con_Handle->MaxMPX = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_mmc_offset); - Con_Handle->MaxVC = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_mnv_offset); - Con_Handle->MaxRaw = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_mrs_offset); - Con_Handle->SessionKey = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_sk_offset); - Con_Handle->SvrTZ = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_stz_offset); - Con_Handle->Encrypt_Key_Len = CVAL(SMB_Hdr(pkt), SMB_negrNTLM_ekl_offset); - - p = (SMB_Hdr(pkt) + SMB_negrNTLM_buf_offset); - memcpy(Con_Handle->Encrypt_Key, p, 8); - p = (SMB_Hdr(pkt) + SMB_negrNTLM_buf_offset + Con_Handle->Encrypt_Key_Len); - - strncpy(p, Con_Handle->Svr_PDom, sizeof(Con_Handle->Svr_PDom) - 1); - - break; - - default: - -#ifdef DEBUG - fprintf(stderr, "Unknown NegProt response format ... Ignored\n"); - fprintf(stderr, " wct = %i\n", CVAL(SMB_Hdr(pkt), SMB_hdr_wct_offset)); -#endif - - break; - } - -#ifdef DEBUG - fprintf(stderr, "Protocol selected is: %i:%s\n", prot, Prots[prot]); -#endif - - RFCNB_Free_Pkt(pkt); - return (0); - -} - -/* Get our hostname */ - -void -SMB_Get_My_Name(char *name, int len) -{ - - if (gethostname(name, len) < 0) { /* Error getting name */ - - strncpy(name, "unknown", len); - - /* Should check the error */ - -#ifdef DEBUG - fprintf(stderr, "gethostname in SMB_Get_My_Name returned error:"); - perror(""); -#endif - - } - /* only keep the portion up to the first "." */ - - -} - -/* Send a TCON to the remote server ... */ - -SMB_Tree_Handle -SMB_TreeConnect(SMB_Handle_Type Con_Handle, - SMB_Tree_Handle Tree_Handle, - char *path, - char *password, - const char *device) -{ - struct RFCNB_Pkt *pkt; - int param_len, pkt_len; - char *p; - SMB_Tree_Handle tree; - - /* Figure out how much space is needed for path, password, dev ... */ - - if ((path == NULL) | (password == NULL) | (device == NULL)) { - -#ifdef DEBUG - fprintf(stderr, "Bad parameter passed to SMB_TreeConnect\n"); -#endif - - SMBlib_errno = SMBlibE_BadParam; - return (NULL); - - } - /* The + 2 is because of the \0 and the marker ... */ - - param_len = strlen(path) + 2 + strlen(password) + 2 + strlen(device) + 2; - - /* The -1 accounts for the one byte smb_buf we have because some systems */ - /* don't like char msg_buf[] */ - - pkt_len = SMB_tcon_len + param_len; - - pkt = (struct RFCNB_Pkt *) RFCNB_Alloc_Pkt(pkt_len); - - if (pkt == NULL) { - - SMBlib_errno = SMBlibE_NoSpace; - return (NULL); /* Should handle the error */ - - } - /* Now allocate a tree for this to go into ... */ - - if (Tree_Handle == NULL) { - - tree = (SMB_Tree_Handle) malloc(sizeof(struct SMB_Tree_Structure)); - - if (tree == NULL) { - - RFCNB_Free_Pkt(pkt); - SMBlib_errno = SMBlibE_NoSpace; - return (NULL); - - } - } else { - - tree = Tree_Handle; - - } - - tree->next = tree->prev = NULL; - tree->con = Con_Handle; - strncpy(tree->path, path, sizeof(tree->path)); - strncpy(tree->device_type, device, sizeof(tree->device_type)); - - /* Now plug in the values ... */ - - memset(SMB_Hdr(pkt), 0, SMB_tcon_len); - SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ - *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBtcon; - SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle->pid); - SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0); - SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle->mid); - SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle->uid); - *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0; - - SSVAL(SMB_Hdr(pkt), SMB_tcon_bcc_offset, param_len); - - /* Now copy the param strings in with the right stuff */ - - p = (char *) (SMB_Hdr(pkt) + SMB_tcon_buf_offset); - *p = SMBasciiID; - strcpy(p + 1, path); - p = p + strlen(path) + 2; - *p = SMBasciiID; - strcpy(p + 1, password); - p = p + strlen(password) + 2; - *p = SMBasciiID; - strcpy(p + 1, device); - - /* Now send the packet and sit back ... */ - - if (RFCNB_Send(Con_Handle->Trans_Connect, pkt, pkt_len) < 0) { - -#ifdef DEBUG - fprintf(stderr, "Error sending TCon request\n"); -#endif - - if (Tree_Handle == NULL) - free(tree); - RFCNB_Free_Pkt(pkt); - SMBlib_errno = -SMBlibE_SendFailed; - return (NULL); - - } - /* Now get the response ... */ - - if (RFCNB_Recv(Con_Handle->Trans_Connect, pkt, pkt_len) < 0) { - -#ifdef DEBUG - fprintf(stderr, "Error receiving response to TCon\n"); -#endif - - if (Tree_Handle == NULL) - free(tree); - RFCNB_Free_Pkt(pkt); - SMBlib_errno = -SMBlibE_RecvFailed; - return (NULL); - - } - /* Check out the response type ... */ - - if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ - -#ifdef DEBUG - fprintf(stderr, "SMB_TCon failed with errorclass = %i, Error Code = %i\n", - CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), - SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); -#endif - - if (Tree_Handle == NULL) - free(tree); - SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); - RFCNB_Free_Pkt(pkt); - SMBlib_errno = SMBlibE_Remote; - return (NULL); - - } - tree->tid = SVAL(SMB_Hdr(pkt), SMB_tconr_tid_offset); - tree->mbs = SVAL(SMB_Hdr(pkt), SMB_tconr_mbs_offset); - -#ifdef DEBUG - fprintf(stderr, "TConn succeeded, with TID=%i, Max Xmit=%i\n", - tree->tid, tree->mbs); -#endif - - /* Now link the Tree to the Server Structure ... */ - - if (Con_Handle->first_tree == NULL) { - - Con_Handle->first_tree = tree; - Con_Handle->last_tree = tree; - - } else { - - Con_Handle->last_tree->next = tree; - tree->prev = Con_Handle->last_tree; - Con_Handle->last_tree = tree; - - } - - RFCNB_Free_Pkt(pkt); - return (tree); - -} - -/* Pick up the last LMBlib error ... */ - -int -SMB_Get_Last_Error() -{ - - return (SMBlib_errno); - -} - -/* Pick up the last error returned in an SMB packet */ -/* We will need macros to extract error class and error code */ - -int -SMB_Get_Last_SMB_Err() -{ - - return (SMBlib_SMB_Error); - -} - -/* Pick up the error message associated with an error from SMBlib */ - -/* Keep this table in sync with the message codes in smblib-common.h */ - -static const char *SMBlib_Error_Messages[] = { - - "Request completed sucessfully.", - "Server returned a non-zero SMB Error Class and Code.", - "A lower layer protocol error occurred.", - "Function not yet implemented.", - "The protocol negotiated does not support the request.", - "No space available for operation.", - "One or more bad parameters passed.", - "None of the protocols we offered were accepted.", - "The attempt to send an SMB request failed. See protocol error info.", - "The attempt to get an SMB response failed. See protocol error info.", - "The logon request failed, but you were logged in as guest.", - "The attempt to call the remote server failed. See protocol error info.", - "The protocol dialect specified in a NegProt and accepted by the server is unknown.", - /* This next one simplifies error handling */ - "No such error code.", - NULL -}; - -void -SMB_Get_Error_Msg(int msg, char *msgbuf, int len) -{ - - if (msg >= 0) { - - strncpy(msgbuf, - SMBlib_Error_Messages[msg > SMBlibE_NoSuchMsg ? SMBlibE_NoSuchMsg : msg], - len - 1); - msgbuf[len - 1] = 0; /* Make sure it is a string */ - } else { /* Add the lower layer message ... */ - - char prot_msg[1024]; - - msg = -msg; /* Make it positive */ - - strncpy(msgbuf, - SMBlib_Error_Messages[msg > SMBlibE_NoSuchMsg ? SMBlibE_NoSuchMsg : msg], - len - 1); - - msgbuf[len - 1] = 0; /* make sure it is a string */ - - if (strlen(msgbuf) < len) { /* If there is space, put rest in */ - - strncat(msgbuf, "\n\t", len - strlen(msgbuf)); - - RFCNB_Get_Error(prot_msg, sizeof(prot_msg) - 1); - - strncat(msgbuf, prot_msg, len - strlen(msgbuf)); - - } - } - -} diff --git a/helpers/basic_auth/MSNT/smblib.c b/helpers/basic_auth/MSNT/smblib.c deleted file mode 100644 index 3c5c18a2ae..0000000000 --- a/helpers/basic_auth/MSNT/smblib.c +++ /dev/null @@ -1,523 +0,0 @@ -/* UNIX SMBlib NetBIOS implementation - * - * Version 1.0 - * SMBlib 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 "util.h" -#include "smblib-priv.h" -#include "smblib.h" -#include "rfcnb-priv.h" -#include "rfcnb.h" -#include "rfcnb-util.h" -#include "smbencrypt.h" - -#include -#include -#include -#include -#include - -#define SMBLIB_ERRNO -#define uchar unsigned char - -int SMBlib_errno; -int SMBlib_SMB_Error; -SMB_State_Types SMBlib_State; - -/* Initialize the SMBlib package */ - -int -SMB_Init(void) -{ - - SMBlib_State = SMB_State_Started; - - signal(SIGPIPE, SIG_IGN); /* Ignore these ... */ - - /* If SMBLIB_Instrument is defines, turn on the instrumentation stuff */ -#ifdef SMBLIB_INSTRUMENT - - SMBlib_Instrument_Init(); - -#endif - - return 0; - -} - -/* SMB_Create: Create a connection structure and return for later use */ -/* We have other helper routines to set variables */ - -SMB_Handle_Type -SMB_Create_Con_Handle(void) -{ - - SMBlib_errno = SMBlibE_NotImpl; - return (NULL); - -} - -/* SMB_Connect_Server: Connect to a server, but don't negotiate protocol */ -/* or anything else ... */ - -SMB_Handle_Type -SMB_Connect_Server(SMB_Handle_Type Con_Handle, - char *server, char *NTdomain) -{ - SMB_Handle_Type con; - char called[80], calling[80], *address; - int i; - - /* Get a connection structure if one does not exist */ - - con = Con_Handle; - - if (Con_Handle == NULL) { - - if ((con = (struct SMB_Connect_Def *) malloc(sizeof(struct SMB_Connect_Def))) == NULL) { - - - SMBlib_errno = SMBlibE_NoSpace; - return NULL; - } - } - /* Init some things ... */ - - strcpy(con->service, ""); - strcpy(con->username, ""); - strcpy(con->password, ""); - strcpy(con->sock_options, ""); - strcpy(con->address, ""); - strcpy(con->desthost, server); - strcpy(con->PDomain, NTdomain); - strcpy(con->OSName, SMBLIB_DEFAULT_OSNAME); - strcpy(con->LMType, SMBLIB_DEFAULT_LMTYPE); - con->first_tree = con->last_tree = NULL; - - SMB_Get_My_Name(con->myname, sizeof(con->myname)); - - con->port = 0; /* No port selected */ - - /* Get some things we need for the SMB Header */ - - con->pid = getpid(); - con->mid = con->pid; /* This will do for now ... */ - con->uid = 0; /* Until we have done a logon, no uid ... */ - con->gid = getgid(); - - /* Now connect to the remote end, but first upper case the name of the - * service we are going to call, sine some servers want it in uppercase */ - - for (i = 0; i < strlen(server); i++) - called[i] = xtoupper(server[i]); - - called[strlen(server)] = 0; /* Make it a string */ - - for (i = 0; i < strlen(con->myname); i++) - calling[i] = xtoupper(con->myname[i]); - - calling[strlen(con->myname)] = 0; /* Make it a string */ - - if (strcmp(con->address, "") == 0) - address = con->desthost; - else - address = con->address; - - con->Trans_Connect = RFCNB_Call(called, - calling, - address, /* Protocol specific */ - con->port); - - /* Did we get one? */ - - if (con->Trans_Connect == NULL) { - - if (Con_Handle == NULL) { - Con_Handle = NULL; - free(con); - } - SMBlib_errno = -SMBlibE_CallFailed; - return NULL; - - } - return (con); - -} - -/* SMB_Connect: Connect to the indicated server */ -/* If Con_Handle == NULL then create a handle and connect, otherwise */ -/* use the handle passed */ - -const char *SMB_Prots_Restrict[] = {"PC NETWORK PROGRAM 1.0", - NULL - }; - - -SMB_Handle_Type -SMB_Connect(SMB_Handle_Type Con_Handle, - SMB_Tree_Handle * tree, - char *service, - char *username, - char *password) -{ - SMB_Handle_Type con; - char *host, *address; - char temp[80], called[80], calling[80]; - int i; - - /* Get a connection structure if one does not exist */ - - con = Con_Handle; - - if (Con_Handle == NULL) { - - if ((con = (struct SMB_Connect_Def *) malloc(sizeof(struct SMB_Connect_Def))) == NULL) { - - SMBlib_errno = SMBlibE_NoSpace; - return NULL; - } - } - /* Init some things ... */ - - strcpy(con->service, service); - strcpy(con->username, username); - strcpy(con->password, password); - strcpy(con->sock_options, ""); - strcpy(con->address, ""); - strcpy(con->PDomain, SMBLIB_DEFAULT_DOMAIN); - strcpy(con->OSName, SMBLIB_DEFAULT_OSNAME); - strcpy(con->LMType, SMBLIB_DEFAULT_LMTYPE); - con->first_tree = con->last_tree = NULL; - - SMB_Get_My_Name(con->myname, sizeof(con->myname)); - - con->port = 0; /* No port selected */ - - /* Get some things we need for the SMB Header */ - - con->pid = getpid(); - con->mid = con->pid; /* This will do for now ... */ - con->uid = 0; /* Until we have done a logon, no uid */ - con->gid = getgid(); - - /* Now figure out the host portion of the service */ - - strcpy(temp, service); - /* AI - Added (char *) to stop compiler warnings */ - host = (char *) strtok(temp, "/\\"); /* Separate host name portion */ - strcpy(con->desthost, host); - - /* Now connect to the remote end, but first upper case the name of the - * service we are going to call, sine some servers want it in uppercase */ - - for (i = 0; i < strlen(host); i++) - called[i] = xtoupper(host[i]); - - called[strlen(host)] = 0; /* Make it a string */ - - for (i = 0; i < strlen(con->myname); i++) - calling[i] = xtoupper(con->myname[i]); - - calling[strlen(con->myname)] = 0; /* Make it a string */ - - if (strcmp(con->address, "") == 0) - address = con->desthost; - else - address = con->address; - - con->Trans_Connect = RFCNB_Call(called, - calling, - address, /* Protocol specific */ - con->port); - - /* Did we get one? */ - - if (con->Trans_Connect == NULL) { - - if (Con_Handle == NULL) { - free(con); - Con_Handle = NULL; - } - SMBlib_errno = -SMBlibE_CallFailed; - return NULL; - - } - /* Now, negotiate the protocol */ - - if (SMB_Negotiate(con, SMB_Prots_Restrict) < 0) { - - /* Hmmm what should we do here ... We have a connection, but could not - * negotiate ... */ - - return NULL; - - } - /* Now connect to the service ... */ - - if ((*tree = SMB_TreeConnect(con, NULL, service, password, "A:")) == NULL) { - - return NULL; - - } - return (con); - -} - -/* Logon to the server. That is, do a session setup if we can. We do not do */ -/* Unicode yet! */ - -int -SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName, - char *PassWord) -{ - struct RFCNB_Pkt *pkt; - int param_len, pkt_len, pass_len; - char *p, pword[128]; - - /* First we need a packet etc ... but we need to know what protocol has */ - /* been negotiated to figure out if we can do it and what SMB format to */ - /* use ... */ - - if (Con_Handle->protocol < SMB_P_LanMan1) { - - SMBlib_errno = SMBlibE_ProtLow; - return (SMBlibE_BAD); - - } - strcpy(pword, PassWord); -#ifdef PAM_SMB_ENC_PASS - if (Con_Handle->encrypt_passwords) { - pass_len = 24; - SMBencrypt((uchar *) PassWord, (uchar *) Con_Handle->Encrypt_Key, (uchar *) pword); - } else -#endif - pass_len = strlen(pword); - - - /* Now build the correct structure */ - - if (Con_Handle->protocol < SMB_P_NT1) { - - param_len = strlen(UserName) + 1 + pass_len + 1 + - strlen(Con_Handle->PDomain) + 1 + - strlen(Con_Handle->OSName) + 1; - - pkt_len = SMB_ssetpLM_len + param_len; - - pkt = (struct RFCNB_Pkt *) RFCNB_Alloc_Pkt(pkt_len); - - if (pkt == NULL) { - - SMBlib_errno = SMBlibE_NoSpace; - return (SMBlibE_BAD); /* Should handle the error */ - - } - memset(SMB_Hdr(pkt), 0, SMB_ssetpLM_len); - SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ - *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX; - SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle->pid); - SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0); - SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle->mid); - SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle->uid); - *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 10; - *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF; /* No extra command */ - SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0); - - SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mbs_offset, SMBLIB_MAX_XMIT); - SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mmc_offset, 2); - SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_vcn_offset, Con_Handle->pid); - SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_snk_offset, 0); - SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_pwl_offset, pass_len + 1); - SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_res_offset, 0); - SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_bcc_offset, param_len); - - /* Now copy the param strings in with the right stuff */ - - p = (char *) (SMB_Hdr(pkt) + SMB_ssetpLM_buf_offset); - - /* Copy in password, then the rest. Password has a null at end */ - - memcpy(p, pword, pass_len); - - p = p + pass_len + 1; - - strcpy(p, UserName); - p = p + strlen(UserName); - *p = 0; - - p = p + 1; - - strcpy(p, Con_Handle->PDomain); - p = p + strlen(Con_Handle->PDomain); - *p = 0; - p = p + 1; - - strcpy(p, Con_Handle->OSName); - p = p + strlen(Con_Handle->OSName); - *p = 0; - - } else { - - /* We don't admit to UNICODE support ... */ - - param_len = strlen(UserName) + 1 + pass_len + - strlen(Con_Handle->PDomain) + 1 + - strlen(Con_Handle->OSName) + 1 + - strlen(Con_Handle->LMType) + 1; - - pkt_len = SMB_ssetpNTLM_len + param_len; - - pkt = (struct RFCNB_Pkt *) RFCNB_Alloc_Pkt(pkt_len); - - if (pkt == NULL) { - - SMBlib_errno = SMBlibE_NoSpace; - return (-1); /* Should handle the error */ - - } - memset(SMB_Hdr(pkt), 0, SMB_ssetpNTLM_len); - SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ - *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX; - SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle->pid); - SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0); - SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle->mid); - SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle->uid); - *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 13; - *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF; /* No extra command */ - SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0); - - SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mbs_offset, SMBLIB_MAX_XMIT); - SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mmc_offset, 0); - SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_vcn_offset, 0); - SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_snk_offset, 0); - SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cipl_offset, pass_len); - SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cspl_offset, 0); - SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_res_offset, 0); - SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cap_offset, 0); - SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_bcc_offset, param_len); - - /* Now copy the param strings in with the right stuff */ - - p = (char *) (SMB_Hdr(pkt) + SMB_ssetpNTLM_buf_offset); - - /* Copy in password, then the rest. Password has no null at end */ - - memcpy(p, pword, pass_len); - - p = p + pass_len; - - strcpy(p, UserName); - p = p + strlen(UserName); - *p = 0; - - p = p + 1; - - strcpy(p, Con_Handle->PDomain); - p = p + strlen(Con_Handle->PDomain); - *p = 0; - p = p + 1; - - strcpy(p, Con_Handle->OSName); - p = p + strlen(Con_Handle->OSName); - *p = 0; - p = p + 1; - - strcpy(p, Con_Handle->LMType); - p = p + strlen(Con_Handle->LMType); - *p = 0; - - } - - /* Now send it and get a response */ - - if (RFCNB_Send(Con_Handle->Trans_Connect, pkt, pkt_len) < 0) { - -#ifdef DEBUG - fprintf(stderr, "Error sending SessSetupX request\n"); -#endif - - RFCNB_Free_Pkt(pkt); - SMBlib_errno = SMBlibE_SendFailed; - return (SMBlibE_BAD); - - } - /* Now get the response ... */ - - if (RFCNB_Recv(Con_Handle->Trans_Connect, pkt, pkt_len) < 0) { - -#ifdef DEBUG - fprintf(stderr, "Error receiving response to SessSetupAndX\n"); -#endif - - RFCNB_Free_Pkt(pkt); - SMBlib_errno = SMBlibE_RecvFailed; - return (SMBlibE_BAD); - - } - /* Check out the response type ... */ - - if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ - -#ifdef DEBUG - fprintf(stderr, "SMB_SessSetupAndX failed with errorclass = %i, Error Code = %i\n", - CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), - SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); -#endif - - SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); - RFCNB_Free_Pkt(pkt); - SMBlib_errno = SMBlibE_Remote; - return (SMBlibE_BAD); - - } -#ifdef DEBUG - fprintf(stderr, "SessSetupAndX response. Action = %i\n", - SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset)); -#endif - - /* Now pick up the UID for future reference ... */ - - Con_Handle->uid = SVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset); - RFCNB_Free_Pkt(pkt); - - return (0); - -} - - -/* Disconnect from the server, and disconnect all tree connects */ - -int -SMB_Discon(SMB_Handle_Type Con_Handle, BOOL KeepHandle) -{ - - /* We just disconnect the connection for now ... */ - - RFCNB_Hangup(Con_Handle->Trans_Connect); - - if (!KeepHandle) - free(Con_Handle); - - return (0); - -} diff --git a/helpers/basic_auth/MSNT/std-defines.h b/helpers/basic_auth/MSNT/std-defines.h deleted file mode 100644 index 4108015086..0000000000 --- a/helpers/basic_auth/MSNT/std-defines.h +++ /dev/null @@ -1,45 +0,0 @@ -/* RFCNB Standard includes ... */ -/* - * - * SMBlib Standard Includes - * - * Copyright (C) 1996, Richard Sharpe - */ -/* One day we will conditionalize these on OS types ... */ - -/* - * 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. - */ - -#ifndef _STD_DEFINES_H_ -#define _STD_DEFINES_H_ - -#define BOOL int16_t -#define int16 int16_t - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TRUE 1 -#define FALSE 0 - -#endif /* _STD_DEFINES_H_ */ diff --git a/helpers/basic_auth/MSNT/std-includes.h b/helpers/basic_auth/MSNT/std-includes.h deleted file mode 100644 index 3336dc820a..0000000000 --- a/helpers/basic_auth/MSNT/std-includes.h +++ /dev/null @@ -1,47 +0,0 @@ -/* RFCNB Standard includes ... */ -/* - * - * RFCNB Standard Includes - * - * Copyright (C) 1996, Richard Sharpe - */ -/* One day we will conditionalize these on OS types ... */ - -/* - * 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. - */ - -/* the types are provided by squid's configure preocess */ -#include "config.h" - -#define BOOL int16_t -#define int16 int16_t - -#include -#include -#include -#include -#include -#include -#include - -#define TRUE 1 -#define FALSE 0 - -/* Pick up define for INADDR_NONE */ - -#ifndef INADDR_NONE -#define INADDR_NONE -1 -#endif diff --git a/helpers/basic_auth/MSNT/usersfile.c b/helpers/basic_auth/MSNT/usersfile.cc similarity index 93% rename from helpers/basic_auth/MSNT/usersfile.c rename to helpers/basic_auth/MSNT/usersfile.cc index 282c5cb871..3074c1eddd 100644 --- a/helpers/basic_auth/MSNT/usersfile.c +++ b/helpers/basic_auth/MSNT/usersfile.cc @@ -29,8 +29,8 @@ static int name_cmp(const void *a, const void *b) { - const char * const *A = a; - const char * const *B = b; + const char * const *A = static_cast(a); + const char * const *B = static_cast(b); return strcasecmp(*A, *B); } @@ -105,10 +105,10 @@ Read_usersfile(const char *path, usersfile * uf) /* grow the list if necessary */ if (0 == uf->Alloc) { uf->Alloc = 256; - uf->names = calloc(uf->Alloc, sizeof(*uf->names)); + uf->names = static_cast(calloc(uf->Alloc, sizeof(*uf->names))); } else if (uf->Inuse == uf->Alloc) { uf->Alloc = uf->Alloc << 1; - uf->names = realloc(uf->names, uf->Alloc * sizeof(*uf->names)); + uf->names = static_cast(realloc(uf->names, uf->Alloc * sizeof(*uf->names))); /* zero out the newly allocated memory */ memset(&uf->names[uf->Alloc >> 1], '\0', diff --git a/helpers/basic_auth/MSNT/valid.c b/helpers/basic_auth/MSNT/valid.cc similarity index 86% rename from helpers/basic_auth/MSNT/valid.c rename to helpers/basic_auth/MSNT/valid.cc index a7a24ce0f2..f82dab63c5 100644 --- a/helpers/basic_auth/MSNT/valid.c +++ b/helpers/basic_auth/MSNT/valid.cc @@ -1,9 +1,14 @@ #include "config.h" +#if HAVE_SYS_TYPES_H #include +#endif +#if HAVE_UNISTD_H #include +#endif +#if HAVE_SYSLOG_H #include -#include "smblib-priv.h" -#include "smblib.h" +#endif +#include "smblib/smblib.h" #include "valid.h" int @@ -19,7 +24,7 @@ Valid_User(char *USERNAME, char *PASSWORD, char *SERVER, char *BACKUP, char *DOM "NT LANMAN 1.0", NULL }; - void *con; + SMB_Handle_Type con; SMB_Init(); con = SMB_Connect_Server(NULL, SERVER, DOMAIN); @@ -33,7 +38,7 @@ Valid_User(char *USERNAME, char *PASSWORD, char *SERVER, char *BACKUP, char *DOM SMB_Discon(con, 0); return (NTV_PROTOCOL_ERROR); } - if (SMB_Logon_Server(con, USERNAME, PASSWORD) < 0) { + if (SMB_Logon_Server(con, USERNAME, PASSWORD, NULL, 0) < 0) { SMB_Discon(con, 0); return (NTV_LOGON_ERROR); } diff --git a/helpers/ntlm_auth/fake/Makefile.am b/helpers/ntlm_auth/fake/Makefile.am index 3f95da400a..8cb2b7fb04 100644 --- a/helpers/ntlm_auth/fake/Makefile.am +++ b/helpers/ntlm_auth/fake/Makefile.am @@ -4,11 +4,13 @@ libexec_PROGRAMS = ntlm_fake_auth ntlm_fake_auth_SOURCES = ntlm_fake_auth.cc ntlm_fake_auth_LDADD = \ - -L$(top_builddir)/libntlmauth -lntlmauth \ + $(top_builddir)/lib/ntlmauth/libntlmauth.la \ $(COMPAT_LIB) \ $(CRYPTLIB) \ $(XTRA_LIBS) +INCLUDES += -I$(top_srcdir)/lib + ## Demo using perl. ## ntlm_fake_auth.pl: ntlm_fake_auth.pl.in ## $(subst_perlshell) diff --git a/helpers/ntlm_auth/fake/ntlm_fake_auth.cc b/helpers/ntlm_auth/fake/ntlm_fake_auth.cc index 73b8a35cc7..816a6ae71d 100644 --- a/helpers/ntlm_auth/fake/ntlm_fake_auth.cc +++ b/helpers/ntlm_auth/fake/ntlm_fake_auth.cc @@ -55,8 +55,8 @@ #include "config.h" #include "helpers/defines.h" -#include "libntlmauth/ntlmauth.h" -#include "libntlmauth/support_bits.cci" +#include "ntlmauth/ntlmauth.h" +#include "ntlmauth/support_bits.cci" #include "util.h" #if HAVE_CTYPE_H diff --git a/helpers/ntlm_auth/smb_lm/Makefile.am b/helpers/ntlm_auth/smb_lm/Makefile.am index 3ea3be14b7..78bae08f73 100644 --- a/helpers/ntlm_auth/smb_lm/Makefile.am +++ b/helpers/ntlm_auth/smb_lm/Makefile.am @@ -4,9 +4,13 @@ libexec_PROGRAMS = ntlm_smb_lm_auth ntlm_smb_lm_auth_SOURCES = ntlm_smb_lm_auth.cc ntlm_smb_lm_auth_LDADD = \ - -L$(top_builddir)/libntlmauth -lntlmauth \ + $(top_builddir)/lib/smblib/libsmblib.la \ + $(top_builddir)/lib/rfcnb/librfcnb.la \ + $(top_builddir)/lib/ntlmauth/libntlmauth.la \ $(COMPAT_LIB) \ $(CRYPTLIB) \ $(XTRA_LIBS) +INCLUDES += -I$(top_srcdir)/lib + EXTRA_DIST = config.test diff --git a/helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.cc b/helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.cc index 2d32af3088..36f1845f9b 100644 --- a/helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.cc +++ b/helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.cc @@ -15,11 +15,11 @@ */ #include "config.h" #include "compat/debug.h" -#include "libntlmauth/ntlmauth.h" -#include "libntlmauth/smb.h" -#include "libntlmauth/rfcnb.h" -#include "libntlmauth/support_bits.cci" -#include "util.h" /* from Squid */ +#include "ntlmauth/ntlmauth.h" +#include "ntlmauth/support_bits.cci" +#include "rfcnb/rfcnb.h" +#include "smblib/smblib.h" +#include "util.h" #if HAVE_STRING_H #include @@ -94,33 +94,6 @@ void process_options(int argc, char *argv[]); const char * obtain_challenge(void); void manage_request(void); -/* these are part of rfcnb-priv.h and smblib-priv.h */ -extern int SMB_Get_Error_Msg(int msg, char *msgbuf, int len); -extern int SMB_Get_Last_Error(); -extern int RFCNB_Get_Last_Errno(); -extern int RFCNB_Get_Last_Error(void); -extern int SMB_Get_Last_SMB_Err(void); - - -/* a few forward-declarations. Hackish, but I don't care right now */ -SMB_Handle_Type SMB_Connect_Server(SMB_Handle_Type Con_Handle, char *server, char *NTdomain); - -/* this one is reallllly haackiish. We really should be using anything from smblib-priv.h - */ -static char const *SMB_Prots[] = {"PC NETWORK PROGRAM 1.0", - "MICROSOFT NETWORKS 1.03", - "MICROSOFT NETWORKS 3.0", - "DOS LANMAN1.0", - "LANMAN1.0", - "DOS LM1.2X002", - "LM1.2X002", - "DOS LANMAN2.1", - "LANMAN2.1", - "Samba", - "NT LM 0.12", - "NT LANMAN 1.0", - NULL - }; #define ENCODED_PASS_LEN 24 #define MAX_USERNAME_LEN 255 diff --git a/lib/Makefile.am b/lib/Makefile.am index e8d71bf882..fbe878a89e 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -5,8 +5,12 @@ include $(top_srcdir)/src/Common.am -SUBDIRS = +DIST_SUBDIRS = ntlmauth rfcnb smblib libTrie +SUBDIRS = rfcnb smblib +if ENABLE_AUTH_NTLM +SUBDIRS += ntlmauth +endif if USE_ESI SUBDIRS += libTrie endif diff --git a/lib/ntlmauth/Makefile.am b/lib/ntlmauth/Makefile.am new file mode 100644 index 0000000000..762f0d9e3e --- /dev/null +++ b/lib/ntlmauth/Makefile.am @@ -0,0 +1,11 @@ +include $(top_srcdir)/src/Common.am +include $(top_srcdir)/src/TestHeaders.am + +INCLUDES += -I$(top_srcdir)/lib + +noinst_LTLIBRARIES = libntlmauth.la + +libntlmauth_la_SOURCES = \ + ntlmauth.cc \ + ntlmauth.h \ + support_bits.cci diff --git a/libntlmauth/ntlmauth.cc b/lib/ntlmauth/ntlmauth.cc similarity index 99% rename from libntlmauth/ntlmauth.cc rename to lib/ntlmauth/ntlmauth.cc index 28f8085c13..4bfa6ebfcf 100644 --- a/libntlmauth/ntlmauth.cc +++ b/lib/ntlmauth/ntlmauth.cc @@ -34,7 +34,7 @@ #include #endif -#include "libntlmauth/ntlmauth.h" +#include "ntlmauth/ntlmauth.h" #include "util.h" /* for base64-related stuff */ /* ************************************************************************* */ diff --git a/libntlmauth/ntlmauth.h b/lib/ntlmauth/ntlmauth.h similarity index 100% rename from libntlmauth/ntlmauth.h rename to lib/ntlmauth/ntlmauth.h diff --git a/libntlmauth/support_bits.cci b/lib/ntlmauth/support_bits.cci similarity index 100% rename from libntlmauth/support_bits.cci rename to lib/ntlmauth/support_bits.cci diff --git a/lib/rfcnb/CHANGELOG b/lib/rfcnb/CHANGELOG new file mode 100644 index 0000000000..2b069b6e58 --- /dev/null +++ b/lib/rfcnb/CHANGELOG @@ -0,0 +1,25 @@ +Oct 2010 - Imported into Squid. + Many build fixes for modern compilers. + Shuffled several private functions (error display and logon) to + to public API file for external use without using rfcnb-priv.h. + +Aug-1996 + +Added #define of INADDR_NONE if not already defined, as Suns do not seem +to define it. + +6-Sep-1996 + +Fixed bug in rfcnb-priv.h where we were getting the packet length wrong +(byte reversed on Suns ...) ... At least I think it is fixed. Will +test. + +6-Sep-1996 + +Use siganction on machines where SA_RESTART is defined, otherwise use +sigvec. This allows the code to compile on Sun, and maybe on HP-UX. + +13-Sep-1996 + +Fixed that bug in rfcnb-priv.h again in RFCNB_Pkt_Len. We were not +shifting the second length byte into the right place. diff --git a/lib/rfcnb/Makefile.am b/lib/rfcnb/Makefile.am new file mode 100644 index 0000000000..ef8953ab33 --- /dev/null +++ b/lib/rfcnb/Makefile.am @@ -0,0 +1,19 @@ +include $(top_srcdir)/src/Common.am + +INCLUDES += -I$(top_srcdir)/lib + +noinst_LTLIBRARIES = librfcnb.la + +librfcnb_la_SOURCES = \ + byteorder.h \ + rfcnb.h \ + rfcnb-common.h \ + rfcnb-error.h \ + rfcnb-priv.h \ + rfcnb-util.h \ + rfcnb-io.h \ + rfcnb-io.c \ + rfcnb-util.c \ + rfcnb-util.h \ + session.c \ + std-includes.h diff --git a/lib/rfcnb/ReadMe.1st b/lib/rfcnb/ReadMe.1st new file mode 100644 index 0000000000..4ffbc2fce0 --- /dev/null +++ b/lib/rfcnb/ReadMe.1st @@ -0,0 +1,52 @@ +RFCNB +Richard Sharpe, +Digital Equipment + +I wrote it in an attempt to understand more about the SMB protocol and +the RFCNB (NBT) protocol underlying it. My manager approved my posting this +as long as there was no suggestion that Digital is responsible for this code +not that any warranties are offered by Digital. So, I put a GPL on the code. + +DISCLAIMER + +To restate, this code is offered as is, and no warranties are implied, either +by Digital Equipment Corporation or by Richard Sharpe. Neither +Digital Equipment Corporation nor Richard Sharpe can be held liable for +any consequences resulting from the use of this code. + +END Disclaimer + +The directory rfcnb contains the following: + +Makefile: a small makefile to build things in this dir + +notes: some notes I made about things ... + +rfcnb.h: defines of the interface routines + +rfcnb-error.h: rfcnb error return definitions etc + +rfcnb-io.h: definitions for routines that do IO to the network + +rfcnb-util.h: definitions of utility routines + +rfcnb-common.h: common defines needed in rfcnb.h and rfcnb-priv.h + +rfcnb-priv.h: defines private to the implementation + +std-includes.h: standard includes and defines + +name-service.c: name service routines. Not implemented yet. + +rfcnb-util.c: utility routines used by session.c and others. + +rfcnb-io.c: all IO to network occurs here + +test_rfcnb.c: a small test program + +session.c: all session routine code is here + +todo: a list of things I would like to do ... + + + diff --git a/lib/rfcnb/byteorder.h b/lib/rfcnb/byteorder.h new file mode 100644 index 0000000000..2dae575619 --- /dev/null +++ b/lib/rfcnb/byteorder.h @@ -0,0 +1,80 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + SMB Byte handling + Copyright (C) Andrew Tridgell 1992-1995 + + 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. +*/ + +/* + This file implements macros for machine independent short and + int manipulation +*/ + +#undef CAREFUL_ALIGNMENT + +/* we know that the 386 can handle misalignment and has the "right" + byteorder */ +#ifdef __i386__ +#define CAREFUL_ALIGNMENT 0 +#endif + +#ifndef CAREFUL_ALIGNMENT +#define CAREFUL_ALIGNMENT 1 +#endif + +#define CVAL(buf,pos) (((unsigned char *)(buf))[pos]) +#define PVAL(buf,pos) ((unsigned)CVAL(buf,pos)) +#define SCVAL(buf,pos,val) (CVAL(buf,pos) = (val)) + + +#if CAREFUL_ALIGNMENT +#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8) +#define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16) +#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8) +#define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16)) +#define SVALS(buf,pos) ((int16)SVAL(buf,pos)) +#define IVALS(buf,pos) ((int32)IVAL(buf,pos)) +#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((uint16)(val))) +#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32)(val))) +#define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16)(val))) +#define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32)(val))) +#else +/* this handles things for architectures like the 386 that can handle + alignment errors */ +/* + WARNING: This section is dependent on the length of int16 and int32 + being correct +*/ +#define SVAL(buf,pos) (*(uint16 *)((char *)(buf) + (pos))) +#define IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos))) +#define SVALS(buf,pos) (*(int16 *)((char *)(buf) + (pos))) +#define IVALS(buf,pos) (*(int32 *)((char *)(buf) + (pos))) +#define SSVAL(buf,pos,val) SVAL(buf,pos)=((uint16)(val)) +#define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32)(val)) +#define SSVALS(buf,pos,val) SVALS(buf,pos)=((int16)(val)) +#define SIVALS(buf,pos,val) IVALS(buf,pos)=((int32)(val)) +#endif + + +/* now the reverse routines - these are used in nmb packets (mostly) */ +#define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF)) +#define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16))) + +#define RSVAL(buf,pos) SREV(SVAL(buf,pos)) +#define RIVAL(buf,pos) IREV(IVAL(buf,pos)) +#define RSSVAL(buf,pos,val) SSVAL(buf,pos,SREV(val)) +#define RSIVAL(buf,pos,val) SIVAL(buf,pos,IREV(val)) diff --git a/lib/rfcnb/notes b/lib/rfcnb/notes new file mode 100644 index 0000000000..22a5e1524e --- /dev/null +++ b/lib/rfcnb/notes @@ -0,0 +1,10 @@ +Notes on RFCNB Impl by R J Sharpe. CopyRight 1996. + +1. Microsoft implementations do not seem to like a 0x00 as char 16 + of the called name, but will work with either a space as char 16 of + the calling name or a 0x00 as char 16. I have not tried any other + combinations. + +2. SAMBA does not seem to care what is in char 16. It certainly works + with either a space or a 0x00. (becomes 'AA' for 0x00 or 'CA' for + 0x20. diff --git a/lib/rfcnb/rfcnb-common.h b/lib/rfcnb/rfcnb-common.h new file mode 100644 index 0000000000..e9e610bea8 --- /dev/null +++ b/lib/rfcnb/rfcnb-common.h @@ -0,0 +1,46 @@ +/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation + + Version 1.0 + RFCNB Common Structures etc Defines + + 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. +*/ + +#ifndef _RFCNB_RFCNB_COMMON_H +#define _RFCNB_RFCNB_COMMON_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* A data structure we need */ + +typedef struct RFCNB_Pkt { + + char * data; /* The data in this portion */ + int len; + struct RFCNB_Pkt *next; + +} RFCNB_Pkt; + +#ifdef __cplusplus +} +#endif +#endif /* _RFCNB_RFCNB_COMMON_H */ diff --git a/lib/rfcnb/rfcnb-error.h b/lib/rfcnb/rfcnb-error.h new file mode 100644 index 0000000000..ac1a1e51b6 --- /dev/null +++ b/lib/rfcnb/rfcnb-error.h @@ -0,0 +1,64 @@ +/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation + + Version 1.0 + RFCNB Error Response Defines + + 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. +*/ + +#ifndef _RFCNB_ERROR_H_ +#define _RFCNB_ERROR_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Error responses */ + +#define RFCNBE_Bad -1 /* Bad response */ +#define RFCNBE_OK 0 + +/* these should follow the spec ... is there one ?*/ + +#define RFCNBE_NoSpace 1 /* Could not allocate space for a struct */ +#define RFCNBE_BadName 2 /* Could not translate a name */ +#define RFCNBE_BadRead 3 /* Read sys call failed */ +#define RFCNBE_BadWrite 4 /* Write Sys call failed */ +#define RFCNBE_ProtErr 5 /* Protocol Error */ +#define RFCNBE_ConGone 6 /* Connection dropped */ +#define RFCNBE_BadHandle 7 /* Handle passed was bad */ +#define RFCNBE_BadSocket 8 /* Problems creating socket */ +#define RFCNBE_ConnectFailed 9 /* Connect failed */ +#define RFCNBE_CallRejNLOCN 10 /* Call rejected, not listening on CN */ +#define RFCNBE_CallRejNLFCN 11 /* Call rejected, not listening for CN */ +#define RFCNBE_CallRejCNNP 12 /* Call rejected, called name not present */ +#define RFCNBE_CallRejInfRes 13/* Call rejetced, name ok, no resources */ +#define RFCNBE_CallRejUnSpec 14/* Call rejected, unspecified error */ +#define RFCNBE_BadParam 15/* Bad parameters passed ... */ +#define RFCNBE_Timeout 16/* IO Timed out */ + +/* Text strings for the error responses */ + +extern const char *RFCNB_Error_Strings[]; + +#ifdef __cplusplus +} +#endif +#endif /* _RFCNB_ERROR_H_ */ diff --git a/lib/rfcnb/rfcnb-io.c b/lib/rfcnb/rfcnb-io.c new file mode 100644 index 0000000000..1f5a1f3936 --- /dev/null +++ b/lib/rfcnb/rfcnb-io.c @@ -0,0 +1,455 @@ +#include "config.h" + +/* UNIX RFCNB (RFC1001/RFC1002) NEtBIOS implementation + + Version 1.0 + RFCNB IO 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 "rfcnb/std-includes.h" +#include "rfcnb/rfcnb-priv.h" +#include "rfcnb/rfcnb-util.h" +#include "rfcnb/rfcnb-io.h" +#include +#include + +#if HAVE_STRING_H +#include +#endif + +int RFCNB_Timeout = 0; /* Timeout in seconds ... */ + +int RFCNB_Discard_Rest(struct RFCNB_Con *con, int len); + +#ifdef NOT_USED +void rfcnb_alarm(int sig) + +{ + + fprintf(stderr, "IO Timed out ...\n"); + +} + +/* Set timeout value and setup signal handling */ + +int RFCNB_Set_Timeout(int seconds) + +{ + /* If we are on a Bezerkeley system, use sigvec, else sigaction */ + +#if ORIGINAL_SAMBA_CODE +#ifndef SA_RESTART + struct sigvec invec, outvec; +#else + struct sigaction inact, outact; +#endif + + RFCNB_Timeout = seconds; + + if (RFCNB_Timeout > 0) { /* Set up handler to ignore but not restart */ + +#ifndef SA_RESTART + invec.sv_handler = (void (*)())rfcnb_alarm; + invec.sv_mask = 0; + invec.sv_flags = SV_INTERRUPT; + + if (sigvec(SIGALRM, &invec, &outvec) < 0) + return(-1); +#else + inact.sa_handler = (void (*)())rfcnb_alarm; +#ifdef Solaris + /* Solaris seems to have an array of vectors ... */ + inact.sa_mask.__sigbits[0] = 0; + inact.sa_mask.__sigbits[1] = 0; + inact.sa_mask.__sigbits[2] = 0; + inact.sa_mask.__sigbits[3] = 0; +#else + inact.sa_mask = (sigset_t)0; +#endif + inact.sa_flags = 0; /* Don't restart */ + + if (sigaction(SIGALRM, &inact, &outact) < 0) + return(-1); + +#endif + + } + +#else /* ADAPTED SQUID CODE */ +#if HAVE_SIGACTION + struct sigaction inact, outact; +#else + struct sigvec invec, outvec; +#endif + + RFCNB_Timeout = seconds; + + if (RFCNB_Timeout > 0) { /* Set up handler to ignore but not restart */ + +#if HAVE_SIGACTION + inact.sa_handler = (void (*)()) rfcnb_alarm; + sigemptyset(&inact.sa_mask); + inact.sa_flags = 0; /* Don't restart */ + + if (sigaction(SIGALRM, &inact, &outact) < 0) + return (-1); +#else + invec.sv_handler = (void (*)()) rfcnb_alarm; + invec.sv_mask = 0; + invec.sv_flags = SV_INTERRUPT; + + if (sigvec(SIGALRM, &invec, &outvec) < 0) + return (-1); +#endif + +#endif + return(0); + +} +#endif + +/* Discard the rest of an incoming packet as we do not have space for it + in the buffer we allocated or were passed ... */ + +int RFCNB_Discard_Rest(struct RFCNB_Con *con, int len) + +{ + char temp[100]; /* Read into here */ + int rest, this_read, bytes_read; + + /* len is the amount we should read */ + +#ifdef RFCNB_DEBUG + fprintf(stderr, "Discard_Rest called to discard: %i\n", len); +#endif + + rest = len; + + while (rest > 0) { + + this_read = (rest > sizeof(temp)?sizeof(temp):rest); + + bytes_read = read(con -> fd, temp, this_read); + + if (bytes_read <= 0) { /* Error so return */ + + if (bytes_read < 0) + RFCNB_errno = RFCNBE_BadRead; + else + RFCNB_errno = RFCNBE_ConGone; + + RFCNB_saved_errno = errno; + return(RFCNBE_Bad); + + } + + rest = rest - bytes_read; + + } + + return(0); + +} + + +/* Send an RFCNB packet to the connection. + + We just send each of the blocks linked together ... + + If we can, try to send it as one iovec ... + +*/ + +int RFCNB_Put_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len) + +{ + int len_sent, tot_sent, this_len; + struct RFCNB_Pkt *pkt_ptr; + char *this_data; + int i; + struct iovec io_list[10]; /* We should never have more */ + /* If we do, this will blow up ...*/ + + /* Try to send the data ... We only send as many bytes as len claims */ + /* We should try to stuff it into an IOVEC and send as one write */ + + + pkt_ptr = pkt; + len_sent = tot_sent = 0; /* Nothing sent so far */ + i = 0; + + while ((pkt_ptr != NULL) & (i < 10)) { /* Watch that magic number! */ + + this_len = pkt_ptr -> len; + this_data = pkt_ptr -> data; + if ((tot_sent + this_len) > len) + this_len = len - tot_sent; /* Adjust so we don't send too much */ + + /* Now plug into the iovec ... */ + + io_list[i].iov_len = this_len; + io_list[i].iov_base = this_data; + i++; + + tot_sent += this_len; + + if (tot_sent == len) break; /* Let's not send too much */ + + pkt_ptr = pkt_ptr -> next; + + } + +#ifdef RFCNB_DEBUG + fprintf(stderr, "Frags = %i, tot_sent = %i\n", i, tot_sent); +#endif + + /* Set up an alarm if timeouts are set ... */ + + if (RFCNB_Timeout > 0) + alarm(RFCNB_Timeout); + + if ((len_sent = writev(con -> fd, io_list, i)) < 0) { /* An error */ + + con -> errn = errno; + if (errno == EINTR) /* We were interrupted ... */ + RFCNB_errno = RFCNBE_Timeout; + else + RFCNB_errno = RFCNBE_BadWrite; + RFCNB_saved_errno = errno; + return(RFCNBE_Bad); + + } + + if (len_sent < tot_sent) { /* Less than we wanted */ + if (errno == EINTR) /* We were interrupted */ + RFCNB_errno = RFCNBE_Timeout; + else + RFCNB_errno = RFCNBE_BadWrite; + RFCNB_saved_errno = errno; + return(RFCNBE_Bad); + } + + if (RFCNB_Timeout > 0) + alarm(0); /* Reset that sucker */ + +#ifdef RFCNB_DEBUG + + fprintf(stderr, "Len sent = %i ...\n", len_sent); + RFCNB_Print_Pkt(stderr, "sent", pkt, len_sent); /* Print what send ... */ + +#endif + + return(len_sent); + +} + +/* Read an RFCNB packet off the connection. + + We read the first 4 bytes, that tells us the length, then read the + rest. We should implement a timeout, but we don't just yet + +*/ + + +int RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len) + +{ + int read_len, pkt_len; + char hdr[RFCNB_Pkt_Hdr_Len]; /* Local space for the header */ + struct RFCNB_Pkt *pkt_frag; + int more, this_time, offset, frag_len, this_len; + BOOL seen_keep_alive = TRUE; + + /* Read that header straight into the buffer */ + + if (len < RFCNB_Pkt_Hdr_Len) { /* What a bozo */ + +#ifdef RFCNB_DEBUG + fprintf(stderr, "Trying to read less than a packet:"); + perror(""); +#endif + RFCNB_errno = RFCNBE_BadParam; + return(RFCNBE_Bad); + + } + + /* We discard keep alives here ... */ + + if (RFCNB_Timeout > 0) + alarm(RFCNB_Timeout); + + while (seen_keep_alive) { + + if ((read_len = read(con -> fd, hdr, sizeof(hdr))) < 0) { /* Problems */ +#ifdef RFCNB_DEBUG + fprintf(stderr, "Reading the packet, we got:"); + perror(""); +#endif + if (errno == EINTR) + RFCNB_errno = RFCNBE_Timeout; + else + RFCNB_errno = RFCNBE_BadRead; + RFCNB_saved_errno = errno; + return(RFCNBE_Bad); + + } + + /* Now we check out what we got */ + + if (read_len == 0) { /* Connection closed, send back eof? */ + +#ifdef RFCNB_DEBUG + fprintf(stderr, "Connection closed reading\n"); +#endif + + if (errno == EINTR) + RFCNB_errno = RFCNBE_Timeout; + else + RFCNB_errno = RFCNBE_ConGone; + RFCNB_saved_errno = errno; + return(RFCNBE_Bad); + + } + + if (RFCNB_Pkt_Type(hdr) == RFCNB_SESSION_KEEP_ALIVE) { + +#ifdef RFCNB_DEBUG + fprintf(stderr, "RFCNB KEEP ALIVE received\n"); +#endif + + } else { + seen_keep_alive = FALSE; + } + + } + + /* What if we got less than or equal to a hdr size in bytes? */ + + if (read_len < sizeof(hdr)) { /* We got a small packet */ + + /* Now we need to copy the hdr portion we got into the supplied packet */ + + memcpy(pkt -> data, hdr, read_len); /*Copy data */ + +#ifdef RFCNB_DEBUG + RFCNB_Print_Pkt(stderr, "rcvd", pkt, read_len); +#endif + + return(read_len); + + } + + /* Now, if we got at least a hdr size, alloc space for rest, if we need it */ + + pkt_len = RFCNB_Pkt_Len(hdr); + +#ifdef RFCNB_DEBUG + fprintf(stderr, "Reading Pkt: Length = %i\n", pkt_len); +#endif + + /* Now copy in the hdr */ + + memcpy(pkt -> data, hdr, sizeof(hdr)); + + /* Get the rest of the packet ... first figure out how big our buf is? */ + /* And make sure that we handle the fragments properly ... Sure should */ + /* use an iovec ... */ + + if (len < pkt_len) /* Only get as much as we have space for */ + more = len - RFCNB_Pkt_Hdr_Len; + else + more = pkt_len; + + this_time = 0; + + /* We read for each fragment ... */ + + if (pkt -> len == read_len) { /* If this frag was exact size */ + pkt_frag = pkt -> next; /* Stick next lot in next frag */ + offset = 0; /* then we start at 0 in next */ + } else { + pkt_frag = pkt; /* Otherwise use rest of this frag */ + offset = RFCNB_Pkt_Hdr_Len; /* Otherwise skip the header */ + } + + frag_len = pkt_frag -> len; + + if (more <= frag_len) /* If len left to get less than frag space */ + this_len = more; /* Get the rest ... */ + else + this_len = frag_len - offset; + + while (more > 0) { + + if ((this_time = read(con -> fd, (pkt_frag -> data) + offset, this_len)) <= 0) { /* Problems */ + + if (errno == EINTR) { + + RFCNB_errno = RFCNB_Timeout; + + } else { + if (this_time < 0) + RFCNB_errno = RFCNBE_BadRead; + else + RFCNB_errno = RFCNBE_ConGone; + } + + RFCNB_saved_errno = errno; + return(RFCNBE_Bad); + + } + +#ifdef RFCNB_DEBUG + fprintf(stderr, "Frag_Len = %i, this_time = %i, this_len = %i, more = %i\n", frag_len, + this_time, this_len, more); +#endif + + read_len = read_len + this_time; /* How much have we read ... */ + + /* Now set up the next part */ + + if (pkt_frag -> next == NULL) break; /* That's it here */ + + pkt_frag = pkt_frag -> next; + this_len = pkt_frag -> len; + offset = 0; + + more = more - this_time; + + } + +#ifdef RFCNB_DEBUG + fprintf(stderr,"Pkt Len = %i, read_len = %i\n", pkt_len, read_len); + RFCNB_Print_Pkt(stderr, "rcvd", pkt, read_len + sizeof(hdr)); +#endif + + if (read_len < (pkt_len + sizeof(hdr))) { /* Discard the rest */ + + return(RFCNB_Discard_Rest(con, (pkt_len + sizeof(hdr)) - read_len)); + + } + + if (RFCNB_Timeout > 0) + alarm(0); /* Reset that sucker */ + + return(read_len + sizeof(RFCNB_Hdr)); +} diff --git a/lib/rfcnb/rfcnb-io.h b/lib/rfcnb/rfcnb-io.h new file mode 100644 index 0000000000..9af8e90cdf --- /dev/null +++ b/lib/rfcnb/rfcnb-io.h @@ -0,0 +1,28 @@ +/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation + + Version 1.0 + RFCNB IO Routines Defines + + 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. +*/ + +int RFCNB_Put_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len); + +int RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len); diff --git a/lib/rfcnb/rfcnb-priv.h b/lib/rfcnb/rfcnb-priv.h new file mode 100644 index 0000000000..ebb78f5836 --- /dev/null +++ b/lib/rfcnb/rfcnb-priv.h @@ -0,0 +1,156 @@ +/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation + + Version 1.0 + RFCNB Defines + + 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. +*/ + +#ifndef _RFCNB_RFCNB_PRIV_H +#define _RFCNB_RFCNB_PRIV_H + +/* Defines we need */ + +typedef unsigned short uint16; + +#define GLOBAL extern + +#include "rfcnb/rfcnb-error.h" +#include "rfcnb/rfcnb-common.h" +#include "rfcnb/byteorder.h" + +#ifdef RFCNB_PORT +#define RFCNB_Default_Port RFCNB_PORT +#else +#define RFCNB_Default_Port 139 +#endif + +#define RFCNB_MAX_STATS 1 + +/* Protocol defines we need */ + +#define RFCNB_SESSION_MESSAGE 0 +#define RFCNB_SESSION_REQUEST 0x81 +#define RFCNB_SESSION_ACK 0x82 +#define RFCNB_SESSION_REJ 0x83 +#define RFCNB_SESSION_RETARGET 0x84 +#define RFCNB_SESSION_KEEP_ALIVE 0x85 + +/* Structures */ + +typedef struct redirect_addr * redirect_ptr; + +struct redirect_addr { + + struct in_addr ip_addr; + int port; + redirect_ptr next; + +}; + +typedef struct RFCNB_Con { + + int fd; /* File descripter for TCP/IP connection */ + int errn; /* last error */ + int timeout; /* How many milli-secs before IO times out */ + int redirects; /* How many times we were redirected */ + struct redirect_addr *redirect_list; /* First is first address */ + struct redirect_addr *last_addr; + +} RFCNB_Con; + +typedef char RFCNB_Hdr[4]; /* The header is 4 bytes long with */ +/* char[0] as the type, char[1] the */ +/* flags, and char[2..3] the length */ + +/* Macros to extract things from the header. These are for portability + between architecture types where we are worried about byte order */ + +#define RFCNB_Pkt_Hdr_Len 4 +#define RFCNB_Pkt_Sess_Len 72 +#define RFCNB_Pkt_Retarg_Len 10 +#define RFCNB_Pkt_Nack_Len 5 +#define RFCNB_Pkt_Type_Offset 0 +#define RFCNB_Pkt_Flags_Offset 1 +#define RFCNB_Pkt_Len_Offset 2 /* Length is 2 bytes plus a flag bit */ +#define RFCNB_Pkt_N1Len_Offset 4 +#define RFCNB_Pkt_Called_Offset 5 +#define RFCNB_Pkt_N2Len_Offset 38 +#define RFCNB_Pkt_Calling_Offset 39 +#define RFCNB_Pkt_Error_Offset 4 +#define RFCNB_Pkt_IP_Offset 4 +#define RFCNB_Pkt_Port_Offset 8 + +/* The next macro isolates the length of a packet, including the bit in the + flags */ + +#define RFCNB_Pkt_Len(p) (PVAL((p), 3) | (PVAL((p), 2) << 8) | \ + ((PVAL((p), RFCNB_Pkt_Flags_Offset) & 0x01) << 16)) + +#define RFCNB_Put_Pkt_Len(p, v) ((p)[1] = (((v) >> 16) & 1)); \ + ((p)[2] = (((v) >> 8) & 0xFF)); \ + ((p)[3] = ((v) & 0xFF)); + +#define RFCNB_Pkt_Type(p) (CVAL((p), RFCNB_Pkt_Type_Offset)) + +/*typedef struct RFCNB_Hdr { + + unsigned char type; + unsigned char flags; + int16 len; + + } RFCNB_Hdr; + +typedef struct RFCNB_Sess_Pkt { + unsigned char type; + unsigned char flags; + int16 length; + unsigned char n1_len; + char called_name[33]; + unsigned char n2_len; + char calling_name[33]; + } RFCNB_Sess_Pkt; + + +typedef struct RFCNB_Nack_Pkt { + + struct RFCNB_Hdr hdr; + unsigned char error; + + } RFCNB_Nack_Pkt; + +typedef struct RFCNB_Retarget_Pkt { + + struct RFCNB_Hdr hdr; + int dest_ip; + unsigned char port; + + } RFCNB_Redir_Pkt; */ + +/* Static variables */ + +/* Only declare this if not defined */ + +#ifndef RFCNB_ERRNO +extern int RFCNB_errno; +extern int RFCNB_saved_errno; /* Save this from point of error */ +#endif + +#endif /* _RFCNB_RFCNB_PRIV_H */ diff --git a/helpers/basic_auth/MSNT/rfcnb-util.c b/lib/rfcnb/rfcnb-util.c similarity index 55% rename from helpers/basic_auth/MSNT/rfcnb-util.c rename to lib/rfcnb/rfcnb-util.c index 9ec8363126..9764f0c6a0 100644 --- a/helpers/basic_auth/MSNT/rfcnb-util.c +++ b/lib/rfcnb/rfcnb-util.c @@ -1,43 +1,47 @@ +#include "config.h" + /* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation - * - * Version 1.0 - * RFCNB Utility Routines ... - * - * Copyright (C) Richard Sharpe 1996 - * - */ + + Version 1.0 + RFCNB Utility 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 "std-includes.h" -#include "rfcnb-priv.h" -#include "rfcnb-util.h" -#include "rfcnb-io.h" - -#include -#include -#include -#include -#include + 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 "rfcnb/rfcnb.h" +#include "rfcnb/std-includes.h" +#include "rfcnb/rfcnb-priv.h" +#include "rfcnb/rfcnb-util.h" +#include "rfcnb/rfcnb-io.h" + +#if HAVE_ARPA_INET_H #include +#endif +#if HAVE_STRING_H #include +#endif -const char *RFCNB_Error_Strings[] = { +extern void (*Prot_Print_Routine)(); /* Pointer to protocol print routine */ +const char *RFCNB_Error_Strings[] = { + "RFCNBE_OK: Routine completed successfully.", "RFCNBE_NoSpace: No space available for a malloc call.", "RFCNBE_BadName: NetBIOS name could not be translated to IP address.", @@ -55,19 +59,15 @@ const char *RFCNB_Error_Strings[] = { "RFCNBE_CallRejUnSpec: Call rejected. Unspecified error.", "RFCNBE_BadParam: Bad parameters passed to a routine.", "RFCNBE_Timeout: IO Operation timed out ..." - -}; - -#ifdef RFCNB_DEBUG -extern void (*Prot_Print_Routine) (); /* Pointer to protocol print routine */ -#endif + +}; /* Convert name and pad to 16 chars as needed */ /* Name 1 is a C string with null termination, name 2 may not be */ /* If SysName is true, then put a <00> on end, else space> */ -void -RFCNB_CvtPad_Name(char *name1, char *name2) +void RFCNB_CvtPad_Name(char *name1, char *name2) + { char c, c1, c2; int i, len; @@ -79,82 +79,81 @@ RFCNB_CvtPad_Name(char *name1, char *name2) if (i >= len) { c1 = 'C'; - c2 = 'A'; /* CA is a space */ + c2 = 'A'; /* CA is a space */ } else { c = name1[i]; - c1 = (char) ((int) c / 16 + (int) 'A'); - c2 = (char) ((int) c % 16 + (int) 'A'); + c1 = (char)((int)c/16 + (int)'A'); + c2 = (char)((int)c%16 + (int)'A'); } - name2[i * 2] = c1; - name2[i * 2 + 1] = c2; + name2[i*2] = c1; + name2[i*2+1] = c2; } - name2[32] = 0; /* Put in the nll ... */ + name2[32] = 0; /* Put in the nll ...*/ } /* Converts an Ascii NB Name (16 chars) to an RFCNB Name (32 chars) - * Uses the encoding in RFC1001. Each nibble of byte is added to 'A' - * to produce the next byte in the name. - * - * This routine assumes that AName is 16 bytes long and that NBName has - * space for 32 chars, so be careful ... - * - */ - -void -RFCNB_AName_To_NBName(char *AName, char *NBName) + Uses the encoding in RFC1001. Each nibble of byte is added to 'A' + to produce the next byte in the name. + + This routine assumes that AName is 16 bytes long and that NBName has + space for 32 chars, so be careful ... + +*/ + +void RFCNB_AName_To_NBName(char *AName, char *NBName) + { char c, c1, c2; int i; - for (i = 0; i < 16; i++) { + for (i=0; i < 16; i++) { c = AName[i]; - c1 = (char) ((c >> 4) + 'A'); - c2 = (char) ((c & 0xF) + 'A'); + c1 = (char)((c >> 4) + 'A'); + c2 = (char)((c & 0xF) + 'A'); - NBName[i * 2] = c1; - NBName[i * 2 + 1] = c2; + NBName[i*2] = c1; + NBName[i*2+1] = c2; } - NBName[32] = 0; /* Put in a null */ + NBName[32] = 0; /* Put in a null */ } /* Do the reverse of the above ... */ -void -RFCNB_NBName_To_AName(char *NBName, char *AName) +void RFCNB_NBName_To_AName(char *NBName, char *AName) + { char c, c1, c2; int i; - for (i = 0; i < 16; i++) { + for (i=0; i < 16; i++) { - c1 = NBName[i * 2]; - c2 = NBName[i * 2 + 1]; + c1 = NBName[i*2]; + c2 = NBName[i*2+1]; - c = (char) (((int) c1 - (int) 'A') * 16 + ((int) c2 - (int) 'A')); + c = (char)(((int)c1 - (int)'A') * 16 + ((int)c2 - (int)'A')); AName[i] = c; } - AName[i] = 0; /* Put a null on the end ... */ + AName[i] = 0; /* Put a null on the end ... */ } -#ifdef RFCNB_DEBUG /* Print a string of bytes in HEX etc */ -void -RFCNB_Print_Hex(FILE * fd, struct RFCNB_Pkt *pkt, int Offset, int Len) +void RFCNB_Print_Hex(FILE *fd, struct RFCNB_Pkt *pkt, int Offset, int Len) + { char c1, c2, outbuf1[33]; unsigned char c; @@ -169,26 +168,27 @@ RFCNB_Print_Hex(FILE * fd, struct RFCNB_Pkt *pkt, int Offset, int Len) while (pkt_ptr != NULL) { for (i = 0; - i < ((Len > (pkt_ptr->len) ? pkt_ptr->len : Len) - Offset); + i < ((Len > (pkt_ptr -> len)?pkt_ptr -> len:Len) - Offset); i++) { - c = pkt_ptr->data[i + Offset]; + c = pkt_ptr -> data[i + Offset]; c1 = Hex_List[c >> 4]; c2 = Hex_List[c & 0xF]; outbuf1[j++] = c1; outbuf1[j++] = c2; - if (j == 32) { /* Print and reset */ + if (j == 32) { /* Print and reset */ outbuf1[j] = 0; fprintf(fd, " %s\n", outbuf1); j = 0; } + } Offset = 0; - Len = Len - pkt_ptr->len; /* Reduce amount by this much */ - pkt_ptr = pkt_ptr->next; + Len = Len - pkt_ptr -> len; /* Reduce amount by this much */ + pkt_ptr = pkt_ptr -> next; } @@ -200,51 +200,60 @@ RFCNB_Print_Hex(FILE * fd, struct RFCNB_Pkt *pkt, int Offset, int Len) fprintf(fd, " %s\n", outbuf1); } + fprintf(fd, "\n"); } -#endif /* Get a packet of size n */ -struct RFCNB_Pkt * -RFCNB_Alloc_Pkt(int n) { +struct RFCNB_Pkt *RFCNB_Alloc_Pkt(int n) + +{ RFCNB_Pkt *pkt; - if ((pkt = malloc(sizeof(struct RFCNB_Pkt))) == NULL) { + if ((pkt = (struct RFCNB_Pkt *)malloc(sizeof(struct RFCNB_Pkt))) == NULL) { + RFCNB_errno = RFCNBE_NoSpace; RFCNB_saved_errno = errno; - return (NULL); + return(NULL); + } - pkt->next = NULL; - pkt->len = n; - if (n == 0) - return (pkt); + pkt -> next = NULL; + pkt -> len = n; + + if (n == 0) return(pkt); + + if ((pkt -> data = (char *)malloc(n)) == NULL) { - if ((pkt->data = malloc(n)) == NULL) { RFCNB_errno = RFCNBE_NoSpace; RFCNB_saved_errno = errno; free(pkt); - return (NULL); + return(NULL); + } - return (pkt); + + return(pkt); } /* Free up a packet */ -void -RFCNB_Free_Pkt(struct RFCNB_Pkt *pkt) +void RFCNB_Free_Pkt(struct RFCNB_Pkt *pkt) + { struct RFCNB_Pkt *pkt_next; + char *data_ptr; while (pkt != NULL) { - pkt_next = pkt->next; + pkt_next = pkt -> next; - if (pkt->data != NULL) - free(pkt->data); + data_ptr = pkt -> data; + + if (data_ptr != NULL) + free(data_ptr); free(pkt); @@ -254,11 +263,10 @@ RFCNB_Free_Pkt(struct RFCNB_Pkt *pkt) } -#ifdef RFCNB_DEBUG /* Print an RFCNB packet */ -void -RFCNB_Print_Pkt(FILE * fd, char *dirn, struct RFCNB_Pkt *pkt, int len) +void RFCNB_Print_Pkt(FILE *fd, char *dirn, struct RFCNB_Pkt *pkt, int len) + { char lname[17]; @@ -267,33 +275,34 @@ RFCNB_Print_Pkt(FILE * fd, char *dirn, struct RFCNB_Pkt *pkt, int len) fprintf(fd, "RFCNB Pkt %s:", dirn); - switch (RFCNB_Pkt_Type(pkt->data)) { + switch (RFCNB_Pkt_Type(pkt -> data)) { case RFCNB_SESSION_MESSAGE: - fprintf(fd, "SESSION MESSAGE: Length = %i\n", RFCNB_Pkt_Len(pkt->data)); + fprintf(fd, "SESSION MESSAGE: Length = %i\n", RFCNB_Pkt_Len(pkt -> data)); RFCNB_Print_Hex(fd, pkt, RFCNB_Pkt_Hdr_Len, #ifdef RFCNB_PRINT_DATA - RFCNB_Pkt_Len(pkt->data) - RFCNB_Pkt_Hdr_Len); + RFCNB_Pkt_Len(pkt -> data) - RFCNB_Pkt_Hdr_Len); #else 40); #endif - if (Prot_Print_Routine != 0) { /* Print the rest of the packet */ + if (Prot_Print_Routine != 0) { /* Print the rest of the packet */ Prot_Print_Routine(fd, strcmp(dirn, "sent"), pkt, RFCNB_Pkt_Hdr_Len, - RFCNB_Pkt_Len(pkt->data) - RFCNB_Pkt_Hdr_Len); + RFCNB_Pkt_Len(pkt -> data) - RFCNB_Pkt_Hdr_Len); } + break; case RFCNB_SESSION_REQUEST: fprintf(fd, "SESSION REQUEST: Length = %i\n", - RFCNB_Pkt_Len(pkt->data)); - RFCNB_NBName_To_AName((char *) (pkt->data + RFCNB_Pkt_Called_Offset), lname); + RFCNB_Pkt_Len(pkt -> data)); + RFCNB_NBName_To_AName((char *)(pkt -> data + RFCNB_Pkt_Called_Offset), lname); fprintf(fd, " Called Name: %s\n", lname); - RFCNB_NBName_To_AName((char *) (pkt->data + RFCNB_Pkt_Calling_Offset), lname); + RFCNB_NBName_To_AName((char *)(pkt -> data + RFCNB_Pkt_Calling_Offset), lname); fprintf(fd, " Calling Name: %s\n", lname); break; @@ -301,18 +310,18 @@ RFCNB_Print_Pkt(FILE * fd, char *dirn, struct RFCNB_Pkt *pkt, int len) case RFCNB_SESSION_ACK: fprintf(fd, "RFCNB SESSION ACK: Length = %i\n", - RFCNB_Pkt_Len(pkt->data)); + RFCNB_Pkt_Len(pkt -> data)); break; case RFCNB_SESSION_REJ: fprintf(fd, "RFCNB SESSION REJECT: Length = %i\n", - RFCNB_Pkt_Len(pkt->data)); + RFCNB_Pkt_Len(pkt -> data)); - if (RFCNB_Pkt_Len(pkt->data) < 1) { + if (RFCNB_Pkt_Len(pkt -> data) < 1) { fprintf(fd, " Protocol Error, short Reject packet!\n"); } else { - fprintf(fd, " Error = %x\n", CVAL(pkt->data, RFCNB_Pkt_Error_Offset)); + fprintf(fd, " Error = %x\n", CVAL(pkt -> data, RFCNB_Pkt_Error_Offset)); } break; @@ -320,7 +329,7 @@ RFCNB_Print_Pkt(FILE * fd, char *dirn, struct RFCNB_Pkt *pkt, int len) case RFCNB_SESSION_RETARGET: fprintf(fd, "RFCNB SESSION RETARGET: Length = %i\n", - RFCNB_Pkt_Len(pkt->data)); + RFCNB_Pkt_Len(pkt -> data)); /* Print out the IP address etc and the port? */ @@ -329,7 +338,7 @@ RFCNB_Print_Pkt(FILE * fd, char *dirn, struct RFCNB_Pkt *pkt, int len) case RFCNB_SESSION_KEEP_ALIVE: fprintf(fd, "RFCNB SESSION KEEP ALIVE: Length = %i\n", - RFCNB_Pkt_Len(pkt->data)); + RFCNB_Pkt_Len(pkt -> data)); break; default: @@ -338,34 +347,38 @@ RFCNB_Print_Pkt(FILE * fd, char *dirn, struct RFCNB_Pkt *pkt, int len) } } -#endif /* Resolve a name into an address */ -int -RFCNB_Name_To_IP(char *host, struct in_addr *Dest_IP) +int RFCNB_Name_To_IP(char *host, struct in_addr *Dest_IP) + { - int addr; /* Assumes IP4, 32 bit network addresses */ + int addr; /* Assumes IP4, 32 bit network addresses */ struct hostent *hp; /* Use inet_addr to try to convert the address */ - if ((addr = inet_addr(host)) == INADDR_NONE) { /* Oh well, a good try :-) */ + if ((addr = inet_addr(host)) == INADDR_NONE) { /* Oh well, a good try :-) */ /* Now try a name look up with gethostbyname */ - if ((hp = gethostbyname(host)) == NULL) { /* Not in DNS */ + if ((hp = gethostbyname(host)) == NULL) { /* Not in DNS */ /* Try NetBIOS name lookup, how the hell do we do that? */ - RFCNB_errno = RFCNBE_BadName; /* Is this right? */ + + RFCNB_errno = RFCNBE_BadName; /* Is this right? */ RFCNB_saved_errno = errno; - return (RFCNBE_Bad); + return(RFCNBE_Bad); } else { /* We got a name */ - Dest_IP->s_addr = (*((struct in_addr*)hp->h_addr_list[0])).s_addr; + + memcpy((void *)Dest_IP, (void *)hp -> h_addr_list[0], sizeof(struct in_addr)); + } } else { /* It was an IP address */ - Dest_IP->s_addr = addr; + + memcpy((void *)Dest_IP, (void *)&addr, sizeof(struct in_addr)); + } return 0; @@ -374,11 +387,11 @@ RFCNB_Name_To_IP(char *host, struct in_addr *Dest_IP) /* Disconnect the TCP connection to the server */ -int -RFCNB_Close(int aSocket) +int RFCNB_Close(int socket) + { - close(aSocket); + close(socket); /* If we want to do error recovery, here is where we put it */ @@ -387,58 +400,61 @@ RFCNB_Close(int aSocket) } /* Connect to the server specified in the IP address. - * Not sure how to handle socket options etc. */ + Not sure how to handle socket options etc. */ + +int RFCNB_IP_Connect(struct in_addr Dest_IP, int port) -int -RFCNB_IP_Connect(struct in_addr Dest_IP, int port) { struct sockaddr_in Socket; int fd; /* Create a socket */ - if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { /* Handle the error */ + if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { /* Handle the error */ RFCNB_errno = RFCNBE_BadSocket; RFCNB_saved_errno = errno; - return (RFCNBE_Bad); + return(RFCNBE_Bad); } - memset((char *) &Socket, 0, sizeof(Socket)); - memcpy((char *) &Socket.sin_addr, (char *) &Dest_IP, sizeof(Dest_IP)); + + bzero((char *)&Socket, sizeof(Socket)); + memcpy((char *)&Socket.sin_addr, (char *)&Dest_IP, sizeof(Dest_IP)); Socket.sin_port = htons(port); Socket.sin_family = PF_INET; /* Now connect to the destination */ - if (connect(fd, (struct sockaddr *) &Socket, sizeof(Socket)) < 0) { /* Error */ + if (connect(fd, (struct sockaddr *)&Socket, sizeof(Socket)) < 0) { /* Error */ close(fd); RFCNB_errno = RFCNBE_ConnectFailed; RFCNB_saved_errno = errno; - return (RFCNBE_Bad); + return(RFCNBE_Bad); } - return (fd); + + return(fd); } /* handle the details of establishing the RFCNB session with remote - * end - * - */ - -int -RFCNB_Session_Req(struct RFCNB_Con *con, - char *Called_Name, - char *Calling_Name, - BOOL * redirect, - struct in_addr *Dest_IP, - int *port) + end + +*/ + +int RFCNB_Session_Req(struct RFCNB_Con *con, + char *Called_Name, + char *Calling_Name, + BOOL *redirect, + struct in_addr *Dest_IP, + int * port) + { char *sess_pkt; /* Response packet should be no more than 9 bytes, make 16 jic */ +// char ln1[16], ln2[16], n1[32], n2[32]; char resp[16]; int len; struct RFCNB_Pkt *pkt, res_pkt; @@ -449,13 +465,14 @@ RFCNB_Session_Req(struct RFCNB_Con *con, if (pkt == NULL) { - return (RFCNBE_Bad); /* Leave the error that RFCNB_Alloc_Pkt gives) */ + return(RFCNBE_Bad); /* Leave the error that RFCNB_Alloc_Pkt gives) */ } - sess_pkt = pkt->data; /* Get pointer to packet proper */ - sess_pkt[RFCNB_Pkt_Type_Offset] = RFCNB_SESSION_REQUEST; - RFCNB_Put_Pkt_Len(sess_pkt, (RFCNB_Pkt_Sess_Len - RFCNB_Pkt_Hdr_Len)); + sess_pkt = pkt -> data; /* Get pointer to packet proper */ + + sess_pkt[RFCNB_Pkt_Type_Offset] = RFCNB_SESSION_REQUEST; + RFCNB_Put_Pkt_Len(sess_pkt, RFCNB_Pkt_Sess_Len-RFCNB_Pkt_Hdr_Len); sess_pkt[RFCNB_Pkt_N1Len_Offset] = 32; sess_pkt[RFCNB_Pkt_N2Len_Offset] = 32; @@ -472,9 +489,10 @@ RFCNB_Session_Req(struct RFCNB_Con *con, if ((len = RFCNB_Put_Pkt(con, pkt, RFCNB_Pkt_Sess_Len)) < 0) { - return (RFCNBE_Bad); /* Should be able to write that lot ... */ + return(RFCNBE_Bad); /* Should be able to write that lot ... */ } + #ifdef RFCNB_DEBUG fprintf(stderr, "Getting packet.\n"); @@ -482,23 +500,24 @@ RFCNB_Session_Req(struct RFCNB_Con *con, #endif res_pkt.data = resp; - res_pkt.len = sizeof(resp); + res_pkt.len = sizeof(resp); res_pkt.next = NULL; if ((len = RFCNB_Get_Pkt(con, &res_pkt, sizeof(resp))) < 0) { - return (RFCNBE_Bad); + return(RFCNBE_Bad); } + /* Now analyze the packet ... */ switch (RFCNB_Pkt_Type(resp)) { - case RFCNB_SESSION_REJ: /* Didnt like us ... too bad */ + case RFCNB_SESSION_REJ: /* Didnt like us ... too bad */ /* Why did we get rejected ? */ - switch (CVAL(resp, RFCNB_Pkt_Error_Offset)) { + switch (CVAL(resp,RFCNB_Pkt_Error_Offset)) { case 0x80: RFCNB_errno = RFCNBE_CallRejNLOCN; @@ -520,28 +539,37 @@ RFCNB_Session_Req(struct RFCNB_Con *con, break; } - return (RFCNBE_Bad); + return(RFCNBE_Bad); break; - case RFCNB_SESSION_ACK: /* Got what we wanted ... */ + case RFCNB_SESSION_ACK: /* Got what we wanted ... */ - return (0); + return(0); break; - case RFCNB_SESSION_RETARGET: /* Go elsewhere */ + case RFCNB_SESSION_RETARGET: /* Go elsewhere */ - *redirect = TRUE; /* Copy port and ip addr */ + *redirect = TRUE; /* Copy port and ip addr */ memcpy(Dest_IP, (resp + RFCNB_Pkt_IP_Offset), sizeof(struct in_addr)); *port = SVAL(resp, RFCNB_Pkt_Port_Offset); - return (0); + return(0); break; - default: /* A protocol error */ + default: /* A protocol error */ RFCNB_errno = RFCNBE_ProtErr; - return (RFCNBE_Bad); + return(RFCNBE_Bad); break; } } + + + + + + + + + diff --git a/lib/rfcnb/rfcnb-util.h b/lib/rfcnb/rfcnb-util.h new file mode 100644 index 0000000000..e977e549fb --- /dev/null +++ b/lib/rfcnb/rfcnb-util.h @@ -0,0 +1,48 @@ +/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation + + Version 1.0 + RFCNB Utility Defines + + 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. +*/ + +void RFCNB_CvtPad_Name(char *name1, char *name2); + +void RFCNB_AName_To_NBName(char *AName, char *NBName); + +void RFCNB_NBName_To_AName(char *NBName, char *AName); + +void RFCNB_Print_Hex(FILE *fd, struct RFCNB_Pkt *pkt, int Offset, int Len); + +void RFCNB_Print_Pkt(FILE *fd, char *dirn, struct RFCNB_Pkt *pkt, int len); + +int RFCNB_Name_To_IP(char *host, struct in_addr *Dest_IP); + +int RFCNB_Close(int socket); + +int RFCNB_IP_Connect(struct in_addr Dest_IP, int port); + +int RFCNB_Session_Req(struct RFCNB_Con *con, + char *Called_Name, + char *Calling_Name, + BOOL *redirect, + struct in_addr *Dest_IP, + int * port); + diff --git a/lib/rfcnb/rfcnb.h b/lib/rfcnb/rfcnb.h new file mode 100644 index 0000000000..0d789edf41 --- /dev/null +++ b/lib/rfcnb/rfcnb.h @@ -0,0 +1,70 @@ +/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation + + Version 1.0 + RFCNB Defines + + 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. +*/ + +#ifndef _RFCNB_RFCNB_H +#define _RFCNB_RFCNB_H + +/* Error responses */ + +#include "rfcnb/rfcnb-error.h" +#include "rfcnb/rfcnb-common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Defines we need */ + +#define RFCNB_Default_Port 139 + +struct RFCNB_Con; + +/* Definition of routines we define */ + +void *RFCNB_Call(char *Called_Name, char *Calling_Name, char *Called_Address, + int port); + +int RFCNB_Send(struct RFCNB_Con *Con_Handle, struct RFCNB_Pkt *udata, int Length); + +int RFCNB_Recv(void *Con_Handle, struct RFCNB_Pkt *Data, int Length); + +int RFCNB_Hangup(struct RFCNB_Con *con_Handle); + +void *RFCNB_Listen(); + +void RFCNB_Get_Error(char *buffer, int buf_len); + +int RFCNB_Get_Last_Error(void); + +void RFCNB_Free_Pkt(struct RFCNB_Pkt *pkt); + +int RFCNB_Set_Sock_NoDelay(struct RFCNB_Con *con_Handle, int yn); + +struct RFCNB_Pkt *RFCNB_Alloc_Pkt(int n); + +#ifdef __cplusplus +} +#endif +#endif /* _RFCNB_RFCNB_H */ diff --git a/lib/rfcnb/session.c b/lib/rfcnb/session.c new file mode 100644 index 0000000000..f723cf894f --- /dev/null +++ b/lib/rfcnb/session.c @@ -0,0 +1,386 @@ +#include "config.h" + +/* 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. +*/ + +int RFCNB_errno = 0; +int RFCNB_saved_errno = 0; +#define RFCNB_ERRNO + +#include "rfcnb/std-includes.h" +#include +#include "rfcnb/rfcnb.h" +#include "rfcnb/rfcnb-priv.h" +#include "rfcnb/rfcnb-io.h" +#include "rfcnb/rfcnb-util.h" + +#if HAVE_STRING_H +#include +#endif + +int RFCNB_Stats[RFCNB_MAX_STATS]; + +void (*Prot_Print_Routine)() = NULL; /* Pointer to print routine */ + +int RFCNB_Get_Last_Errno(void); +int RFCNB_Get_Error_Msg(int code, char *msg_buf, int len); +void RFCNB_Register_Print_Routine(void (*fn)()); + +/* 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 ... +*/ + +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 -> errn = 0; /* no error yet */ + con -> timeout = 0; /* no timeout */ + con -> redirects = 0; + + /* Resolve that name into an IP address */ + + Service_Address = Called_Name; + if (strcmp(Called_Address, "") != 0) { /* If the Called Address = "" */ + 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 */ + free(con); + 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; + free(con); + 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 */ + free(con); + 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.. */ + + RFCNB_Close(con->fd); /* Close it */ + free(con); + 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 ... */ + +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 ... */ + +int RFCNB_Recv(void *con_Handle, struct RFCNB_Pkt *Data, int Length) + +{ + struct RFCNB_Pkt *pkt; +// struct RFCNB_Hdr *hdr; + 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 */ + +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; + + +} + +/* Set TCP_NODELAY on the socket */ + +int RFCNB_Set_Sock_NoDelay(struct RFCNB_Con *con_Handle, BOOL yn) + +{ + + return(setsockopt(con_Handle -> fd, IPPROTO_TCP, TCP_NODELAY, + (char *)&yn, sizeof(yn))); + +} + +#if NOT_IMPLEMENTED + +/* Listen for a connection on a port???, when */ +/* the connection comes in, we return with the connection */ + +void *RFCNB_Listen() + +{ + +} +#endif + +/* Pick up the last error response as a string, hmmm, this routine should */ +/* have been different ... */ + +void RFCNB_Get_Error(char *buffer, int buf_len) + +{ + + if (RFCNB_saved_errno <= 0) { + snprintf(buffer, (buf_len-1) ,"%s", RFCNB_Error_Strings[RFCNB_errno]); + } else { + snprintf(buffer, (buf_len-1), "%s\n\terrno:%s", RFCNB_Error_Strings[RFCNB_errno], + strerror(RFCNB_saved_errno)); + } + +} + +/* Pick up the last error response and returns as a code */ + +int RFCNB_Get_Last_Error() + +{ + + return(RFCNB_errno); + +} + +/* Pick up saved errno as well */ + +int RFCNB_Get_Last_Errno() + +{ + + return(RFCNB_saved_errno); + +} + +/* Pick up the last error response and return in string ... */ + +int RFCNB_Get_Error_Msg(int code, char *msg_buf, int len) + +{ + + return (strncpy(msg_buf, RFCNB_Error_Strings[abs(code)], len) != NULL); + +} + +/* Register a higher level protocol print routine */ + +void RFCNB_Register_Print_Routine(void (*fn)()) + +{ + + Prot_Print_Routine = fn; + +} diff --git a/lib/rfcnb/std-includes.h b/lib/rfcnb/std-includes.h new file mode 100644 index 0000000000..e52bd40874 --- /dev/null +++ b/lib/rfcnb/std-includes.h @@ -0,0 +1,50 @@ +/* RFCNB Standard includes ... */ +/* + + RFCNB Standard Includes + + Copyright (C) 1996, Richard Sharpe +*/ + +/* One day we will conditionalize these on OS types ... */ + +/* + 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. +*/ +#ifndef _RFCNB_STD_INCLUDES_H +#define _RFCNB_STD_INCLUDES_H + +#define BOOL int +typedef short int16; + +#include +#include +#include +#include +#include +#include +#include +#include + +#define TRUE 1 +#define FALSE 0 + +/* Pick up define for INADDR_NONE */ + +#ifndef INADDR_NONE +#define INADDR_NONE -1 +#endif + +#endif /* _RFCNB_STD_INCLUDES_H */ diff --git a/lib/smblib/Changes b/lib/smblib/Changes new file mode 100644 index 0000000000..a2c9dcef4d --- /dev/null +++ b/lib/smblib/Changes @@ -0,0 +1,19 @@ +Change Log. + +Oct 2010 - Imported into Squid. + Many build fixes for modern compilers. + Shuffled several private functions (error display and logon) to + to public API file for external use without using smblib-priv.h. + Patched to permit pre-encrypted password blobs. + Patched to pass-thru of unicode binary blobs (logon). + Patched to permit selective domain logon. + +Aug 96 - Fixed problems with test_perf using strcpy and strcat while passing + arguments for strncpy and strncat + +Aug 96 - Moved to gcc as compiler in Makefile + +Aug 96 - Fixed the macro that handes Error code extraction and added Invalid + API and Password has expired to the error messages + +Aug 96 - Added first API call, SetUserPassword diff --git a/lib/smblib/Makefile.am b/lib/smblib/Makefile.am new file mode 100644 index 0000000000..50c3618e06 --- /dev/null +++ b/lib/smblib/Makefile.am @@ -0,0 +1,19 @@ +include $(top_srcdir)/src/Common.am + +INCLUDES += -I$(top_srcdir)/lib + +noinst_LTLIBRARIES = libsmblib.la + +libsmblib_la_SOURCES = \ + md4.c \ + md4.h \ + smblib.c \ + smblib.h \ + smblib-common.h \ + smblib-priv.h \ + smblib-util.c \ + smbencrypt.c \ + smbencrypt.h \ + smbdes.c \ + smbdes.h \ + std-defines.h diff --git a/lib/smblib/ReadMe.1st b/lib/smblib/ReadMe.1st new file mode 100644 index 0000000000..6c879f525f --- /dev/null +++ b/lib/smblib/ReadMe.1st @@ -0,0 +1,85 @@ +SMBlib 0.20 +Richard Sharpe +Digital Equipment Corporation + +This is a first attempt at an SMBlibrary, and is incomplete. + +I wrote it in an attempt to understand more about the SMB protocol and +the RFCNB (NBT) protocol underlying it. My manager approved my posting this +as long as there was no suggestion that Digital is responsible for this code +not that any warranties are offered by Digital. So, I put a GPL on the code. + +DISCLAIMER + +To restate, this code is offered as is, and no warranties are implied, either +by Digital Equipment Corporation or by Richard Sharpe. Neither +Digital Equipment Corporation nor Richard Sharpe can be held liable for +any consequences resulting from the use of this code. + +END Disclaimer + +At the moment, it can connect to Windows NT servers, Windows 95 servers, +PATHWORKS 4 VMS and PATHWORKS 4 Ultrix servers, as well as Samba. + +It can Connect, Negotiate a protocol, logon to a Samba Server, Logon to +Windows NT, Logon to LAN Manager 2.2 (for UNIX) server, connect to a tree, +open a file, create a file, read a file, write a file, delete a file, +close a file, disconnect a tree connection, create a directory, delete a +directory, check a directory. +This represents about 75% of the core protocol. + +It has a number of deficiencies: + +a. It does not do any more than the Core Protocol (except for logon). + +b. Because of the structure of the code, it is not going to be easy to use + the And_X commands properly. + +c. It will not be easy to use OPLOCKS (if I understand them well) as they + will result in unsolicited SMBs from the server to break locks. + +d. It does not check that SMBs received are in response to SMBs sent. This + is a lack of defensive programming. + +e. It is not thread safe. + +It is offered as an example for those who might want to take things +further. I am unhappy about the way that some things have panned out, +and may tinker with this some more over time. I am also happy to answer +questions, time permitting. + +The files here are: + +Makefile: a small makefile to build things in this dir ... + +smblib.h: include file of interface routines for SMBlib + +smblib-priv.h: include file of internal stuff to SMBlib + +std-defines.h: some standard defines I needed. + +smblib.c: the beginnings of routines that connect and logon + +file.c: the beginings of routines that do SMB file ops + +smblib-util.c: utility routines for SMBlib + +test_smblib.c: a small test program + +test_perf.c: the beginings of a performance test routine ... + +usage.txt: some documentation on using all the routines ... + +Testing: + +This has been compiled and tested on ULTRIX and Digital UNIX, and some +testing has been done on Linux, but I have not tested it on any other +versions of UNIX. + +Regards +Richard Sharpe +sharpe@nmesis.enet.dec.com + + + + diff --git a/lib/smblib/bad-chain.c b/lib/smblib/bad-chain.c new file mode 100644 index 0000000000..56f6ec2983 --- /dev/null +++ b/lib/smblib/bad-chain.c @@ -0,0 +1,284 @@ +/* UNIX SMBlib NetBIOS implementation + + Version 1.0 + SMBlib Routines. Experimental Section ... + + 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 "smblib-priv.h" + +#include "../rfcnb/rfcnb.h" + +#include + + +/* Logon and tree connect to the server */ + +int SMB_Logon_And_TCon(SMB_Handle_Type Con_Handle, char *UserName, + char *PassWord, + char *service, + char *service_type) + +{ + struct RFCNB_Pkt *pkt; + int param_len, i, pkt_len, andx_len, andx_param_len; + char *p, *AndXCom; + + /* First we need a packet etc ... but we need to know what protocol has */ + /* been negotiated to figure out if we can do it and what SMB format to */ + /* use ... */ + + /* Since we are going to do a LogonAndX with a TCon as the second command*/ + /* We need the packet size correct. So TCon starts at wct field */ + + if (SMB_Types[Con_Handle -> protocol] < SMB_P_LanMan1) { + + SMBlib_errno = SMBlibE_ProtLow; + return(SMBlibE_BAD); + + } + + /* Now build the correct structure */ + + if (SMB_Types[Con_Handle -> protocol] < SMB_P_NT1) { + + param_len = strlen(UserName) + 1 + strlen(PassWord) + + strlen(Con_Handle -> PDomain) + 1 + + strlen(Con_Handle -> OSName) + 1; + + pkt_len = SMB_ssetpLM_len + param_len; + + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); + + if (pkt == NULL) { + + SMBlib_errno = SMBlibE_NoSpace; + return(SMBlibE_BAD); /* Should handle the error */ + + } + + bzero(SMB_Hdr(pkt), SMB_ssetpLM_len); + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX; + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid); + *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 10; + *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF; /* No extra command */ + SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0); + + SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mbs_offset, SMBLIB_MAX_XMIT); + SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mmc_offset, 2); + SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_vcn_offset, Con_Handle -> pid); + SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_snk_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_pwl_offset, strlen(PassWord)); + SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_res_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_bcc_offset, param_len); + + /* Now copy the param strings in with the right stuff */ + + p = (char *)(SMB_Hdr(pkt) + SMB_ssetpLM_buf_offset); + + /* Copy in password, then the rest. Password has no null at end */ + + strcpy(p, PassWord); + + p = p + strlen(PassWord); + + strcpy(p, UserName); + p = p + strlen(UserName); + *p = 0; + + p = p + 1; + + strcpy(p, Con_Handle -> PDomain); + p = p + strlen(Con_Handle -> PDomain); + *p = 0; + p = p + 1; + + strcpy(p, Con_Handle -> OSName); + p = p + strlen(Con_Handle -> OSName); + *p = 0; + + } else { + + /* We don't admit to UNICODE support ... */ + + param_len = strlen(UserName) + 1 + strlen(PassWord) + + strlen(Con_Handle -> PDomain) + 1 + + strlen(Con_Handle -> OSName) + 1; + + andx_len = SMB_tcon_len - SMB_hdr_wct_offset; + + /* We send a null password as we sent one in the setup and X */ + + andx_param_len = strlen(service) + 2 + 2 + strlen(service_type) + 2; + + pkt_len = SMB_ssetpNTLM_len + param_len + andx_len + andx_param_len; + + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); + + if (pkt == NULL) { + + SMBlib_errno = SMBlibE_NoSpace; + return(-1); /* Should handle the error */ + + } + + bzero(SMB_Hdr(pkt), SMB_ssetpNTLM_len); + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX; + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid); + *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 13; + *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = SMBtcon; + SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, SMB_ssetpNTLM_len + param_len); + + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mbs_offset, SMBLIB_MAX_XMIT); + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mmc_offset, 2); + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_vcn_offset, 0); + SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_snk_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cipl_offset, strlen(PassWord)); + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cspl_offset, 0); + SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_res_offset, 0); + SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cap_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_bcc_offset, param_len); + + /* Now copy the param strings in with the right stuff */ + + p = (char *)(SMB_Hdr(pkt) + SMB_ssetpNTLM_buf_offset); + + /* Copy in password, then the rest. Password has no null at end */ + + strcpy(p, PassWord); + + p = p + strlen(PassWord); + + strcpy(p, UserName); + p = p + strlen(UserName); + *p = 0; + + p = p + 1; + + strcpy(p, Con_Handle -> PDomain); + p = p + strlen(Con_Handle -> PDomain); + *p = 0; + p = p + 1; + + strcpy(p, Con_Handle -> OSName); + p = p + strlen(Con_Handle -> OSName); + *p = 0; + + /* Now set up the TCON Part ... from WCT, make up a pointer that will + help us ... */ + + AndXCom = SMB_Hdr(pkt) + SMB_ssetpNTLM_len + param_len - SMB_hdr_wct_offset; + + *(AndXCom + SMB_hdr_wct_offset) = 0; /* No Words */ + + SSVAL(AndXCom, SMB_tcon_bcc_offset, andx_param_len); + + p = (char *)(AndXCom + SMB_tcon_buf_offset); + + *p = SMBasciiID; + strcpy(p + 1, service); + p = p + strlen(service) + 2; + *p = SMBasciiID; /* No password ... */ + *(p + 1) = 0; + p = p + 2; + *p = SMBasciiID; + strcpy(p + 1, service_type); + + } + + /* Now send it and get a response */ + + if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error sending SessSetupAndTCon request\n"); +#endif + + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_SendFailed; + return(SMBlibE_BAD); + + } + + /* Now get the response ... */ + + if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error receiving response to SessSetupAndTCon\n"); +#endif + + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_RecvFailed; + return(SMBlibE_BAD); + + } + + /* Check out the response type ... */ + + if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ + +#ifdef DEBUG + fprintf(stderr, "SMB_SessSetupAndTCon failed with errorclass = %i, Error Code = %i\n", + CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), + SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); +#endif + + /* Note, here, that we have not properly handled the error processing */ + /* and so we cannot tell how much of our request crapped out */ + + SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_Remote; + return(SMBlibE_BAD); + + } + +#ifdef DEBUG + fprintf(stderr, "SessSetupAndX response. Action = %i\n", + SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset)); +#endif + + /* Now pick up the UID for future reference ... */ + + Con_Handle -> uid = SVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset); + + /* And pick up the TID as well, which will be at offset 4? from wct */ + + AndXCom = (char *)SMB_Hdr(pkt) + SVAL(SMB_Hdr(pkt), SMB_ssetpr_axo_offset); + + Con_Handle -> tid = SVAL(AndXCom, 3); /* Naughty */ + Con_Handle -> max_xmit = SVAL(AndXCom, 1); /* And Again */ + + RFCNB_Free_Pkt(pkt); + + return(0); + +} + diff --git a/lib/smblib/exper.c b/lib/smblib/exper.c new file mode 100644 index 0000000000..b85f85a320 --- /dev/null +++ b/lib/smblib/exper.c @@ -0,0 +1,743 @@ +/* UNIX SMBlib NetBIOS implementation + + Version 1.0 + SMBlib Routines. Experimental Section ... + + 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 "smblib-priv.h" + +#include "../rfcnb/rfcnb.h" + +#include + + +/* Logon and tree connect to the server. If a tree handle was given to us, */ +/* we use it and return it, otherwise we create one ... */ + +SMB_Tree_Handle SMB_Logon_And_TCon(SMB_Handle_Type Con_Handle, + SMB_Tree_Handle Tree_Handle, + char *UserName, + char *PassWord, + char *service, + char *service_type) + +{ + struct RFCNB_Pkt *pkt; + int param_len, i, pkt_len, andx_len, andx_param_len; + char *p, *AndXCom; + SMB_Tree_Handle tree; + + /* Lets create a tree if we need one ... */ + + if (Tree_Handle == NULL) { + + tree = (SMB_Tree_Handle)malloc(sizeof(struct SMB_Tree_Structure)); + + if (tree == NULL) { + + SMBlib_errno = SMBlibE_NoSpace; + return(tree); + + } else { /* Initialize the tree */ + + tree -> con = Con_Handle; + tree -> prev = tree -> next = NULL; + + } + } else + tree = Tree_Handle; + + /* First we need a packet etc ... but we need to know what protocol has */ + /* been negotiated to figure out if we can do it and what SMB format to */ + /* use ... */ + + /* Since we are going to do a LogonAndX with a TCon as the second command*/ + /* We need the packet size correct. So TCon starts at wct field */ + + if (Con_Handle -> protocol < SMB_P_LanMan1) { + + SMBlib_errno = SMBlibE_ProtLow; + if (Tree_Handle == NULL) + free(tree); + return(NULL); + + } + + /* Now build the correct structure */ + + andx_len = SMB_tconx_len - SMB_hdr_wct_offset; + + /* We send a null password as we sent one in the setup and X */ + + andx_param_len = strlen(service) + 1 + strlen(service_type) + 1; + + if (Con_Handle -> protocol < SMB_P_NT1) { + +#ifdef SMBLIB_DEBUG + fprintf(stderr, "Doing an LM session setup etc ...\n"); +#endif + + /* We don't do encrypted passwords ... */ + + param_len = strlen(UserName) + 1 + strlen(PassWord) + 1 + + strlen(Con_Handle -> PDomain) + 1 + + strlen(Con_Handle -> OSName) + 1; + + pkt_len = SMB_ssetpLM_len + param_len + andx_len + andx_param_len; + + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); + + if (pkt == NULL) { + + SMBlib_errno = SMBlibE_NoSpace; + if (Tree_Handle == NULL) + free(tree); + return(NULL); /* Should handle the error */ + + } + + bzero(SMB_Hdr(pkt), SMB_ssetpLM_len); + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX; + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, 0); + *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 10; + *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = SMBtconX; + SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, SMB_ssetpLM_len + param_len); + + SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mbs_offset, SMBLIB_MAX_XMIT); + SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mmc_offset, 2); + SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_vcn_offset, Con_Handle -> pid); + SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_snk_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_pwl_offset, strlen(PassWord) + 1); + SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_res_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_bcc_offset, param_len); + + /* Now copy the param strings in with the right stuff */ + + p = (char *)(SMB_Hdr(pkt) + SMB_ssetpLM_buf_offset); + + /* Copy in password, then the rest. Password has no null at end */ + + strcpy(p, PassWord); + + p = p + strlen(PassWord) + 1; + + strcpy(p, UserName); + p = p + strlen(UserName); + *p = 0; + + p = p + 1; + + strcpy(p, Con_Handle -> PDomain); + p = p + strlen(Con_Handle -> PDomain); + *p = 0; + p = p + 1; + + strcpy(p, Con_Handle -> OSName); + p = p + strlen(Con_Handle -> OSName); + *p = 0; + + AndXCom = SMB_Hdr(pkt) + SMB_ssetpLM_len + param_len - SMB_hdr_wct_offset; + + } else { + + /* We don't admit to UNICODE support ... */ + +#ifdef SMBLIB_DEBUG + fprintf(stderr, "Doing NT LM Sess Setup etc ... \n"); +#endif + + param_len = strlen(UserName) + 1 + strlen(PassWord) + + strlen(Con_Handle -> PDomain) + 1 + + strlen(Con_Handle -> OSName) + 1 + + strlen(Con_Handle -> LMType) + 1; + + pkt_len = SMB_ssetpNTLM_len + param_len + andx_len + andx_param_len; + + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); + + if (pkt == NULL) { + + SMBlib_errno = SMBlibE_NoSpace; + if (Tree_Handle == NULL) + free(tree); + return(NULL); /* Should handle the error */ + + } + + bzero(SMB_Hdr(pkt), SMB_ssetpNTLM_len); + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX; + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, 0); + *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 13; + *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = SMBtconX; + SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, SMB_ssetpNTLM_len + param_len); + + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mbs_offset, SMBLIB_MAX_XMIT); + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mmc_offset, 2); + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_vcn_offset, 0); + SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_snk_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cipl_offset, strlen(PassWord)); + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cspl_offset, 0); + SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_res_offset, 0); + SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cap_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_bcc_offset, param_len); + + /* Now copy the param strings in with the right stuff */ + + p = (char *)(SMB_Hdr(pkt) + SMB_ssetpNTLM_buf_offset); + + /* Copy in password, then the rest. Password has no null at end */ + + strcpy(p, PassWord); + + p = p + strlen(PassWord); + + strcpy(p, UserName); + p = p + strlen(UserName); + *p = 0; + + p = p + 1; + + strcpy(p, Con_Handle -> PDomain); + p = p + strlen(Con_Handle -> PDomain); + *p = 0; + p = p + 1; + + strcpy(p, Con_Handle -> OSName); + p = p + strlen(Con_Handle -> OSName); + *p = 0; + p = p + 1; + + strcpy(p, Con_Handle -> LMType); + p = p + strlen(Con_Handle -> LMType); + *p = 0; + + /* Now set up the TCON Part ... from WCT, make up a pointer that will + help us ... */ + + AndXCom = SMB_Hdr(pkt) + SMB_ssetpNTLM_len + param_len - SMB_hdr_wct_offset; + + } + *(AndXCom + SMB_hdr_wct_offset) = 4; + *(AndXCom + SMB_tconx_axc_offset) = 0xFF; /* No command */ + SSVAL(AndXCom, SMB_tconx_axo_offset, 0); + SSVAL(AndXCom, SMB_tconx_flg_offset, 0); /* Don't disconnect TID */ + SSVAL(AndXCom, SMB_tconx_pwl_offset, 0); /* No password, */ + SSVAL(AndXCom, SMB_tconx_bcc_offset, andx_param_len); + + p = (char *)(AndXCom + SMB_tconx_buf_offset); + + /**p = 0; + p = p + 1; */ + strcpy(p, service); + p = p + strlen(service) + 1; + strcpy(p, service_type); + + /* Now send it and get a response */ + + if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error sending SessSetupAndTCon request\n"); +#endif + + RFCNB_Free_Pkt(pkt); + free(tree); + SMBlib_errno = SMBlibE_SendFailed; + return(NULL); + + } + + /* Now get the response ... */ + + if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error receiving response to SessSetupAndTCon\n"); +#endif + + RFCNB_Free_Pkt(pkt); + free(tree); + SMBlib_errno = SMBlibE_RecvFailed; + return(NULL); + + } + + /* Check out the response type ... */ + + if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ + +#ifdef DEBUG + fprintf(stderr, "SMB_SessSetupAndTCon failed with errorclass = %i, Error Code = %i\n", + CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), + SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); +#endif + + /* Note, here, that we have not properly handled the error processing */ + /* and so we cannot tell how much of our request crapped out */ + + SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); + free(tree); + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_Remote; + return(NULL); + + } + +#ifdef DEBUG + fprintf(stderr, "SessSetupAndX response. Action = %i\n", + SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset)); +#endif + + /* Now pick up the UID for future reference ... */ + + Con_Handle -> uid = SVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset); + + /* And pick up the TID as well */ + + tree -> tid = SVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset); + + tree -> mbs = Con_Handle -> max_xmit; + + /* Link the tree into the list in con */ + + if (Con_Handle -> first_tree == NULL) { + + Con_Handle -> first_tree == tree; + Con_Handle -> last_tree == tree; + + } else { + + Con_Handle -> last_tree -> next = tree; + tree -> prev = Con_Handle -> last_tree; + Con_Handle -> last_tree = tree; + + } + + RFCNB_Free_Pkt(pkt); + + return(tree); + +} + +/* Logon and TCon and Open to a file on the server, but we need to pass */ +/* back a file pointer, so we better have one in the parameter list */ + +int SMB_Logon_TCon_Open(SMB_Handle_Type Con_Handle, char *UserName, + char *PassWord, + char *service, + char *service_type, + SMB_Tree_Handle *Tree_Handle, + char *filename, + WORD mode, + WORD search, + SMB_File **File_Handle) + +{ + struct RFCNB_Pkt *pkt; + int param_len, i, pkt_len, tcon_len, tcon_param_len, open_len, + open_param_len, header_len; + struct SMB_File_Def *file_tmp; + SMB_Tree_Handle tree; + char *p, *AndXCom; + + /* First, we need a tree STRUCTURE as we are going to tree connect */ + + tree = (SMB_Tree_Handle)malloc(sizeof(struct SMB_Tree_Structure)); + + if (tree == NULL) { + + SMBlib_errno = SMBlibE_NoSpace; + return(SMBlibE_BAD); + + } else { + + tree -> con = Con_Handle; + tree -> next = tree -> prev = NULL; + + } + + /* Next, we need a file handle as we are going to pass one back ... */ + /* Hmm, there is a bug here ... We should check on File_Handle ... */ + + if ((file_tmp = (SMB_File *)malloc(sizeof(SMB_File))) == NULL) { + +#ifdef DEBUG + fprintf(stderr, "Could not allocate file handle space ..."); +#endif + + SMBlib_errno = SMBlibE_NoSpace; + free(tree); + return(SMBlibE_BAD); + + } + + /* Next we need a packet etc ... but we need to know what protocol has */ + /* been negotiated to figure out if we can do it and what SMB format to */ + /* use ... */ + + /* Since we are going to do a LogonAndX with a TCon as the second command*/ + /* We need the packet size correct. So TCon starts at wct field */ + + if (Con_Handle -> protocol < SMB_P_LanMan1) { + + free(tree); + free(file_tmp); + SMBlib_errno = SMBlibE_ProtLow; + return(SMBlibE_BAD); + + } + + /* Now build the correct structure */ + + /* We send a null password in the TconAndX ... */ + + tcon_len = SMB_tconx_len - SMB_hdr_wct_offset; + tcon_param_len = strlen(service) + 1 + strlen(service_type) + 1; + + open_len = SMB_openx_len - SMB_hdr_wct_offset; + open_param_len = 1 + strlen(filename) + 1; /* AsciiID + null */ + + if (Con_Handle -> protocol < SMB_P_NT1) { + + /* We don't do encrypted passwords yet */ + + param_len = strlen(UserName) + 1 + strlen(PassWord) + 1 + + strlen(Con_Handle -> PDomain) + 1 + + strlen(Con_Handle -> OSName) + 1; + + header_len = SMB_ssetpLM_len + param_len; + + pkt_len = header_len + tcon_len + tcon_param_len + + open_len + open_param_len; + + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); + + if (pkt == NULL) { + + SMBlib_errno = SMBlibE_NoSpace; + free(tree); + free(file_tmp); + return(SMBlibE_BAD); /* Should handle the error */ + + } + + bzero(SMB_Hdr(pkt), SMB_ssetpLM_len); + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX; + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, 0); + *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 10; + *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = SMBtconX; + SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, SMB_ssetpLM_len + param_len); + + SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mbs_offset, SMBLIB_MAX_XMIT); + SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mmc_offset, 2); + SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_vcn_offset, Con_Handle -> pid); + SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_snk_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_pwl_offset, strlen(PassWord) + 1); + SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_res_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_bcc_offset, param_len); + + /* Now copy the param strings in with the right stuff */ + + p = (char *)(SMB_Hdr(pkt) + SMB_ssetpLM_buf_offset); + + /* Copy in password, then the rest. Password has no null at end */ + + strcpy(p, PassWord); + + p = p + strlen(PassWord) + 1; + + strcpy(p, UserName); + p = p + strlen(UserName); + *p = 0; + + p = p + 1; + + strcpy(p, Con_Handle -> PDomain); + p = p + strlen(Con_Handle -> PDomain); + *p = 0; + p = p + 1; + + strcpy(p, Con_Handle -> OSName); + p = p + strlen(Con_Handle -> OSName); + *p = 0; + + AndXCom = SMB_Hdr(pkt) + SMB_ssetpLM_len + param_len - SMB_hdr_wct_offset; + + } else { + + /* We don't admit to UNICODE support ... */ + + param_len = strlen(UserName) + 1 + strlen(PassWord) + + strlen(Con_Handle -> PDomain) + 1 + + strlen(Con_Handle -> OSName) + 1 + + strlen(Con_Handle -> LMType) + 1; + + header_len = SMB_ssetpNTLM_len + param_len; + + pkt_len = header_len + tcon_len + tcon_param_len + + open_len + open_param_len; + + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); + + if (pkt == NULL) { + + SMBlib_errno = SMBlibE_NoSpace; + free(tree); + free(file_tmp); /* Should only do if we created one ... */ + return(-1); /* Should handle the error */ + + } + + bzero(SMB_Hdr(pkt), SMB_ssetpNTLM_len); + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX; + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, 0); + *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 13; + *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = SMBtconX; + SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, SMB_ssetpNTLM_len + param_len); + + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mbs_offset, SMBLIB_MAX_XMIT); + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mmc_offset, 2); + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_vcn_offset, 0); + SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_snk_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cipl_offset, strlen(PassWord)); + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cspl_offset, 0); + SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_res_offset, 0); + SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cap_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_bcc_offset, param_len); + + /* Now copy the param strings in with the right stuff */ + + p = (char *)(SMB_Hdr(pkt) + SMB_ssetpNTLM_buf_offset); + + /* Copy in password, then the rest. Password has no null at end */ + + strcpy(p, PassWord); + + p = p + strlen(PassWord); + + strcpy(p, UserName); + p = p + strlen(UserName); + *p = 0; + + p = p + 1; + + strcpy(p, Con_Handle -> PDomain); + p = p + strlen(Con_Handle -> PDomain); + *p = 0; + p = p + 1; + + strcpy(p, Con_Handle -> OSName); + p = p + strlen(Con_Handle -> OSName); + *p = 0; + p = p + 1; + + strcpy(p, Con_Handle -> LMType); + p = p + strlen(Con_Handle -> LMType); + *p = 0; + + /* Now set up the TCON Part ... from WCT, make up a pointer that will + help us ... */ + + AndXCom = SMB_Hdr(pkt) + SMB_ssetpNTLM_len + param_len - SMB_hdr_wct_offset; + + } + + *(AndXCom + SMB_hdr_wct_offset) = 4; + *(AndXCom + SMB_tconx_axc_offset) = SMBopenX; + SSVAL(AndXCom, SMB_tconx_axo_offset, (header_len + + tcon_len + tcon_param_len)); + SSVAL(AndXCom, SMB_tconx_flg_offset, 0); /* Don't disconnect TID */ + SSVAL(AndXCom, SMB_tconx_pwl_offset, 0); /* No password */ + SSVAL(AndXCom, SMB_tconx_bcc_offset, tcon_param_len); + + p = (char *)(AndXCom + SMB_tconx_buf_offset); + + /* *p = 0; + p = p + 1; */ + strcpy(p, service); + p = p + strlen(service) + 1; + strcpy(p, service_type); + + /* Now the open bit ... */ + + AndXCom = AndXCom + tcon_len + tcon_param_len; /* Should get us there */ + + *(AndXCom + SMB_hdr_wct_offset) = 15; + *(AndXCom + SMB_openx_axc_offset) = 0xFF; + *(AndXCom + SMB_openx_axr_offset) = 0; + SSVAL(AndXCom, SMB_openx_axo_offset, 0); + SSVAL(AndXCom, SMB_openx_flg_offset, 0); + SSVAL(AndXCom, SMB_openx_mod_offset, mode); + SSVAL(AndXCom, SMB_openx_atr_offset, search); + SSVAL(AndXCom, SMB_openx_fat_offset, 0); + SIVAL(AndXCom, SMB_openx_tim_offset, 0); + SSVAL(AndXCom, SMB_openx_ofn_offset, 0x0011); /* Create or open */ + SIVAL(AndXCom, SMB_openx_als_offset, 0); + SSVAL(AndXCom, SMB_openx_bcc_offset, open_param_len); + + p = (char *)(AndXCom + SMB_openx_buf_offset); + + /* *p = SMBasciiID; */ + strcpy(p, filename); + + /* Now send it and get a response */ + + if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error sending SessSetupAndTCon request\n"); +#endif + + RFCNB_Free_Pkt(pkt); + free(tree); + free(file_tmp); + SMBlib_errno = SMBlibE_SendFailed; + return(SMBlibE_BAD); + + } + + /* Now get the response ... */ + + if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error receiving response to SessSetupAndTCon\n"); +#endif + + RFCNB_Free_Pkt(pkt); + free(tree); + free(file_tmp); + SMBlib_errno = SMBlibE_RecvFailed; + return(SMBlibE_BAD); + + } + + /* Check out the response type ... */ + + if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ + +#ifdef DEBUG + fprintf(stderr, "SMB_SessSetupAndTCon failed with errorclass = %i, Error Code = %i\n", + CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), + SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); +#endif + + /* Note, here, that we have not properly handled the error processing */ + /* and so we cannot tell how much of our request crapped out */ + + SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); + RFCNB_Free_Pkt(pkt); + free(tree); + free(file_tmp); + SMBlib_errno = SMBlibE_Remote; + return(SMBlibE_BAD); + + } + +#ifdef DEBUG + fprintf(stderr, "SessSetupAndX response. Action = %i\n", + SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset)); +#endif + + /* Now pick up the UID for future reference ... */ + + Con_Handle -> uid = SVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset); + + /* And pick up the TID as well */ + + tree -> tid = SVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset); + tree -> mbs = Con_Handle -> max_xmit; /* We need this */ + +#ifdef DEBUG + fprintf(stderr, "mbs=%i\n", tree -> mbs); +#endif + + /* Now we populate the file hanble and pass it back ... */ + + strncpy(file_tmp -> filename, filename, sizeof(file_tmp -> filename) - 1); + file_tmp -> tree = tree; + + /* Pick up a pointer to the right part ... */ + + AndXCom = SMB_Hdr(pkt) + SVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset) - + SMB_hdr_wct_offset; + + /* Now skip the response to the TConX */ + + AndXCom = SMB_Hdr(pkt) + SVAL(AndXCom, SMB_tconxr_axo_offset) - + SMB_hdr_wct_offset; + +#ifdef DEBUG + fprintf(stderr, "Word Params = %x, AXO = %x\n", + CVAL(AndXCom, SMB_hdr_wct_offset), + SVAL(AndXCom, SMB_openxr_axo_offset)); +#endif + + /* Now pick up the things from the openX response that we need */ + + file_tmp -> fid = SVAL(AndXCom, SMB_openxr_fid_offset); + file_tmp -> lastmod = IVAL(AndXCom, SMB_openxr_tim_offset); + file_tmp -> size = IVAL(AndXCom, SMB_openxr_fsz_offset); + file_tmp -> access = SVAL(AndXCom, SMB_openxr_acc_offset); + file_tmp -> fileloc = 0; + + *File_Handle = file_tmp; + + /* Now link the tree into the right place ... */ + + if (Con_Handle -> first_tree == NULL) { + + Con_Handle -> first_tree == tree; + Con_Handle -> last_tree == tree; + + } else { + + Con_Handle -> last_tree -> next = tree; + tree -> prev = Con_Handle -> last_tree; + Con_Handle -> last_tree = tree; + + } + + RFCNB_Free_Pkt(pkt); + + *Tree_Handle = tree; + + return(0); + +} + diff --git a/lib/smblib/file.c b/lib/smblib/file.c new file mode 100644 index 0000000000..34bb6312a1 --- /dev/null +++ b/lib/smblib/file.c @@ -0,0 +1,1318 @@ +/* UNIX SMBlib NetBIOS implementation + + Version 1.0 + SMBlib File Access 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 "smblib-priv.h" + +#include "../rfcnb/rfcnb.h" + +/* Open a file with file_name using desired mode and search attr */ +/* If File_Handle is null, then create and populate a file handle */ + +SMB_File *SMB_Open(SMB_Tree_Handle Tree_Handle, + SMB_File *File_Handle, + char *file_name, + WORD mode, + WORD search) + +{ + struct RFCNB_Pkt *pkt; + int pkt_len, param_len; + char *p; + struct SMB_File_Def *file_tmp; + + /* We allocate a file object and copy some things ... */ + + file_tmp = File_Handle; + + if (File_Handle == NULL) { + + if ((file_tmp = (SMB_File *)malloc(sizeof(SMB_File))) == NULL) { + +#ifdef DEBUG + fprintf(stderr, "Could not allocate file handle space ..."); +#endif + + SMBlib_errno = SMBlibE_NoSpace; + return(NULL); + + } + + } + + strncpy(file_tmp -> filename, file_name, sizeof(file_tmp -> filename) - 1); + file_tmp -> tree = Tree_Handle; + file_tmp -> fid = 0xFFFF; /* Is this an invalid FID? */ + + param_len = strlen(file_name) + 2; /* 1 for null, 1 for ASCII marker */ + + pkt_len = SMB_open_len + param_len; + + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(max(pkt_len, SMB_openr_len)); + + if (pkt == NULL) { /* Really should do some error handling */ + + if (File_Handle == NULL) + free(file_tmp); + SMBlib_errno = SMBlibE_NoSpace; + return(NULL); + + } + + /* Now plug in the bits we need */ + + bzero(SMB_Hdr(pkt), SMB_open_len); + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBopen; + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Tree_Handle -> con -> pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, Tree_Handle -> tid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Tree_Handle -> con -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Tree_Handle -> con -> uid); + *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 2; + + SSVAL(SMB_Hdr(pkt), SMB_open_mod_offset, mode); + SSVAL(SMB_Hdr(pkt), SMB_open_atr_offset, search); + SSVAL(SMB_Hdr(pkt), SMB_open_bcc_offset, param_len); + + /* Now plug in the file name ... */ + + p = (char *)(SMB_Hdr(pkt) + SMB_open_buf_offset); + *p = SMBasciiID; + strcpy(p+1, file_name); + p = p + strlen(file_name); + *(p+1) = 0; /* plug in a null ... */ + + /* Now send the packet and get the response ... */ + + if (RFCNB_Send(Tree_Handle -> con -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error sending Open request\n"); +#endif + + if (File_Handle == NULL) + free(file_tmp); + RFCNB_Free_Pkt(pkt); + SMBlib_errno = -SMBlibE_SendFailed; + return(NULL); + + } + + /* Now get the response ... */ + +#ifdef DEBUG + fprintf(stderr, "Pkt_Len for Open resp = %i\n", pkt_len); +#endif + + if (RFCNB_Recv(Tree_Handle -> con -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error receiving response to open request\n"); +#endif + + if (File_Handle = NULL) + free(file_tmp); + RFCNB_Free_Pkt(pkt); + SMBlib_errno = -SMBlibE_RecvFailed; + return(NULL); + + } + + /* Now parse the response and pass back any error ... */ + + if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ + +#ifdef DEBUG + fprintf(stderr, "SMB_Open failed with errorclass = %i, Error Code = %i\n", + CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), + SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); +#endif + + if (File_Handle = NULL) + free(file_tmp); + SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_Remote; + return(NULL); /* Should clean up ... */ + + } + + file_tmp -> fid = SVAL(SMB_Hdr(pkt), SMB_openr_fid_offset); + file_tmp -> lastmod = IVAL(SMB_Hdr(pkt), SMB_openr_tim_offset); + file_tmp -> size = IVAL(SMB_Hdr(pkt), SMB_openr_fsz_offset); + file_tmp -> access = SVAL(SMB_Hdr(pkt), SMB_openr_acc_offset); + file_tmp -> fileloc = 0; + + RFCNB_Free_Pkt(pkt); /* Free up this space */ + +#ifdef DEBUG + fprintf(stderr, "SMB_Open succeeded, FID = %i\n", file_tmp -> fid); +#endif + + RFCNB_Free_Pkt(pkt); + + return(file_tmp); + +} + +/* Close the file referred to in File_Handle */ + +int SMB_Close(SMB_File *File_Handle) + +{ + struct SMB_Close_Prot_Def *prot_pkt; + struct SMB_Hdr_Def_LM12 *resp_pkt; + struct RFCNB_Pkt *pkt; + int pkt_len; + + if (File_Handle == NULL) { /* Error */ + + /*SMBLIB_errno = SMBLIBE_BadHandle; */ + return(-1); + + } + + pkt_len = SMB_clos_len; + + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); + + if (pkt == NULL) { /* Really should do some error handling */ + + SMBlib_errno = SMBlibE_NoSpace; + return(SMBlibE_BAD); + + } + + /* Now plug in the bits we need */ + + bzero(SMB_Hdr(pkt), SMB_clos_len); + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBclose; + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, File_Handle -> tree -> con -> pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, File_Handle -> tree -> tid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, File_Handle -> tree -> con -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, File_Handle -> tree -> con -> uid); + *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 3; + + SSVAL(SMB_Hdr(pkt), SMB_clos_fid_offset, File_Handle -> fid); + SIVAL(SMB_Hdr(pkt), SMB_clos_tim_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_clos_bcc_offset, 0); + + /* Now send the packet and get the response ... */ + + if (RFCNB_Send(File_Handle -> tree -> con -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error sending Open request\n"); +#endif + + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_SendFailed; + return(SMBlibE_BAD); + + } + + /* Now get the response ... */ + + if (RFCNB_Recv(File_Handle -> tree -> con -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error receiving response to open request\n"); +#endif + + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_RecvFailed; + return(SMBlibE_BAD); + + } + + /* Now parse the response and pass back any error ... */ + + if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ + +#ifdef DEBUG + fprintf(stderr, "SMB_Close failed with errorclass = %i, Error Code = %i\n", + CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), + SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); +#endif + + SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_Remote; + return(SMBlibE_BAD); /* Should clean up ... */ + + } + +#ifdef DEBUG + fprintf(stderr, "File %s closed successfully.\n", File_Handle -> filename); +#endif DEBUG + + /* We should deallocate the File_Handle now ... */ + + File_Handle -> tree = NULL; + File_Handle -> filename[0] = 0; + File_Handle -> fid = 0xFFFF; + + RFCNB_Free_Pkt(pkt); + free(File_Handle); + + return(0); +} + +/* Read numbytes into data from the file pointed to by File_Handle from */ +/* the offset in the File_Handle. */ + +int SMB_Read(SMB_File *File_Handle, char *data, int numbytes) + +{ + int tot_read; + struct RFCNB_Pkt *snd_pkt, *recv_pkt, *data_ptr; + int snd_pkt_len, recv_pkt_len, this_read, bytes_left = numbytes; + int max_read_data, bytes_read = 0; + + /* We loop around, reading the data, accumulating it into the buffer */ + /* We build an SMB packet, where the data is pointed to by a fragment*/ + /* tagged onto the end */ + + data_ptr = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(0); + if (data_ptr == NULL) { + + /* We should handle the error here */ + + SMBlib_errno = SMBlibE_NoSpace; + return(SMBlibE_BAD); + + } + + snd_pkt_len = SMB_read_len; /* size for the read SMB */ + recv_pkt_len = SMB_readr_len + 3; /* + 3 for the datablockID and blklen */ + + snd_pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(snd_pkt_len); + + if (snd_pkt == NULL) { + + RFCNB_Free_Pkt(data_ptr); + SMBlib_errno = SMBlibE_NoSpace; + return(SMBlibE_BAD); + + } + + recv_pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(recv_pkt_len); + + if (recv_pkt == NULL) { + + RFCNB_Free_Pkt(snd_pkt); + RFCNB_Free_Pkt(data_ptr); + SMBlib_errno = SMBlibE_NoSpace; + return(SMBlibE_BAD); + + } + + /* Put the recv pkt together */ + + recv_pkt -> next = data_ptr; + + /* Now build the read request and the receive packet etc ... */ + + bzero(SMB_Hdr(snd_pkt), SMB_read_len); + SIVAL(SMB_Hdr(snd_pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + *(SMB_Hdr(snd_pkt) + SMB_hdr_com_offset) = SMBread; + SSVAL(SMB_Hdr(snd_pkt), SMB_hdr_pid_offset, File_Handle -> tree -> con -> pid); + SSVAL(SMB_Hdr(snd_pkt), SMB_hdr_tid_offset, File_Handle -> tree -> tid); + SSVAL(SMB_Hdr(snd_pkt), SMB_hdr_mid_offset, File_Handle -> tree -> con -> mid); + SSVAL(SMB_Hdr(snd_pkt), SMB_hdr_uid_offset, File_Handle -> tree -> con -> uid); + *(SMB_Hdr(snd_pkt) + SMB_hdr_wct_offset) = 5; + SSVAL(SMB_Hdr(snd_pkt), SMB_read_fid_offset, File_Handle -> fid); + + max_read_data = (File_Handle -> tree -> mbs) - recv_pkt_len; + + while (bytes_left > 0) { + + this_read = (bytes_left > max_read_data?max_read_data: bytes_left); + + SSVAL(SMB_Hdr(snd_pkt), SMB_read_cnt_offset, this_read); + SIVAL(SMB_Hdr(snd_pkt), SMB_read_ofs_offset, File_Handle -> fileloc); + SSVAL(SMB_Hdr(snd_pkt), SMB_read_clf_offset, 0x0); + SSVAL(SMB_Hdr(snd_pkt), SMB_read_bcc_offset, 0x0); + + /* Now send the packet and wait for a response */ + + if (RFCNB_Send(File_Handle -> tree -> con -> Trans_Connect, snd_pkt, snd_pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error sending read request\n"); +#endif + + data_ptr -> data = NULL; + data_ptr -> len = 0; + RFCNB_Free_Pkt(recv_pkt); + RFCNB_Free_Pkt(snd_pkt); + SMBlib_errno = SMBlibE_SendFailed; + return(SMBlibE_BAD); + + } + + /* Now get the response ... first point the data portion to the right */ + /* place in the read buffer ... what we are doing is ugly */ + + data_ptr -> data = (data + bytes_read); + data_ptr -> len = this_read; + + if (RFCNB_Recv(File_Handle -> tree -> con -> Trans_Connect, recv_pkt, recv_pkt_len + this_read) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error receiving response to write\n"); +#endif + + data_ptr -> len = 0; + data_ptr -> data = NULL; + RFCNB_Free_Pkt(recv_pkt); + RFCNB_Free_Pkt(snd_pkt); + SMBlib_errno = SMBlibE_RecvFailed; + return(SMBlibE_BAD); + + } + + if (CVAL(SMB_Hdr(recv_pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ + +#ifdef DEBUG + fprintf(stderr, "SMB_Read failed with errorclass = %i, Error Code = %i\n", + CVAL(SMB_Hdr(recv_pkt), SMB_hdr_rcls_offset), + SVAL(SMB_Hdr(recv_pkt), SMB_hdr_err_offset)); +#endif + + SMBlib_SMB_Error = IVAL(SMB_Hdr(recv_pkt), SMB_hdr_rcls_offset); + data_ptr -> data = NULL; + data_ptr -> len = 0; + RFCNB_Free_Pkt(recv_pkt); + RFCNB_Free_Pkt(snd_pkt); + SMBlib_errno = SMBlibE_Remote; + return(-1); + + } + + /* Ok, that worked, so update some things here ... */ + + bytes_read = bytes_read + SVAL(SMB_Hdr(recv_pkt), SMB_readr_cnt_offset); + bytes_left = bytes_left - SVAL(SMB_Hdr(recv_pkt), SMB_readr_cnt_offset); + + } + + /* Now free those packet headers that we allocated ... */ + + data_ptr -> data = NULL; /* Since recv_pkt points to data_ptr */ + data_ptr -> len = 0; /* it is freed too */ + RFCNB_Free_Pkt(recv_pkt); + RFCNB_Free_Pkt(snd_pkt); + + return(bytes_read); + +} + +/* Lseek seeks just like the UNIX version does ... */ + +off_t SMB_Lseek(SMB_File *File_Handle, off_t offset, int whence) + +{ + + /* We should check that the file handle is kosher ... We may also blow up + if we get a 64 bit offset ... should avoid wrap-around ... */ + + switch (whence) { + case SEEK_SET: + + File_Handle -> fileloc = offset; + break; + + case SEEK_CUR: + + File_Handle -> fileloc = File_Handle -> fileloc + offset; + break; + + case SEEK_END: + + File_Handle -> fileloc = File_Handle -> size + offset; + break; + + default: + return(-1); + + } + + return(File_Handle -> fileloc); + +} + + +/* Write numbytes from data to the file pointed to by the File_Handle at */ +/* the offset in the File_Handle. */ + +int SMB_Write(SMB_File *File_Handle, char *data, int numbytes) + +{ + int tot_written = 0; + struct RFCNB_Pkt *pkt, *data_ptr; + int pkt_len, i, this_write, max_write_data, bytes_left = numbytes; + + /* We loop around, writing the data, accumulating what was written */ + /* We build an SMB packet, where the data is pointed to by a fragment */ + /* tagged onto the end ... */ + + data_ptr = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(0); + if (data_ptr == NULL) { + + SMBlib_errno = SMBlibE_NoSpace; + return(SMBlibE_BAD); + + } + + pkt_len = SMB_write_len + 3; /* + 3 for the datablockID and blklen */ + + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); + + if (pkt == NULL) { + + RFCNB_Free_Pkt(data_ptr); + SMBlib_errno = SMBlibE_NoSpace; + return(SMBlibE_BAD); + + } + + /* Now init the things that will be the same across the possibly multiple + packets to write this data. */ + + bzero(SMB_Hdr(pkt), SMB_write_len); + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBwrite; + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, File_Handle -> tree -> con -> pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, File_Handle -> tree -> tid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, File_Handle -> tree -> con -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, File_Handle -> tree -> con -> uid); + SSVAL(SMB_Hdr(pkt), SMB_write_fid_offset, File_Handle -> fid); + + /* We will program this as send/response for the moment, but if we could + only send the second block before getting the first, we could speed + things up a bit ... */ + + max_write_data = (File_Handle -> tree -> mbs) - pkt_len; + + /* the 3 is for the data block id and length that preceeds the data */ + + while (bytes_left > 0) { + + /* bytes to write? */ + + this_write = (bytes_left > max_write_data?max_write_data:bytes_left); + + data_ptr -> next = NULL; + data_ptr -> len = this_write; + data_ptr -> data = data + tot_written; + + pkt -> next = data_ptr; /* link the data on the end */ + + SSVAL(SMB_Hdr(pkt), SMB_hdr_flg_offset, 0); + *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 5; + SSVAL(SMB_Hdr(pkt), SMB_write_fid_offset, File_Handle -> fid); + SSVAL(SMB_Hdr(pkt), SMB_write_cnt_offset, this_write); + SIVAL(SMB_Hdr(pkt), SMB_write_ofs_offset, File_Handle -> fileloc); + SSVAL(SMB_Hdr(pkt), SMB_write_clf_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_write_bcc_offset, (this_write + 3)); + + *(SMB_Hdr(pkt) + SMB_write_buf_offset) = SMBdatablockID; + SSVAL(SMB_Hdr(pkt), SMB_write_buf_offset + 1, this_write); + + /* Now send the packet and wait for a response */ + + if (RFCNB_Send(File_Handle -> tree -> con -> Trans_Connect, pkt, pkt_len + this_write) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error sending write request\n"); +#endif + + data_ptr -> next = NULL; + data_ptr -> len = 0; + RFCNB_Free_Pkt(pkt); + SMBlib_errno = -SMBlibE_SendFailed; + return(-1); + + } + + /* Now get the response ... */ + + if (RFCNB_Recv(File_Handle -> tree -> con -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error receiving response to write\n"); +#endif + + data_ptr -> next = NULL; + data_ptr -> len = 0; + RFCNB_Free_Pkt(pkt); + SMBlib_errno = -SMBlibE_RecvFailed; + return(-1); + + } + + if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ + +#ifdef DEBUG + fprintf(stderr, "SMB_Write failed with errorclass = %i, Error Code = %i\n", + CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), + SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); +#endif + + SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); + data_ptr -> data = NULL; + data_ptr -> len = 0; + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_Remote; + return(SMBlibE_BAD); + + } + + /* Ok, that worked, so update some things here ... */ + + tot_written = tot_written + this_write; + bytes_left = bytes_left - this_write; + + /* Assume that it is ok to update this now, but what about only part */ + /* of the write succeeding? */ + + File_Handle -> fileloc = File_Handle -> fileloc + this_write; + +#ifdef DEBUG + fprintf(stderr, "--This_write = %i, bytes_left = %i\n", + this_write, bytes_left); +#endif + + } + + /* Let's get rid of those packet headers we are using ... */ + + data_ptr -> data = NULL; + pkt -> next = NULL; + + RFCNB_Free_Pkt(pkt); + + return(tot_written); + +} + +/* Create file on the server with name file_name and attributes search */ + +SMB_File *SMB_Create(SMB_Tree_Handle Tree_Handle, + SMB_File *File_Handle, + char *file_name, + WORD search) + +{ + struct RFCNB_Pkt *pkt; + int pkt_len, param_len; + char *p; + struct SMB_File_Def *file_tmp; + + /* We allocate a file object and copy some things ... */ + + file_tmp = File_Handle; + + if (File_Handle == NULL) { + + if ((file_tmp = (SMB_File *)malloc(sizeof(SMB_File))) == NULL) { + +#ifdef DEBUG + fprintf(stderr, "Could not allocate file handle space ..."); +#endif + + SMBlib_errno = SMBlibE_NoSpace; + return(NULL); + + } + + } + + strncpy(file_tmp -> filename, file_name, sizeof(file_tmp -> filename)); + file_tmp -> tree = Tree_Handle; + file_tmp -> fid = 0xFFFF; /* Is this an invalid FID? */ + + param_len = strlen(file_name) + 2; /* 1 for null, 1 for ASCII marker */ + + pkt_len = SMB_creat_len + param_len; + + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); + + if (pkt == NULL) { /* Really should do some error handling */ + + if (File_Handle == NULL) + free(file_tmp); + SMBlib_errno = SMBlibE_NoSpace; + return(NULL); + + } + + /* Now plug in the bits we need */ + + bzero(SMB_Hdr(pkt), SMB_creat_len); + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBcreate; + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Tree_Handle -> con -> pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, Tree_Handle -> tid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Tree_Handle -> con -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Tree_Handle -> con -> uid); + *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 3; + + SSVAL(SMB_Hdr(pkt), SMB_creat_atr_offset, search); + SSVAL(SMB_Hdr(pkt), SMB_creat_tim_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_creat_dat_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_creat_bcc_offset, param_len); + + /* Now plug in the file name ... */ + + p = (char *)(SMB_Hdr(pkt) + SMB_creat_buf_offset); + *p = SMBasciiID; + strcpy(p+1, file_name); + p = p + strlen(file_name); + *(p+1) = 0; /* plug in a null ... */ + + /* Now send the packet and get the response ... */ + + if (RFCNB_Send(Tree_Handle -> con -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error sending Open request\n"); +#endif + + if (File_Handle == NULL) + free(file_tmp); + RFCNB_Free_Pkt(pkt); + SMBlib_errno = -SMBlibE_SendFailed; + return(NULL); + + } + + /* Now get the response ... */ + +#ifdef DEBUG + fprintf(stderr, "Pkt_Len for Create resp = %i\n", pkt_len); +#endif + + if (RFCNB_Recv(Tree_Handle -> con -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error receiving response to create request\n"); +#endif + + if (File_Handle == NULL) + free(file_tmp); + RFCNB_Free_Pkt(pkt); + SMBlib_errno = -SMBlibE_RecvFailed; + return(NULL); + + } + + /* Now parse the response and pass back any error ... */ + + if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ + +#ifdef DEBUG + fprintf(stderr, "SMB_Create failed with errorclass = %i, Error Code = %i\n", + CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), + SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); +#endif + + if (File_Handle == NULL) + free(file_tmp); + SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_Remote; + return(NULL); /* Should clean up ... */ + + } + + file_tmp -> fid = SVAL(SMB_Hdr(pkt), SMB_creatr_fid_offset); + file_tmp -> lastmod = 0; + file_tmp -> size = 0; + file_tmp -> access = SMB_AMODE_OPENRW; + file_tmp -> fileloc = 0; + + RFCNB_Free_Pkt(pkt); /* Free up this space */ + +#ifdef DEBUG + fprintf(stderr, "SMB_Create succeeded, FID = %i\n", file_tmp -> fid); +#endif + + return(file_tmp); + +} + +/* Delete the file passed in as file_name. */ + +int SMB_Delete(SMB_Tree_Handle tree, char *file_name, WORD search) + +{ + struct RFCNB_Pkt *pkt; + int pkt_len, param_len; + char *p; + + param_len = strlen(file_name) + 2; + pkt_len = SMB_delet_len + param_len; + + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); + + if (pkt == NULL) { /* Really should do some error handling */ + + SMBlib_errno = SMBlibE_NoSpace; + return(SMBlibE_BAD); + + } + + /* Now plug in the bits we need */ + + bzero(SMB_Hdr(pkt), SMB_delet_len); + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBunlink; + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid); + *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 1; + + SIVAL(SMB_Hdr(pkt), SMB_delet_sat_offset, search); + SSVAL(SMB_Hdr(pkt), SMB_delet_bcc_offset, param_len); + + /* Now plug in the file name ... */ + + p = (char *)(SMB_Hdr(pkt) + SMB_delet_buf_offset); + *p = SMBasciiID; + strcpy(p+1, file_name); + p = p + strlen(file_name); + *(p+1) = 0; /* plug in a null ... */ + + /* Now send the packet and get the response ... */ + + if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error sending Delete request\n"); +#endif + + RFCNB_Free_Pkt(pkt); + SMBlib_errno = -SMBlibE_SendFailed; + return(SMBlibE_BAD); + + } + + /* Now get the response ... */ + + if (RFCNB_Recv(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error receiving response to delete request\n"); +#endif + + RFCNB_Free_Pkt(pkt); + SMBlib_errno = -SMBlibE_RecvFailed; + return(SMBlibE_BAD); + + } + + /* Now parse the response and pass back any error ... */ + + if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ + +#ifdef DEBUG + fprintf(stderr, "SMB_Delete failed with errorclass = %i, Error Code = %i\n", + CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), + SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); +#endif + + SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_Remote; + return(SMBlibE_BAD); /* Should clean up ... */ + + } + +#ifdef DEBUG + fprintf(stderr, "File %s deleted successfully.\n", file_name); +#endif DEBUG + + RFCNB_Free_Pkt(pkt); + + return(0); +} + +/* Create the directory passed in as dir_name */ + +int SMB_Create_Dir(SMB_Tree_Handle tree, char *dir_name) + +{ + struct RFCNB_Pkt *pkt; + int pkt_len, param_len; + char *p; + + param_len = strlen(dir_name) + 2; /* + null and + asciiID */ + pkt_len = SMB_creatdir_len + param_len; + + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); + + if (pkt == NULL) { /* Really should do some error handling */ + + SMBlib_errno = SMBlibE_NoSpace; + return(SMBlibE_BAD); + + } + + /* Now plug in the bits we need */ + + bzero(SMB_Hdr(pkt), SMB_creatdir_len); + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBmkdir; + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid); + *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0; + + SSVAL(SMB_Hdr(pkt), SMB_creatdir_bcc_offset, param_len); + + /* Now plug in the file name ... */ + + p = (char *)(SMB_Hdr(pkt) + SMB_creatdir_buf_offset); + *p = SMBasciiID; + strcpy(p+1, dir_name); + p = p + strlen(dir_name); + *(p+1) = 0; /* plug in a null ... */ + + /* Now send the packet and get the response ... */ + + if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error sending Create Dir request\n"); +#endif + + RFCNB_Free_Pkt(pkt); + SMBlib_errno = -SMBlibE_SendFailed; + return(SMBlibE_BAD); + + } + + /* Now get the response ... */ + + if (RFCNB_Recv(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error receiving response to Create Dir request\n"); +#endif + + RFCNB_Free_Pkt(pkt); + SMBlib_errno = -SMBlibE_RecvFailed; + return(SMBlibE_BAD); + + } + + /* Now parse the response and pass back any error ... */ + + if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ + +#ifdef DEBUG + fprintf(stderr, "SMB_Create_Dir failed with errorclass = %i, Error Code = %i\n", + CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), + SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); +#endif + + SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_Remote; + return(SMBlibE_BAD); /* Should clean up ... */ + + } + +#ifdef DEBUG + fprintf(stderr, "Directory %s created successfully.\n", dir_name); +#endif DEBUG + + RFCNB_Free_Pkt(pkt); + + return(0); +} + +/* Delete the directory passed as dir_name, as long as it is empty ... */ + +int SMB_Delete_Dir(SMB_Tree_Handle tree, char *dir_name) + +{ + struct RFCNB_Pkt *pkt; + int pkt_len, param_len; + char *p; + + param_len = strlen(dir_name) + 2; /* + null and + asciiID */ + pkt_len = SMB_deletdir_len + param_len; + + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); + + if (pkt == NULL) { /* Really should do some error handling */ + + SMBlib_errno = SMBlibE_NoSpace; + return(SMBlibE_BAD); + + } + + /* Now plug in the bits we need */ + + bzero(SMB_Hdr(pkt), SMB_deletdir_len); + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBrmdir; + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid); + *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0; + + SSVAL(SMB_Hdr(pkt), SMB_deletdir_bcc_offset, param_len); + + /* Now plug in the file name ... */ + + p = (char *)(SMB_Hdr(pkt) + SMB_deletdir_buf_offset); + *p = SMBasciiID; + strcpy(p+1, dir_name); + p = p + strlen(dir_name); + *(p+1) = 0; /* plug in a null ... */ + + /* Now send the packet and get the response ... */ + + if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error sending Delete Dir request\n"); +#endif + + RFCNB_Free_Pkt(pkt); + SMBlib_errno = -SMBlibE_SendFailed; + return(SMBlibE_BAD); + + } + + /* Now get the response ... */ + + if (RFCNB_Recv(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error receiving response to Delete Dir request\n"); +#endif + + RFCNB_Free_Pkt(pkt); + SMBlib_errno = -SMBlibE_RecvFailed; + return(SMBlibE_BAD); + + } + + /* Now parse the response and pass back any error ... */ + + if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ + +#ifdef DEBUG + fprintf(stderr, "SMB_Delete_Dir failed with errorclass = %i, Error Code = %i\n", + CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), + SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); +#endif + + SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_Remote; + return(SMBlibE_BAD); /* Should clean up ... */ + + } + +#ifdef DEBUG + fprintf(stderr, "Directory %s deleted successfully.\n", dir_name); +#endif DEBUG + + RFCNB_Free_Pkt(pkt); + + return(0); +} + +/* Check for the existence of the directory in dir_name */ + +int SMB_Check_Dir(SMB_Tree_Handle tree, char *dir_name) + +{ + struct RFCNB_Pkt *pkt; + int pkt_len, param_len; + char *p; + + param_len = strlen(dir_name) + 2; /* + null and + asciiID */ + pkt_len = SMB_checkdir_len + param_len; + + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); + + if (pkt == NULL) { /* Really should do some error handling */ + + SMBlib_errno = SMBlibE_NoSpace; + return(SMBlibE_BAD); + + } + + /* Now plug in the bits we need */ + + bzero(SMB_Hdr(pkt), SMB_checkdir_len); + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBchkpth; + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid); + *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0; + + SSVAL(SMB_Hdr(pkt), SMB_checkdir_bcc_offset, param_len); + + /* Now plug in the file name ... */ + + p = (char *)(SMB_Hdr(pkt) + SMB_checkdir_buf_offset); + *p = SMBasciiID; + strcpy(p+1, dir_name); + p = p + strlen(dir_name); + *(p+1) = 0; /* plug in a null ... */ + + /* Now send the packet and get the response ... */ + + if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error sending Check Dir Path request\n"); +#endif + + RFCNB_Free_Pkt(pkt); + SMBlib_errno = -SMBlibE_SendFailed; + return(SMBlibE_BAD); + + } + + /* Now get the response ... */ + + if (RFCNB_Recv(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error receiving response to Check Dir request\n"); +#endif + + RFCNB_Free_Pkt(pkt); + SMBlib_errno = -SMBlibE_RecvFailed; + return(SMBlibE_BAD); + + } + + /* Now parse the response and pass back any error ... */ + + if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ + +#ifdef DEBUG + fprintf(stderr, "SMB_Check_Dir failed with errorclass = %i, Error Code = %i\n", + CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), + SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); +#endif + + SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_Remote; + return(SMBlibE_BAD); /* Should clean up ... */ + + } + +#ifdef DEBUG + fprintf(stderr, "Directory %s checked successfully.\n", dir_name); +#endif DEBUG + + RFCNB_Free_Pkt(pkt); + + return(0); +} + +/* Search directory for the files listed ... Relative to the TID in the */ +/* Con Handle. Return number of Dir Ents returned as the result. */ + +int SMB_Search(SMB_Tree_Handle tree, + char *dir_name, + WORD search, + SMB_CP_dirent *dirents, + int direntc, + char *resumekey, + int resumekey_len) + +{ + struct RFCNB_Pkt *pkt, *recv_pkt; + int pkt_len, param_len, recv_param_len, recv_pkt_len, ret_count, i; + char *p; + + param_len = strlen(dir_name) + 2 + resumekey_len + 3; /* You have to know */ + pkt_len = SMB_search_len + param_len; + + recv_param_len = direntc * SMB_searchr_dirent_len + 3; + recv_pkt_len = SMB_searchr_len + recv_param_len; + + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); + + if (pkt == NULL) { /* Really should do some error handling */ + + SMBlib_errno = SMBlibE_NoSpace; + return(SMBlibE_BAD); + + } + + recv_pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(recv_pkt_len); + + if (recv_pkt == NULL) { /* Really should do some error handling */ + + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_NoSpace; + return(SMBlibE_BAD); + + } + + + /* Now plug in the bits we need */ + + bzero(SMB_Hdr(pkt), SMB_search_len); + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsearch; + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid); + + /* Tell server we known about non-dos names and extended attibutes */ + + SSVAL(SMB_Hdr(pkt), SMB_hdr_flg2_offset, + (SMB_FLG2_NON_DOS | SMB_FLG2_EXT_ATR)); + + *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 2; + + SSVAL(SMB_Hdr(pkt), SMB_search_mdc_offset, direntc); /* How many we want */ + SSVAL(SMB_Hdr(pkt), SMB_search_atr_offset, search); + SSVAL(SMB_Hdr(pkt), SMB_search_bcc_offset, param_len); + + /* Now plug in the file name ... */ + + p = (char *)(SMB_Hdr(pkt) + SMB_search_buf_offset); + *p = SMBasciiID; + strcpy(p+1, dir_name); + p = p + strlen(dir_name) + 2; /* Skip the null */ + + + + *p = SMBvariableblockID; + p = p + 1; + + /* And now the resume key */ + + SSVAL(p, 0, resumekey_len); + + p = p + 2; + + bcopy(resumekey, p, resumekey_len); + + /* Now send the packet and get the response ... */ + + if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error sending search request\n"); +#endif + + RFCNB_Free_Pkt(pkt); + RFCNB_Free_Pkt(recv_pkt); + SMBlib_errno = -SMBlibE_SendFailed; + return(SMBlibE_BAD); + + } + + /* Now get the response ... */ + + if (RFCNB_Recv(tree -> con -> Trans_Connect, recv_pkt, recv_pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error receiving response to Check Dir request\n"); +#endif + + RFCNB_Free_Pkt(pkt); + RFCNB_Free_Pkt(recv_pkt); + SMBlib_errno = -SMBlibE_RecvFailed; + return(SMBlibE_BAD); + + } + + /* Now parse the response and pass back any error ... */ + + if (CVAL(SMB_Hdr(recv_pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ + +#ifdef DEBUG + fprintf(stderr, "SMB_Check_Dir failed with errorclass = %i, Error Code = %i\n", + CVAL(SMB_Hdr(recv_pkt), SMB_hdr_rcls_offset), + SVAL(SMB_Hdr(recv_pkt), SMB_hdr_err_offset)); +#endif + + SMBlib_SMB_Error = IVAL(SMB_Hdr(recv_pkt), SMB_hdr_rcls_offset); + RFCNB_Free_Pkt(pkt); + RFCNB_Free_Pkt(recv_pkt); + SMBlib_errno = SMBlibE_Remote; + return(SMBlibE_BAD); /* Should clean up ... */ + + } + + /* Now copy the results into the user's structure */ + + ret_count = SVAL(SMB_Hdr(recv_pkt), SMB_searchr_dec_offset); + + p = SMB_Hdr(recv_pkt) + SMB_searchr_buf_offset + 3; + + /* Hmmm, should check that we have the right number of bytes ... */ + + for (i = 0; i < ret_count; i++) { + + bcopy(p, dirents[i].resume_key, 21); + + p = p + 21; + + dirents[i].file_attributes = (unsigned char)*p; + + p = p + 1; + + dirents[i].date_time = IVAL(p, 0); /* Should this be IVAL? */ + + p = p + 4; + + dirents[i].size = IVAL(p, 0); + + p = p + 4; + + bcopy(p, dirents[i].filename, 13); /* Copy in file name */ + + p = p + 13; + + } + + return(ret_count); + +} diff --git a/lib/smblib/find_password.c b/lib/smblib/find_password.c new file mode 100644 index 0000000000..f31be07bd1 --- /dev/null +++ b/lib/smblib/find_password.c @@ -0,0 +1,278 @@ +/* Find passwords ... */ +/* We do it in a brute force way ... Cycle through all the possible passwords + sending a logon to see if all it works ... We have to wait for any timeout + the the server implements before we try the next one. We could open lots + of connections to the server and then send the logon request and not wait + for the reply. This would allow us to have lots of outstanding attempts at + a time. */ + +#include +#include + +#include "smblib.h" + +int verbose = FALSE; +int lotc = FALSE; + +char *SMB_Prots[] = {"PC NETWORK PROGRAM 1.0", + "MICROSOFT NETWORKS 1.03", + "MICROSOFT NETWORKS 3.0", + "LANMAN1.0", + "LM1.2X002", + "LANMAN2.1", + "NT LM 0.12", + "NT LANMAN 1.0", + NULL + }; + +void usage() + +{ + fprintf(stderr,"Usage: find_password -u -l server\n"); +} + +/* figure out next password */ + +static int pwinit = FALSE, pwpos = 0; + +int next_password(char *pw, int pwlen) + +{ + int i, carry = FALSE; + + if (pwinit == FALSE) { + + pwinit = TRUE; + bzero(pw, pwlen + 1); + pwpos = 0; + + } + + i = pwpos; + + while (TRUE) { + + pw[i] = pw[i] + 1; + + /* If it has wrapped around, then inc to 1 and carry up the chain */ + + if (pw[i] == 0) { + + pw[i] = 1; + i = i - 1; + + if (i < 0) { /* If we went off the end, increment pwpos */ + + pwpos = pwpos + 1; + if (pwpos >= pwlen) return(FALSE); /* No more passwords */ + + pw[pwpos] = 1; + return(TRUE); + + } + + } else + return(TRUE); + + return(FALSE); + } +} + +static char pwd_str[1024]; /* Where we put passwords as we convert them */ + +char *print_password(char * password) + +{ + int i,j; + char temp[4]; + + j = 0; + + for (i = 0; i < strlen(password); i++) { + + if (((unsigned)password[i] <= ' ') || ((unsigned)password[i] > 127)) { + + pwd_str[j] = '\\'; + sprintf(temp, "%03i", (int)password[i]); + strcpy(&pwd_str[j + 1], temp); + j = j + 3; /* Space for \ accounted for below */ + + } else + pwd_str[j] = password[i]; + + j = j + 1; + + } + + pwd_str[j] = 0; /* Put a null on the end ... */ + + return(pwd_str); + +} + +main(int argc, char *argv[]) + +{ + void *con, *tree; + extern char *optarg; + extern int optind; + int opt, error, SMB_Error, err_class, err_code, pwlen, tries = 0; + char server[80], service[80], service_name[160], password[80], username[80]; + char old_password[80], err_string[1024]; + + server[0] = 0; + strncpy(service, "IPC$", sizeof(service) - 1); + service_name[0] = 0; + username[0] = 0; + password[0] = 0; + old_password[0] = 0; + + while ((opt = getopt(argc, argv, "s:u:l:v")) != EOF) { + + switch (opt) { + case 's': + + strcpy(service, optarg); + break; + + case 'u': /* Pick up the user name */ + + strncpy(username, optarg, sizeof(username) - 1); + break; + + case 'l': /* pick up password len */ + + pwlen = atoi(optarg); + break; + + case 'v': /* Verbose? */ + verbose = TRUE; + break; + + default: + + usage(); + exit(1); + break; + } + + } + + if (optind < argc) { /* Some more parameters, assume is the server */ + strncpy(server, argv[optind], sizeof(server) - 1); + optind++; + } else { + strcpy(server, "nemesis"); + } + + if (verbose == TRUE) { /* Print out all we know */ + + fprintf(stderr, "Finding password for User: %s, on server: %s\n", + username, server); + fprintf(stderr, "with a pwlen = %i\n", pwlen); + + } + + SMB_Init(); /* Initialize things ... */ + + /* We connect to the server and negotiate */ + + con = SMB_Connect_Server(NULL, server); + + if (con == NULL) { /* Error processing */ + + fprintf(stderr, "Unable to connect to server %s ...\n", server); + + if (SMB_Get_Last_Error() == SMBlibE_Remote) { + + SMB_Error = SMB_Get_Last_SMB_Err(); + SMB_Get_SMB_Error_Msg(SMBlib_Error_Class(SMB_Error), + SMBlib_Error_Code(SMB_Error), + err_string, + sizeof(err_string) - 1); + + } else { + SMB_Get_Error_Msg(SMB_Get_Last_Error(), err_string, sizeof(err_string) - 1); + } + + printf(" %s\n", err_string); + exit(1); + + } + + /* We need to negotiate a protocol better than PC NetWork Program */ + + if (SMB_Negotiate(con, SMB_Prots) < 0) { + + fprintf(stderr, "Unable to negotiate a protocol with server %s ...\n", + server); + + if (SMB_Get_Last_Error() == SMBlibE_Remote) { + + SMB_Error = SMB_Get_Last_SMB_Err(); + SMB_Get_SMB_Error_Msg(SMBlib_Error_Class(SMB_Error), + SMBlib_Error_Code(SMB_Error), + err_string, + sizeof(err_string) - 1); + + } else { + SMB_Get_Error_Msg(SMB_Get_Last_Error(), err_string, sizeof(err_string) - 1); + } + + printf(" %s\n", err_string); + exit(1); + + } + + sprintf(service_name, "\\\\%s\\%s", server, service); /* Could blow up */ + + /* Now loop through all password possibilities ... */ + + bzero(password, sizeof(password)); + + while (next_password(password, pwlen) == TRUE) { + + if ((tree = SMB_Logon_And_TCon(con, + NULL, + username, + password, + service_name, "?????")) == NULL) { + + if (verbose == TRUE) { /* Lets hear about the error */ + + fprintf(stderr, "Unable to logon and tree connect to server %s ...\n", + server); + fprintf(stderr, "With username: %s, and password: %s\n", + username, print_password(password)); + + if (SMB_Get_Last_Error() == SMBlibE_Remote) { + + SMB_Error = SMB_Get_Last_SMB_Err(); + SMB_Get_SMB_Error_Msg(SMBlib_Error_Class(SMB_Error), + SMBlib_Error_Code(SMB_Error), + err_string, + sizeof(err_string) - 1); + + } else { + SMB_Get_Error_Msg(SMB_Get_Last_Error(), err_string, sizeof(err_string) - 1); + } + + printf(" %s\n", err_string); + + } + } else { /* Password match */ + + fprintf(stderr, "Logged in with password:%s\n", + print_password(password)); + + /* Exit now ... */ + + exit(0); + + } + + } + + fprintf(stderr, "Passwords exhausted."); + +} diff --git a/helpers/basic_auth/MSNT/md4.c b/lib/smblib/md4.c similarity index 99% rename from helpers/basic_auth/MSNT/md4.c rename to lib/smblib/md4.c index 5eaa0e019b..ac9d9bd39c 100644 --- a/helpers/basic_auth/MSNT/md4.c +++ b/lib/smblib/md4.c @@ -20,7 +20,7 @@ */ #include -#include "md4.h" +#include "smblib/md4.h" /* NOTE: This code makes no attempt to be fast! * diff --git a/libntlmauth/smb-md4.h b/lib/smblib/md4.h similarity index 100% rename from libntlmauth/smb-md4.h rename to lib/smblib/md4.h diff --git a/lib/smblib/smb-errors.c b/lib/smblib/smb-errors.c new file mode 100644 index 0000000000..0c0d94c91f --- /dev/null +++ b/lib/smblib/smb-errors.c @@ -0,0 +1,222 @@ +/* UNIX SMBlib NetBIOS implementation + + Version 1.0 + SMBlib Error values etc ... + + Copyright (C) Richard Sharpe, Andrew Tridgell, and Merik Karman, 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. +*/ + +/* This code ripped out of smbclient, where it was attributed to Merik */ +/* Karman merik@blackadder.dsh.oz.au */ +/* Modified by Richard Sharpe to try to make it more bullit proof and */ +/* ensure we don't overwrite strings when not passed enough space. Also */ +/* added code to say unknown error codes if we see any */ + + +#include + +typedef struct { + char *name; + int code; + char *message; +} err_code_struct; + +/* Dos Error Messages */ +err_code_struct dos_msgs[] = { + {"ERRbadfunc",1,"Invalid function."}, + {"ERRbadfile",2,"File not found."}, + {"ERRbadpath",3,"Directory invalid."}, + {"ERRnofids",4,"No file descriptors available"}, + {"ERRnoaccess",5,"Access denied."}, + {"ERRbadfid",6,"Invalid file handle."}, + {"ERRbadmcb",7,"Memory control blocks destroyed."}, + {"ERRnomem",8,"Insufficient server memory to perform the requested function."} + , + {"ERRbadmem",9,"Invalid memory block address."}, + {"ERRbadenv",10,"Invalid environment."}, + {"ERRbadformat",11,"Invalid format."}, + {"ERRbadaccess",12,"Invalid open mode."}, + {"ERRbaddata",13,"Invalid data."}, + {"ERR",14,"reserved."}, + {"ERRbaddrive",15,"Invalid drive specified."}, + {"ERRremcd",16,"A Delete Directory request attempted to remove the server's current directory."}, + {"ERRdiffdevice",17,"Not same device."}, + {"ERRnofiles",18,"A File Search command can find no more files matching the specified criteria."}, + {"ERRbadshare",32,"The sharing mode specified for an Open conflicts with existing FIDs on the file."}, + {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."}, + {"ERRbaddevtyp",66,"The device type is incorrect for a tree connect."}, + {"ERRbadnetnam",67,"The network name is incorrect or inappropriate."}, + {"ERRfilexists",80,"The file named in a Create Directory, Make New File or Link request already exists."}, + {"ERRbadpipe",230,"Pipe invalid."}, + {"ERRpipebusy",231,"All instances of the requested pipe are busy."}, + {"ERRpipeclosing",232,"Pipe close in progress."}, + {"ERRnotconnected",233,"No process on other end of pipe."}, + {"ERRmoredata",234,"There is more data to be returned."}, + {"ERRinvapi", 2142, "The API is invalid."}, + {NULL,-1,NULL} +}; + +/* Server Error Messages */ +err_code_struct server_msgs[] = { + {"ERRerror",1,"Non-specific error code."}, + {"ERRbadpw",2,"Bad password - name/password pair in a Tree Connect or Session Setup are invalid."}, + {"ERRbadtype",3,"reserved."}, + {"ERRaccess",4,"Network access denied. The requester does not have the necessary access rights within the specified context for the requested function. The context is defined by the TID or the UID."}, + {"ERRinvnid",5,"The tree ID (TID) specified in a command was invalid."}, + {"ERRinvnetname",6,"Invalid network name in tree connect."}, + {"ERRinvdevice",7,"Invalid device - printer request made to non-printer connection or non-printer request made to printer connection."}, + {"ERRqfull",49,"Print queue full (files) -- returned by open print file."}, + {"ERRqtoobig",50,"Print queue full -- no space."}, + {"ERRqeof",51,"EOF on print queue dump."}, + {"ERRinvpfid",52,"Invalid print file FID."}, + {"ERRsmbcmd",64,"The server did not recognize the command received."}, + {"ERRsrverror",65,"The server encountered an internal error, e.g., system file unavailable."}, + {"ERRfilespecs",67,"The file handle (FID) and pathname parameters contained an invalid combination of values."}, + {"ERRreserved",68,"reserved."}, + {"ERRbadpermits",69,"The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute."}, + {"ERRreserved",70,"reserved."}, + {"ERRsetattrmode",71,"The attribute mode in the Set File Attribute request is invalid."}, + {"ERRpaused",81,"Server is paused."}, + {"ERRmsgoff",82,"Not receiving messages."}, + {"ERRnoroom",83,"No room to buffer message."}, + {"ERRrmuns",87,"Too many remote user names."}, + {"ERRtimeout",88,"Operation timed out."}, + {"ERRnoresource",89,"No resources currently available for request."}, + {"ERRtoomanyuids",90,"Too many UIDs active on this session."}, + {"ERRbaduid",91,"The UID is not known as a valid ID on this session."}, + {"ERRusempx",250,"Temp unable to support Raw, use MPX mode."}, + {"ERRusestd",251,"Temp unable to support Raw, use standard read/write."}, + {"ERRcontmpx",252,"Continue in MPX mode."}, + {"ERRreserved",253,"reserved."}, + {"ERRreserved",254,"reserved."}, + {"ERRpwdexp",2242,"Password has expired."}, + {"ERRnosupport",0xFFFF,"Function not supported."}, + {NULL,-1,NULL} +}; + +/* Hard Error Messages */ +err_code_struct hard_msgs[] = { + {"ERRnowrite",19,"Attempt to write on write-protected diskette."}, + {"ERRbadunit",20,"Unknown unit."}, + {"ERRnotready",21,"Drive not ready."}, + {"ERRbadcmd",22,"Unknown command."}, + {"ERRdata",23,"Data error (CRC)."}, + {"ERRbadreq",24,"Bad request structure length."}, + {"ERRseek",25 ,"Seek error."}, + {"ERRbadmedia",26,"Unknown media type."}, + {"ERRbadsector",27,"Sector not found."}, + {"ERRnopaper",28,"Printer out of paper."}, + {"ERRwrite",29,"Write fault."}, + {"ERRread",30,"Read fault."}, + {"ERRgeneral",31,"General failure."}, + {"ERRbadshare",32,"A open conflicts with an existing open."}, + {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."}, + {"ERRwrongdisk",34,"The wrong disk was found in a drive."}, + {"ERRFCBUnavail",35,"No FCBs are available to process request."}, + {"ERRsharebufexc",36,"A sharing buffer has been exceeded."}, + {"ERRdiskfull",39,"The disk is full."}, + {NULL,-1,NULL} +}; + +struct { + int code; + char *class; + err_code_struct *err_msgs; +} err_classes[] = { + {0,"SUCCESS",NULL}, + {0x01,"ERRDOS",dos_msgs}, + {0x02,"ERRSRV",server_msgs}, + {0x03,"ERRHRD",hard_msgs}, + {0x04,"ERRXOS",NULL}, + {0xE1,"ERRRMX1",NULL}, + {0xE2,"ERRRMX2",NULL}, + {0xE3,"ERRRMX3",NULL}, + {0xFF,"ERRCMD",NULL}, + {-1,NULL,NULL} +}; + +/* Return in the string an error message after decoding the class and code */ + +int SMB_Get_SMB_Error_Msg(int err_class, int err_code, char *msg_buf, int len) + +{ + int i,j; + char internal_buf[80]; + + for (i=0; err_classes[i].class; i++) + + if (err_classes[i].code == err_class) { + + if (err_classes[i].err_msgs) { + + err_code_struct *err = err_classes[i].err_msgs; + + for (j=0; err[j].name; j++) + + if (err_code == err[j].code) { + + /* Put together the message */ + + strncpy(msg_buf, err_classes[i].class, len); + strncat(msg_buf, " - ", len - strlen(msg_buf)); + strncat(msg_buf, err[j].name, len - strlen(msg_buf)); + strncat(msg_buf, " (", len - strlen(msg_buf)); + strncat(msg_buf, err[j].message, len - strlen(msg_buf)); + strncat(msg_buf, ").", len - strlen(msg_buf)); + + return(strlen(msg_buf)); + } + + /* We only get here if the error code is one we don't know about */ + /* Just print out the code etc ... */ + + strncpy(msg_buf, err_classes[i].class, len); + strncat(msg_buf, " - ", len - strlen(msg_buf)); + sprintf(internal_buf, "%d", err_code); + strncat(msg_buf, internal_buf, len - strlen(msg_buf)); + strncat(msg_buf, " (Unknown error code).", len - strlen(msg_buf)); + + return(strlen(msg_buf)); + + } else { + + strncpy(msg_buf, err_classes[i].class, len); + strncat(msg_buf, " - ", len - strlen(msg_buf)); + sprintf(internal_buf, "%d", err_code); + strncat(msg_buf, internal_buf, len - strlen(msg_buf)); + + return(strlen(msg_buf)); + + } + + } + + /* If we get here, we did not recognize the error class */ + + sprintf(internal_buf, "%d", err_class); + strncat(msg_buf, internal_buf, len - strlen(msg_buf)); + strncat(msg_buf, " (Unknown Error Class) - ", len - strlen(msg_buf)); + sprintf(internal_buf, "%d", err_code); + strncat(msg_buf, internal_buf, len - strlen(msg_buf)); + strncat(msg_buf, "(error code).", len - strlen(msg_buf)); + + return(strlen(msg_buf)); + +} diff --git a/helpers/basic_auth/MSNT/smbdes.c b/lib/smblib/smbdes.c similarity index 100% rename from helpers/basic_auth/MSNT/smbdes.c rename to lib/smblib/smbdes.c diff --git a/helpers/basic_auth/MSNT/smbdes.h b/lib/smblib/smbdes.h similarity index 100% rename from helpers/basic_auth/MSNT/smbdes.h rename to lib/smblib/smbdes.h diff --git a/helpers/basic_auth/MSNT/smbencrypt.c b/lib/smblib/smbencrypt.c similarity index 93% rename from helpers/basic_auth/MSNT/smbencrypt.c rename to lib/smblib/smbencrypt.c index bffd64b9de..1be0241b72 100644 --- a/helpers/basic_auth/MSNT/smbencrypt.c +++ b/lib/smblib/smbencrypt.c @@ -1,3 +1,5 @@ +#include "config.h" + /* * Unix SMB/Netbios implementation. * Version 1.9. @@ -34,15 +36,15 @@ #include #endif -#include "smblib-priv.h" +#include "smblib/smblib-priv.h" #define uchar unsigned char extern int DEBUGLEVEL; -#include "byteorder.h" +#include "rfcnb/byteorder.h" -#include "md4.h" -#include "smbdes.h" -#include "smbencrypt.h" +#include "smblib/md4.h" +#include "smblib/smbdes.h" +#include "smblib/smbencrypt.h" static void E_md4hash(unsigned char *passwd, unsigned char *p16); static char *StrnCpy(char *dest, char *src, int n); @@ -68,7 +70,7 @@ SMBencrypt(uchar * passwd, uchar * c8, uchar * p24) /* Routines for Windows NT MD4 Hash functions. */ static int -_my_wcslen(int16 * str) +_my_wcslen(int16_t * str) { int len = 0; while (*str++ != 0) @@ -84,10 +86,10 @@ _my_wcslen(int16 * str) */ static int -_my_mbstowcs(int16 * dst, uchar * src, int len) +_my_mbstowcs(int16_t * dst, uchar * src, int len) { int i; - int16 val; + int16_t val; for (i = 0; i < len; i++) { val = *src; @@ -108,7 +110,7 @@ void E_md4hash(uchar * passwd, uchar * p16) { int len; - int16 wpwd[129]; + int16_t wpwd[129]; /* Password cannot be longer than 128 characters */ len = strlen((char *) passwd); @@ -118,7 +120,7 @@ E_md4hash(uchar * passwd, uchar * p16) _my_mbstowcs(wpwd, passwd, len); wpwd[len] = 0; /* Ensure string is null terminated */ /* Calculate length in bytes */ - len = _my_wcslen(wpwd) * sizeof(int16); + len = _my_wcslen(wpwd) * sizeof(int16_t); mdfour(p16, (unsigned char *) wpwd, len); } diff --git a/helpers/basic_auth/MSNT/smbencrypt.h b/lib/smblib/smbencrypt.h similarity index 57% rename from helpers/basic_auth/MSNT/smbencrypt.h rename to lib/smblib/smbencrypt.h index d35e4c4a1f..e6abaf6890 100644 --- a/helpers/basic_auth/MSNT/smbencrypt.h +++ b/lib/smblib/smbencrypt.h @@ -1,4 +1,15 @@ -/* smbencrypt.c */ +#ifndef _SMBLIB_SMBENCRYPT_H +#define _SMBLIB_SMBENCRYPT_H + +#ifdef __cplusplus +extern "C" { +#endif + void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); void nt_lm_owf_gen(char *pwd, char *nt_p16, char *p16); + +#ifdef __cplusplus +} +#endif +#endif /* _SMBLIB_SMBENCRYPT_H */ diff --git a/lib/smblib/smblib-api.c b/lib/smblib/smblib-api.c new file mode 100644 index 0000000000..72dce617d5 --- /dev/null +++ b/lib/smblib/smblib-api.c @@ -0,0 +1,381 @@ +/* UNIX SMBlib NetBIOS implementation + + Version 1.0 + SMB API Calls ... + + 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 "smblib-priv.h" +#include "../rfcnb/rfcnb.h" + +SMB_Tree_Handle SMBapi_Tree = NULL; + +/* Send an api request to the \\server\IPC$ tree, with a \PIPE\LANMAN api */ +/* request to change the user's password */ + +#define SMB_LMAPI_SLOT "\\PIPE\\LANMAN" +#define SMB_LMAPI_SUPW_DESC "zb16b16WW" + +int SMBapi_NetUserPasswordSet(SMB_Tree_Handle tree, char *user, + char *oldpass, char *newpass, int *apiStatus) + +{ + struct RFCNB_Pkt *pkt; + int param_len, i, pkt_len, pad_api_name = FALSE; + char *p; + + /* Get a packet, we need one with space for a transact plus. The calc */ + /* below lays it all out as it is, including the empty string after the */ + /* descriptor and before the username */ + + param_len = 2 + strlen(SMB_LMAPI_SUPW_DESC) + 1 + + 1 /* for empty string :-) */ + strlen(user) + + 1 + 16 + 16 + 2 + 2; + + /* We have no setup words, wo we don't account for them */ + + pkt_len = SMB_trans_len + 2 /* for bcc */ + strlen(SMB_LMAPI_SLOT) + 1; + + /* Pad things onto a word boundary ... */ + + if (pkt_len & 0x0001) { + pkt_len = pkt_len + 1; + pad_api_name = TRUE; + } + + + pkt_len = pkt_len + param_len; + + /* Now allocate space for the packet, build it and send it */ + + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); + + if (pkt == NULL) { + + SMBlib_errno = SMBlibE_NoSpace; + return(SMBlibE_BAD); /* Should handle the error */ + + } + + bzero(SMB_Hdr(pkt), SMB_trans_len); + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBtrans; + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid); + *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 14; + + SSVAL(SMB_Hdr(pkt), SMB_trans_tpc_offset, param_len); + SSVAL(SMB_Hdr(pkt), SMB_trans_tdc_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_trans_mpc_offset, 4); + SSVAL(SMB_Hdr(pkt), SMB_trans_mdc_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_trans_msc_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_trans_flg_offset, 0); + SIVAL(SMB_Hdr(pkt), SMB_trans_tmo_offset, 5000); + SSVAL(SMB_Hdr(pkt), SMB_trans_pbc_offset, param_len); + SSVAL(SMB_Hdr(pkt), SMB_trans_pbo_offset, SMB_trans_len + 2 + + strlen(SMB_LMAPI_SLOT) + 1); + SSVAL(SMB_Hdr(pkt), SMB_trans_dbc_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_trans_dbo_offset, 0); + + /* Now put in the bcc and the rest of the info ... */ + + SSVAL(SMB_Hdr(pkt), SMB_trans_len, param_len + strlen(SMB_LMAPI_SLOT) + 1); + + p = SMB_Hdr(pkt) + SMB_trans_len + 2; /* Skip the BCC and ect */ + + strcpy(p, SMB_LMAPI_SLOT); + p = p + strlen(SMB_LMAPI_SLOT) + 1; + + if (pad_api_name == TRUE) /* Pad if we need to */ + p = p + 1; + + /* SSVAL(p, 0, 65000); /* Check the result */ + SSVAL(p, 0, SMB_LMapi_UserPasswordSet); /* The api call */ + + p = p + 2; + + strcpy(p, SMB_LMAPI_SUPW_DESC); /* Copy in the param desc */ + + p = p + strlen(SMB_LMAPI_SUPW_DESC) + 1; + + *p = 0; /* Stick in that null string */ + p = p + 1; + + strcpy(p, user); + + p = p + strlen(user) + 1; + + strncpy(p, oldpass, 16); + + p = p + 16; + + strncpy(p, newpass, 16); + + p = p + 16; + + SSVAL(p, 0, 0); /* Seems to be zero always? */ + SSVAL(p, 2, strlen(newpass)); /* Length of new password ...*/ + + /* Now send the lot and get a response ... */ + + if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error sending Trans request\n"); +#endif + + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_SendFailed; + return(SMBlibE_BAD); + + } + + /* Now get the response ... */ + + if (RFCNB_Recv(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error receiving response to Trans request\n"); +#endif + + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_RecvFailed; + return(SMBlibE_BAD); + + } + + /* Check out the response type ... */ + + if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ + +#ifdef DEBUG + fprintf(stderr, "SMB_trans failed with errorclass = %i, Error Code = %i\n", + CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), + SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); +#endif + + SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_Remote; + return(SMBlibE_BAD); + + } + + /* All ok, pass back the status */ + + *apiStatus = SVAL(SMB_Hdr(pkt), SVAL(SMB_Hdr(pkt), SMB_transr_pbo_offset)); + RFCNB_Free_Pkt(pkt); + + return(0); + +} + +#define SMB_LMAPI_SUI_DESC "zWsTPWW" +#define SMB_LMAPI_SUI_DATA_DESC "B16" + + +/* Set user info ... specifically, password */ + +int SMBapi_NetSetUserInfo(SMB_Tree_Handle tree, char *user, + char *newpass, int *apiStatus) + +{ + struct RFCNB_Pkt *pkt; + int param_len, i, pkt_len, data_len, pad_api_name = FALSE; + int pad_params = FALSE; + char *p; + + /* Get a packet, we need one with space for a transact plus. The calc */ + /* below lays it all out as it is, including the empty string after the */ + /* descriptor and before the username */ + + param_len = 2 + strlen(SMB_LMAPI_SUI_DESC) + 1 + + + strlen(SMB_LMAPI_SUI_DATA_DESC) + 1 + strlen(user) + + 1 + 2 + 2 + 2 + 2; + + data_len = 16; + + /* We have no setup words, so we don't account for them */ + + pkt_len = SMB_trans_len + 2 /* for bcc */ + strlen(SMB_LMAPI_SLOT) + 1; + + if (pkt_len & 0x0001) { /* Pad to a WORD boundary */ + + pad_api_name = TRUE; + + } + + if (param_len & 0x0001) { /* pad to a WORD boundary */ + + pad_params = TRUE; + + } + + pkt_len = pkt_len + param_len + data_len; + + if (pad_api_name == TRUE) pkt_len = pkt_len + 1; + if (pad_params == TRUE) pkt_len = pkt_len + 1; + + /* Now allocate space for the packet, build it and send it */ + + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); + + if (pkt == NULL) { + + SMBlib_errno = SMBlibE_NoSpace; + return(SMBlibE_BAD); /* Should handle the error */ + + } + + bzero(SMB_Hdr(pkt), SMB_trans_len); + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBtrans; + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, tree -> con -> pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, tree -> tid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, tree -> con -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, tree -> con -> uid); + *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 14; + + SSVAL(SMB_Hdr(pkt), SMB_trans_tpc_offset, param_len); + SSVAL(SMB_Hdr(pkt), SMB_trans_tdc_offset, data_len); + SSVAL(SMB_Hdr(pkt), SMB_trans_mpc_offset, 4); + SSVAL(SMB_Hdr(pkt), SMB_trans_mdc_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_trans_msc_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_trans_flg_offset, 0); + SIVAL(SMB_Hdr(pkt), SMB_trans_tmo_offset, 5000); + SSVAL(SMB_Hdr(pkt), SMB_trans_pbc_offset, param_len); + SSVAL(SMB_Hdr(pkt), SMB_trans_pbo_offset, SMB_trans_len + 2 + + strlen(SMB_LMAPI_SLOT) + 1); + SSVAL(SMB_Hdr(pkt), SMB_trans_dbc_offset, data_len); + SSVAL(SMB_Hdr(pkt), SMB_trans_dbo_offset, pkt_len - data_len); + + /* Now put in the bcc and the rest of the info ... */ + + SSVAL(SMB_Hdr(pkt), SMB_trans_len, param_len + strlen(SMB_LMAPI_SLOT) + + 1 + data_len); + + p = SMB_Hdr(pkt) + SMB_trans_len + 2; /* Skip the BCC and ect */ + + strcpy(p, SMB_LMAPI_SLOT); + p = p + strlen(SMB_LMAPI_SLOT) + 1; + + if (pad_api_name == TRUE) /* Pad to a word boundary */ + p = p + 1; + + /* SSVAL(p, 0, 65000); /* Check the result */ + SSVAL(p, 0, SMB_LMapi_SetUserInfo); /* The api call */ + + p = p + 2; + + strcpy(p, SMB_LMAPI_SUI_DESC); /* Copy in the param desc */ + + p = p + strlen(SMB_LMAPI_SUI_DESC) + 1; + + strcpy(p, SMB_LMAPI_SUI_DATA_DESC); /* Copy in second descriptor */ + + p = p + strlen(SMB_LMAPI_SUI_DATA_DESC) + 1; + + strcpy(p, user); + + p = p + strlen(user) + 1; + + SSVAL(p, 0, 1); /* Claim that we have a level 1 struct ? */ + + p = p + 2; + + SSVAL(p, 0, 3); /* Set the password */ + SSVAL(p, 2, 1); /* Seems to be one ... */ + SSVAL(p, 4, strlen(newpass)); /* Length of new password ...*/ + + /* Now copy the data in ... */ + + p = p + 6; + + if (pad_params == TRUE) + p = p + 1; + + strcpy(p, newpass); + + /* Now send the lot and get a response ... */ + + if (RFCNB_Send(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error sending Trans SetUserInfo request\n"); +#endif + + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_SendFailed; + return(SMBlibE_BAD); + + } + + /* Now get the response ... */ + + if (RFCNB_Recv(tree -> con -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error receiving response to Trans SetUserInfo request\n"); +#endif + + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_RecvFailed; + return(SMBlibE_BAD); + + } + + /* Check out the response type ... */ + + if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ + +#ifdef DEBUG + fprintf(stderr, "SMB_trans SetUserInfo failed with errorclass = %i, Error Code = %i\n", + CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), + SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); +#endif + + SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_Remote; + return(SMBlibE_BAD); + + } + + /* All ok, pass back the status */ + + *apiStatus = SVAL(SMB_Hdr(pkt), SVAL(SMB_Hdr(pkt), SMB_transr_pbo_offset)); + RFCNB_Free_Pkt(pkt); + + return(0); + +} + +/* List all the shares available on a server */ + +int SMBapi_NetShareEnum(SMB_Tree_Handle tree, char *enum_buf, int bufsiz, + int *shares_returned, int *shares_total) + +{ + + +} diff --git a/lib/smblib/smblib-common.h b/lib/smblib/smblib-common.h new file mode 100644 index 0000000000..8a56d229c6 --- /dev/null +++ b/lib/smblib/smblib-common.h @@ -0,0 +1,254 @@ +/* UNIX SMBlib NetBIOS implementation + + Version 1.0 + SMBlib Common Defines + + 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. +*/ + +#ifndef _SMBLIB_SMBLIB_COMMON_H +#define _SMBLIB_SMBLIB_COMMON_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* To get the error class we want the first 8 bits */ +/* Because we just grab 4bytes from the SMB header, we have to re-order */ +/* here, but it makes the NtStatus part easier in future */ + +#define SMBlib_Error_Class(p) (p & 0x000000FF) + +/* To get the error code, we want the bottom 16 bits */ + +#define SMBlib_Error_Code(p) (((unsigned int)p & 0xFFFF0000) >>16) + +/* Error CLASS codes and etc ... */ + +#define SMBC_SUCCESS 0 +#define SMBC_ERRDOS 0x01 +#define SMBC_ERRSRV 0x02 +#define SMBC_ERRHRD 0x03 +#define SMBC_ERRCMD 0xFF + +/* Success error codes */ + +#define SMBS_BUFFERED 0x54 +#define SMBS_LOGGED 0x55 +#define SMBS_DISPLAYED 0x56 + +/* ERRDOS Error codes */ + +#define SMBD_badfunc 0x01 +#define SMBD_badfile 0x02 +#define SMBD_badpath 0x03 +#define SMBD_nofids 0x04 +#define SMBD_noaccess 0x05 +#define SMBD_badfid 0x06 +#define SMBD_badmcb 0x07 +#define SMBD_nomem 0x08 +#define SMBD_badmem 0x09 +#define SMBD_badenv 0x0A +#define SMBD_badformat 0x0B +#define SMBD_badaccess 0x0C +#define SMBD_baddata 0x0D +#define SMBD_reserved 0x0E +#define SMBD_baddrive 0x0F +#define SMBD_remcd 0x10 +#define SMBD_diffdevice 0x11 +#define SMBD_nofiles 0x12 +#define SMBD_badshare 0x20 +#define SMBD_errlock 0x21 +#define SMBD_filexists 0x50 + +/* Server errors ... */ + +#define SMBV_error 0x01 /* Generic error */ +#define SMBV_badpw 0x02 +#define SMBV_badtype 0x03 +#define SMBV_access 0x04 +#define SMBV_invnid 0x05 +#define SMBV_invnetname 0x06 +#define SMBV_invdevice 0x07 +#define SMBV_qfull 0x31 +#define SMBV_qtoobig 0x32 +#define SMBV_qeof 0x33 +#define SMBV_invpfid 0x34 +#define SMBV_paused 0x51 +#define SMBV_msgoff 0x52 +#define SMBV_noroom 0x53 +#define SMBV_rmuns 0x57 +#define SMBV_nosupport 0xFFFF + +/* Hardware error codes ... */ + +#define SMBH_nowrite 0x13 +#define SMBH_badunit 0x14 +#define SMBH_notready 0x15 +#define SMBH_badcmd 0x16 +#define SMBH_data 0x17 +#define SMBH_badreq 0x18 +#define SMBH_seek 0x19 +#define SMBH_badmedia 0x1A +#define SMBH_badsector 0x1B +#define SMBH_nopaper 0x1C +#define SMBH_write 0x1D +#define SMBH_read 0x1E +#define SMBH_general 0x1F +#define SMBH_badshare 0x20 + +/* Access mode defines ... */ + +#define SMB_AMODE_WTRU 0x4000 +#define SMB_AMODE_NOCACHE 0x1000 +#define SMB_AMODE_COMPAT 0x0000 +#define SMB_AMODE_DENYRWX 0x0010 +#define SMB_AMODE_DENYW 0x0020 +#define SMB_AMODE_DENYRX 0x0030 +#define SMB_AMODE_DENYNONE 0x0040 +#define SMB_AMODE_OPENR 0x0000 +#define SMB_AMODE_OPENW 0x0001 +#define SMB_AMODE_OPENRW 0x0002 +#define SMB_AMODE_OPENX 0x0003 +#define SMB_AMODE_FCBOPEN 0x00FF +#define SMB_AMODE_LOCUNKN 0x0000 +#define SMB_AMODE_LOCMSEQ 0x0100 +#define SMB_AMODE_LOCMRAN 0x0200 +#define SMB_AMODE_LOCRAL 0x0300 + +/* File attribute encoding ... */ + +#define SMB_FA_ORD 0x00 +#define SMB_FA_ROF 0x01 +#define SMB_FA_HID 0x02 +#define SMB_FA_SYS 0x04 +#define SMB_FA_VOL 0x08 +#define SMB_FA_DIR 0x10 +#define SMB_FA_ARC 0x20 + +/* Define the protocol types ... */ + +#define SMB_P_Unknown -1 /* Hmmm, is this smart? */ +#define SMB_P_Core 0 +#define SMB_P_CorePlus 1 +#define SMB_P_DOSLanMan1 2 +#define SMB_P_LanMan1 3 +#define SMB_P_DOSLanMan2 4 +#define SMB_P_LanMan2 5 +#define SMB_P_DOSLanMan2_1 6 +#define SMB_P_LanMan2_1 7 +#define SMB_P_NT1 8 + +/* SMBlib return codes */ +/* We want something that indicates whether or not the return code was a */ +/* remote error, a local error in SMBlib or returned from lower layer ... */ +/* Wonder if this will work ... */ +/* SMBlibE_Remote = 1 indicates remote error */ +/* SMBlibE_ values < 0 indicate local error with more info available */ +/* SMBlibE_ values >1 indicate local from SMBlib code errors? */ + +#define SMBlibE_Success 0 +#define SMBlibE_Remote 1 /* Remote error, get more info from con */ +#define SMBlibE_BAD -1 +#define SMBlibE_LowerLayer 2 /* Lower layer error */ +#define SMBlibE_NotImpl 3 /* Function not yet implemented */ +#define SMBlibE_ProtLow 4 /* Protocol negotiated does not support req */ +#define SMBlibE_NoSpace 5 /* No space to allocate a structure */ +#define SMBlibE_BadParam 6 /* Bad parameters */ +#define SMBlibE_NegNoProt 7 /* None of our protocols was liked */ +#define SMBlibE_SendFailed 8 /* Sending an SMB failed */ +#define SMBlibE_RecvFailed 9 /* Receiving an SMB failed */ +#define SMBlibE_GuestOnly 10 /* Logged in as guest */ +#define SMBlibE_CallFailed 11 /* Call remote end failed */ +#define SMBlibE_ProtUnknown 12 /* Protocol unknown */ +#define SMBlibE_NoSuchMsg 13 /* Keep this up to date */ + +/* the default SMB protocols supported by this library. */ +extern const char *SMB_Prots[]; + +typedef struct { /* A structure for a Dirent */ + + unsigned char resume_key[21]; /* Don't touch this */ + unsigned char file_attributes; /* Attributes of file */ + unsigned int date_time; /* date and time of last mod */ + unsigned int size; + char filename[13]; /* The name of the file */ + +} SMB_CP_dirent; + +typedef struct SMB_Connect_Def * SMB_Handle_Type; + +typedef struct SMB_Tree_Structure * SMB_Tree_Handle; + +/* A Tree_Structure */ + +struct SMB_Tree_Structure { + + SMB_Tree_Handle next, prev; + SMB_Handle_Type con; + char path[129]; + char device_type[20]; + int mbs; /* Local MBS */ + int tid; + +}; + +struct SMB_Connect_Def +{ + SMB_Handle_Type Next_Con, Prev_Con; /* Next and previous conn */ + int protocol; /* What is the protocol */ + int prot_IDX; /* And what is the index */ + void *Trans_Connect; /* The connection */ + + /* All these strings should be malloc'd */ + + char service[80], username[80], password[80], desthost[80], sock_options[80]; + char address[80], myname[80]; + + SMB_Tree_Handle first_tree, last_tree; /* List of trees on this server */ + + int gid; /* Group ID, do we need it? */ + int mid; /* Multiplex ID? We might need one per con */ + int pid; /* Process ID */ + + int uid; /* Authenticated user id. */ + + /* It is pretty clear that we need to bust some of */ + /* these out into a per TCon record, as there may */ + /* be multiple TCon's per server, etc ... later */ + + int port; /* port to use in case not default, this is a TCPism! */ + + int max_xmit; /* Max xmit permitted by server */ + int Security; /* 0 = share, 1 = user */ + int Raw_Support; /* bit 0 = 1 = Read Raw supported, 1 = 1 Write raw */ + int encrypt_passwords; /* 1 = do , 0 = don't */ + int MaxMPX, MaxVC, MaxRaw; + unsigned int SessionKey, Capabilities; + int SvrTZ; /* Server Time Zone */ + int Encrypt_Key_Len; + char Encrypt_Key[80], Domain[80], PDomain[80], OSName[80], LMType[40]; + char Svr_OS[80], Svr_LMType[80], Svr_PDom[80]; +}; + +#ifdef __cplusplus +} +#endif +#endif /* _SMBLIB_SMBLIB_COMMON_H */ diff --git a/lib/smblib/smblib-priv.h b/lib/smblib/smblib-priv.h new file mode 100644 index 0000000000..5d3beffd12 --- /dev/null +++ b/lib/smblib/smblib-priv.h @@ -0,0 +1,548 @@ +/* UNIX SMBlib NetBIOS implementation + + Version 1.0 + SMBlib private Defines + + 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. +*/ + +#ifndef _SMBLIB_PRIV_H_ +#define _SMBLIB_PRIV_H_ + +#include "smblib/std-defines.h" +#include "smblib/smblib-common.h" +#include +#include + +typedef unsigned short uint16; +typedef unsigned int uint32; + +#include "rfcnb/byteorder.h" /* Hmmm ... hot good */ + +#ifndef max +#define max(a,b) (a < b ? b : a) +#endif + +#define SMB_DEF_IDF 0x424D53FF /* "\377SMB" */ + +/* Core protocol commands */ + +#define SMBmkdir 0x00 /* create directory */ +#define SMBrmdir 0x01 /* delete directory */ +#define SMBopen 0x02 /* open file */ +#define SMBcreate 0x03 /* create file */ +#define SMBclose 0x04 /* close file */ +#define SMBflush 0x05 /* flush file */ +#define SMBunlink 0x06 /* delete file */ +#define SMBmv 0x07 /* rename file */ +#define SMBgetatr 0x08 /* get file attributes */ +#define SMBsetatr 0x09 /* set file attributes */ +#define SMBread 0x0A /* read from file */ +#define SMBwrite 0x0B /* write to file */ +#define SMBlock 0x0C /* lock byte range */ +#define SMBunlock 0x0D /* unlock byte range */ +#define SMBctemp 0x0E /* create temporary file */ +#define SMBmknew 0x0F /* make new file */ +#define SMBchkpth 0x10 /* check directory path */ +#define SMBexit 0x11 /* process exit */ +#define SMBlseek 0x12 /* seek */ +#define SMBtcon 0x70 /* tree connect */ +#define SMBtdis 0x71 /* tree disconnect */ +#define SMBnegprot 0x72 /* negotiate protocol */ +#define SMBdskattr 0x80 /* get disk attributes */ +#define SMBsearch 0x81 /* search directory */ +#define SMBsplopen 0xC0 /* open print spool file */ +#define SMBsplwr 0xC1 /* write to print spool file */ +#define SMBsplclose 0xC2 /* close print spool file */ +#define SMBsplretq 0xC3 /* return print queue */ +#define SMBsends 0xD0 /* send single block message */ +#define SMBsendb 0xD1 /* send broadcast message */ +#define SMBfwdname 0xD2 /* forward user name */ +#define SMBcancelf 0xD3 /* cancel forward */ +#define SMBgetmac 0xD4 /* get machine name */ +#define SMBsendstrt 0xD5 /* send start of multi-block message */ +#define SMBsendend 0xD6 /* send end of multi-block message */ +#define SMBsendtxt 0xD7 /* send text of multi-block message */ + +/* CorePlus protocol */ + +#define SMBlockread 0x13 /* Lock a range and read it */ +#define SMBwriteunlock 0x14 /* Unlock a range and then write */ +#define SMBreadbraw 0x1a /* read a block of data without smb header ohead*/ +#define SMBwritebraw 0x1d /* write a block of data without smb header ohead*/ +#define SMBwritec 0x20 /* secondary write request */ +#define SMBwriteclose 0x2c /* write a file and then close it */ + +/* DOS Extended Protocol */ + +#define SMBreadBraw 0x1A /* read block raw */ +#define SMBreadBmpx 0x1B /* read block multiplexed */ +#define SMBreadBs 0x1C /* read block (secondary response) */ +#define SMBwriteBraw 0x1D /* write block raw */ +#define SMBwriteBmpx 0x1E /* write block multiplexed */ +#define SMBwriteBs 0x1F /* write block (secondary request) */ +#define SMBwriteC 0x20 /* write complete response */ +#define SMBsetattrE 0x22 /* set file attributes expanded */ +#define SMBgetattrE 0x23 /* get file attributes expanded */ +#define SMBlockingX 0x24 /* lock/unlock byte ranges and X */ +#define SMBtrans 0x25 /* transaction - name, bytes in/out */ +#define SMBtranss 0x26 /* transaction (secondary request/response) */ +#define SMBioctl 0x27 /* IOCTL */ +#define SMBioctls 0x28 /* IOCTL (secondary request/response) */ +#define SMBcopy 0x29 /* copy */ +#define SMBmove 0x2A /* move */ +#define SMBecho 0x2B /* echo */ +#define SMBopenX 0x2D /* open and X */ +#define SMBreadX 0x2E /* read and X */ +#define SMBwriteX 0x2F /* write and X */ +#define SMBsesssetupX 0x73 /* Session Set Up & X (including User Logon) */ +#define SMBtconX 0x75 /* tree connect and X */ +#define SMBffirst 0x82 /* find first */ +#define SMBfunique 0x83 /* find unique */ +#define SMBfclose 0x84 /* find close */ +#define SMBinvalid 0xFE /* invalid command */ + +/* Any more ? */ + +#define SMBdatablockID 0x01 /* A data block identifier */ +#define SMBdialectID 0x02 /* A dialect id */ +#define SMBpathnameID 0x03 /* A pathname ID */ +#define SMBasciiID 0x04 /* An ascii string ID */ +#define SMBvariableblockID 0x05 /* A variable block ID */ + +/* some other defines we need */ + +/* Flags defines ... */ + +#define SMB_FLG2_NON_DOS 0x01 /* We know non dos names */ +#define SMB_FLG2_EXT_ATR 0x02 /* We know about Extended Attributes */ +#define SMB_FLG2_LNG_NAM 0x04 /* Long names ? */ + +typedef unsigned short WORD; +typedef unsigned short UWORD; +typedef unsigned int ULONG; +typedef unsigned char BYTE; +typedef unsigned char UCHAR; + +/* Some macros to allow access to actual packet data so that we */ +/* can change the underlying representation of packets. */ +/* */ +/* The current formats vying for attention are a fragment */ +/* approach where the SMB header is a fragment linked to the */ +/* data portion with the transport protocol (rfcnb or whatever) */ +/* being linked on the front. */ +/* */ +/* The other approach is where the whole packet is one array */ +/* of bytes with space allowed on the front for the packet */ +/* headers. */ + +#define SMB_Hdr(p) (char *)(p -> data) + +/* SMB Hdr def for File Sharing Protocol? From MS and Intel, */ +/* Intel PN 138446 Doc Version 2.0, Nov 7, 1988. This def also */ +/* applies to LANMAN1.0 as well as the Core Protocol */ +/* The spec states that wct and bcc must be present, even if 0 */ + +/* We define these as offsets into a char SMB[] array for the */ +/* sake of portability */ + +/* NOTE!. Some of the lenght defines, SMB__len do not include */ +/* the data that follows in the SMB packet, so the code will have to */ +/* take that into account. */ + +#define SMB_hdr_idf_offset 0 /* 0xFF,'SMB' 0-3 */ +#define SMB_hdr_com_offset 4 /* BYTE 4 */ +#define SMB_hdr_rcls_offset 5 /* BYTE 5 */ +#define SMB_hdr_reh_offset 6 /* BYTE 6 */ +#define SMB_hdr_err_offset 7 /* WORD 7 */ +#define SMB_hdr_reb_offset 9 /* BYTE 9 */ +#define SMB_hdr_flg_offset 9 /* same as reb ...*/ +#define SMB_hdr_res_offset 10 /* 7 WORDs 10 */ +#define SMB_hdr_res0_offset 10 /* WORD 10 */ +#define SMB_hdr_flg2_offset 10 /* WORD */ +#define SMB_hdr_res1_offset 12 /* WORD 12 */ +#define SMB_hdr_res2_offset 14 +#define SMB_hdr_res3_offset 16 +#define SMB_hdr_res4_offset 18 +#define SMB_hdr_res5_offset 20 +#define SMB_hdr_res6_offset 22 +#define SMB_hdr_tid_offset 24 +#define SMB_hdr_pid_offset 26 +#define SMB_hdr_uid_offset 28 +#define SMB_hdr_mid_offset 30 +#define SMB_hdr_wct_offset 32 + +#define SMB_hdr_len 33 /* 33 byte header? */ + +#define SMB_hdr_axc_offset 33 /* AndX Command */ +#define SMB_hdr_axr_offset 34 /* AndX Reserved */ +#define SMB_hdr_axo_offset 35 /* Offset from start to WCT of AndX cmd */ + +/* Format of the Negotiate Protocol SMB */ + +#define SMB_negp_bcc_offset 33 +#define SMB_negp_buf_offset 35 /* Where the buffer starts */ +#define SMB_negp_len 35 /* plus the data */ + +/* Format of the Negotiate Response SMB, for CoreProtocol, LM1.2 and */ +/* NT LM 0.12. wct will be 1 for CoreProtocol, 13 for LM 1.2, and 17 */ +/* for NT LM 0.12 */ + +#define SMB_negrCP_idx_offset 33 /* Response to the neg req */ +#define SMB_negrCP_bcc_offset 35 +#define SMB_negrLM_idx_offset 33 /* dialect index */ +#define SMB_negrLM_sec_offset 35 /* Security mode */ +#define SMB_sec_user_mask 0x01 /* 0 = share, 1 = user */ +#define SMB_sec_encrypt_mask 0x02 /* pick out encrypt */ +#define SMB_negrLM_mbs_offset 37 /* max buffer size */ +#define SMB_negrLM_mmc_offset 39 /* max mpx count */ +#define SMB_negrLM_mnv_offset 41 /* max number of VCs */ +#define SMB_negrLM_rm_offset 43 /* raw mode support bit vec*/ +#define SMB_read_raw_mask 0x01 +#define SMB_write_raw_mask 0x02 +#define SMB_negrLM_sk_offset 45 /* session key, 32 bits */ +#define SMB_negrLM_st_offset 49 /* Current server time */ +#define SMB_negrLM_sd_offset 51 /* Current server date */ +#define SMB_negrLM_stz_offset 53 /* Server Time Zone */ +#define SMB_negrLM_ekl_offset 55 /* encryption key length */ +#define SMB_negrLM_res_offset 57 /* reserved */ +#define SMB_negrLM_bcc_offset 59 /* bcc */ +#define SMB_negrLM_len 61 /* 61 bytes ? */ +#define SMB_negrLM_buf_offset 61 /* Where the fun begins */ + +#define SMB_negrNTLM_idx_offset 33 /* Selected protocol */ +#define SMB_negrNTLM_sec_offset 35 /* Security more */ +#define SMB_negrNTLM_mmc_offset 36 /* Different format above */ +#define SMB_negrNTLM_mnv_offset 38 /* Max VCs */ +#define SMB_negrNTLM_mbs_offset 40 /* MBS now a long */ +#define SMB_negrNTLM_mrs_offset 44 /* Max raw size */ +#define SMB_negrNTLM_sk_offset 48 /* Session Key */ +#define SMB_negrNTLM_cap_offset 52 /* Capabilities */ +#define SMB_negrNTLM_stl_offset 56 /* Server time low */ +#define SMB_negrNTLM_sth_offset 60 /* Server time high */ +#define SMB_negrNTLM_stz_offset 64 /* Server time zone */ +#define SMB_negrNTLM_ekl_offset 66 /* Encrypt key len */ +#define SMB_negrNTLM_bcc_offset 67 /* Bcc */ +#define SMB_negrNTLM_len 69 +#define SMB_negrNTLM_buf_offset 69 + +/* Offsets related to Tree Connect */ + +#define SMB_tcon_bcc_offset 33 +#define SMB_tcon_buf_offset 35 /* where the data is for tcon */ +#define SMB_tcon_len 35 /* plus the data */ + +#define SMB_tconr_mbs_offset 33 /* max buffer size */ +#define SMB_tconr_tid_offset 35 /* returned tree id */ +#define SMB_tconr_bcc_offset 37 +#define SMB_tconr_len 39 + +#define SMB_tconx_axc_offset 33 /* And X Command */ +#define SMB_tconx_axr_offset 34 /* reserved */ +#define SMB_tconx_axo_offset 35 /* Next command offset */ +#define SMB_tconx_flg_offset 37 /* Flags, bit0=1 means disc TID */ +#define SMB_tconx_pwl_offset 39 /* Password length */ +#define SMB_tconx_bcc_offset 41 /* bcc */ +#define SMB_tconx_buf_offset 43 /* buffer */ +#define SMB_tconx_len 43 /* up to data ... */ + +#define SMB_tconxr_axc_offset 33 /* Where the AndX Command is */ +#define SMB_tconxr_axr_offset 34 /* Reserved */ +#define SMB_tconxr_axo_offset 35 /* AndX offset location */ + +/* Offsets related to tree_disconnect */ + +#define SMB_tdis_bcc_offset 33 /* bcc */ +#define SMB_tdis_len 35 /* total len */ + +#define SMB_tdisr_bcc_offset 33 /* bcc */ +#define SMB_tdisr_len 35 + +/* Offsets related to Open Request */ + +#define SMB_open_mod_offset 33 /* Mode to open with */ +#define SMB_open_atr_offset 35 /* Attributes of file */ +#define SMB_open_bcc_offset 37 /* bcc */ +#define SMB_open_buf_offset 39 /* File name */ +#define SMB_open_len 39 /* Plus the file name */ + +#define SMB_openx_axc_offset 33 /* Next command */ +#define SMB_openx_axr_offset 34 /* Reserved */ +#define SMB_openx_axo_offset 35 /* offset of next wct */ +#define SMB_openx_flg_offset 37 /* Flags, bit0 = need more info */ +/* bit1 = exclusive oplock */ +/* bit2 = batch oplock */ +#define SMB_openx_mod_offset 39 /* mode to open with */ +#define SMB_openx_atr_offset 41 /* search attributes */ +#define SMB_openx_fat_offset 43 /* File attributes */ +#define SMB_openx_tim_offset 45 /* time and date of creat */ +#define SMB_openx_ofn_offset 49 /* Open function */ +#define SMB_openx_als_offset 51 /* Space to allocate on */ +#define SMB_openx_res_offset 55 /* reserved */ +#define SMB_openx_bcc_offset 63 /* bcc */ +#define SMB_openx_buf_offset 65 /* Where file name goes */ +#define SMB_openx_len 65 + +#define SMB_openr_fid_offset 33 /* FID returned */ +#define SMB_openr_atr_offset 35 /* Attributes opened with */ +#define SMB_openr_tim_offset 37 /* Last mod time of file */ +#define SMB_openr_fsz_offset 41 /* File size 4 bytes */ +#define SMB_openr_acc_offset 45 /* Access allowed */ +#define SMB_openr_bcc_offset 47 +#define SMB_openr_len 49 + +#define SMB_openxr_axc_offset 33 /* And X command */ +#define SMB_openxr_axr_offset 34 /* reserved */ +#define SMB_openxr_axo_offset 35 /* offset to next command */ +#define SMB_openxr_fid_offset 37 /* FID returned */ +#define SMB_openxr_fat_offset 39 /* File attributes returned*/ +#define SMB_openxr_tim_offset 41 /* File creation date etc */ +#define SMB_openxr_fsz_offset 45 /* Size of file */ +#define SMB_openxr_acc_offset 49 /* Access granted */ + +#define SMB_clos_fid_offset 33 /* FID to close */ +#define SMB_clos_tim_offset 35 /* Last mod time */ +#define SMB_clos_bcc_offset 39 /* bcc */ +#define SMB_clos_len 41 + +/* Offsets related to Write requests */ + +#define SMB_write_fid_offset 33 /* FID to write */ +#define SMB_write_cnt_offset 35 /* bytes to write */ +#define SMB_write_ofs_offset 37 /* location to write to */ +#define SMB_write_clf_offset 41 /* advisory count left */ +#define SMB_write_bcc_offset 43 /* bcc = data bytes + 3 */ +#define SMB_write_buf_offset 45 /* Data=0x01, len, data */ +#define SMB_write_len 45 /* plus the data ... */ + +#define SMB_writr_cnt_offset 33 /* Count of bytes written */ +#define SMB_writr_bcc_offset 35 /* bcc */ +#define SMB_writr_len 37 + +/* Offsets related to read requests */ + +#define SMB_read_fid_offset 33 /* FID of file to read */ +#define SMB_read_cnt_offset 35 /* count of words to read */ +#define SMB_read_ofs_offset 37 /* Where to read from */ +#define SMB_read_clf_offset 41 /* Advisory count to go */ +#define SMB_read_bcc_offset 43 +#define SMB_read_len 45 + +#define SMB_readr_cnt_offset 33 /* Count of bytes returned */ +#define SMB_readr_res_offset 35 /* 4 shorts reserved, 8 bytes */ +#define SMB_readr_bcc_offset 43 /* bcc */ +#define SMB_readr_bff_offset 45 /* buffer format char = 0x01 */ +#define SMB_readr_len_offset 46 /* buffer len */ +#define SMB_readr_len 45 /* length of the readr before data */ + +/* Offsets for Create file */ + +#define SMB_creat_atr_offset 33 /* Attributes of new file ... */ +#define SMB_creat_tim_offset 35 /* Time of creation */ +#define SMB_creat_dat_offset 37 /* 4004BCE :-) */ +#define SMB_creat_bcc_offset 39 /* bcc */ +#define SMB_creat_buf_offset 41 +#define SMB_creat_len 41 /* Before the data */ + +#define SMB_creatr_fid_offset 33 /* FID of created file */ + +/* Offsets for Delete file */ + +#define SMB_delet_sat_offset 33 /* search attribites */ +#define SMB_delet_bcc_offset 35 /* bcc */ +#define SMB_delet_buf_offset 37 +#define SMB_delet_len 37 + +/* Offsets for SESSION_SETUP_ANDX for both LM and NT LM protocols */ + +#define SMB_ssetpLM_mbs_offset 37 /* Max buffer Size, allow for AndX */ +#define SMB_ssetpLM_mmc_offset 39 /* max multiplex count */ +#define SMB_ssetpLM_vcn_offset 41 /* VC number if new VC */ +#define SMB_ssetpLM_snk_offset 43 /* Session Key */ +#define SMB_ssetpLM_pwl_offset 47 /* password length */ +#define SMB_ssetpLM_res_offset 49 /* reserved */ +#define SMB_ssetpLM_bcc_offset 53 /* bcc */ +#define SMB_ssetpLM_len 55 /* before data ... */ +#define SMB_ssetpLM_buf_offset 55 + +#define SMB_ssetpNTLM_mbs_offset 37 /* Max Buffer Size for NT LM 0.12 */ +/* and above */ +#define SMB_ssetpNTLM_mmc_offset 39 /* Max Multiplex count */ +#define SMB_ssetpNTLM_vcn_offset 41 /* VC Number */ +#define SMB_ssetpNTLM_snk_offset 43 /* Session key */ +#define SMB_ssetpNTLM_cipl_offset 47 /* Case Insensitive PW Len */ +#define SMB_ssetpNTLM_cspl_offset 49 /* Unicode pw len */ +#define SMB_ssetpNTLM_res_offset 51 /* reserved */ +#define SMB_ssetpNTLM_cap_offset 55 /* server capabilities */ +#define SMB_ssetpNTLM_bcc_offset 59 /* bcc */ +#define SMB_ssetpNTLM_len 61 /* before data */ +#define SMB_ssetpNTLM_buf_offset 61 + +#define SMB_ssetpr_axo_offset 35 /* Offset of next response ... */ +#define SMB_ssetpr_act_offset 37 /* action, bit 0 = 1 => guest */ +#define SMB_ssetpr_bcc_offset 39 /* bcc */ +#define SMB_ssetpr_buf_offset 41 /* Native OS etc */ + +/* Offsets for SMB create directory */ + +#define SMB_creatdir_bcc_offset 33 /* only a bcc here */ +#define SMB_creatdir_buf_offset 35 /* Where things start */ +#define SMB_creatdir_len 35 + +/* Offsets for SMB delete directory */ + +#define SMB_deletdir_bcc_offset 33 /* only a bcc here */ +#define SMB_deletdir_buf_offset 35 /* where things start */ +#define SMB_deletdir_len 35 + +/* Offsets for SMB check directory */ + +#define SMB_checkdir_bcc_offset 33 /* Only a bcc here */ +#define SMB_checkdir_buf_offset 35 /* where things start */ +#define SMB_checkdir_len 35 + +/* Offsets for SMB search */ + +#define SMB_search_mdc_offset 33 /* Max Dir ents to return */ +#define SMB_search_atr_offset 35 /* Search attributes */ +#define SMB_search_bcc_offset 37 /* bcc */ +#define SMB_search_buf_offset 39 /* where the action is */ +#define SMB_search_len 39 + +#define SMB_searchr_dec_offset 33 /* Dir ents returned */ +#define SMB_searchr_bcc_offset 35 /* bcc */ +#define SMB_searchr_buf_offset 37 /* Where the action starts */ +#define SMB_searchr_len 37 /* before the dir ents */ + +#define SMB_searchr_dirent_len 43 /* 53 bytes */ + +/* Defines for SMB transact and transact2 calls */ + +#define SMB_trans_tpc_offset 33 /* Total param count */ +#define SMB_trans_tdc_offset 35 /* total Data count */ +#define SMB_trans_mpc_offset 37 /* Max params bytes to return */ +#define SMB_trans_mdc_offset 39 /* Max data bytes to return */ +#define SMB_trans_msc_offset 41 /* Max setup words to return */ +#define SMB_trans_rs1_offset 42 /* Reserved byte */ +#define SMB_trans_flg_offset 43 /* flags */ +#define SMB_trans_tmo_offset 45 /* Timeout, long */ +#define SMB_trans_rs2_offset 49 /* Next reserved */ +#define SMB_trans_pbc_offset 51 /* Param Byte count in buf */ +#define SMB_trans_pbo_offset 53 /* Offset to param bytes */ +#define SMB_trans_dbc_offset 55 /* Data byte count in buf */ +#define SMB_trans_dbo_offset 57 /* Data byte offset */ +#define SMB_trans_suc_offset 59 /* Setup count - byte */ +#define SMB_trans_rs3_offset 60 /* Reserved to pad ... */ +#define SMB_trans_len 61 /* Up to setup, still need bcc */ + +#define SMB_transr_tpc_offset 33 /* Total param bytes returned */ +#define SMB_transr_tdc_offset 35 +#define SMB_transr_rs1_offset 37 +#define SMB_transr_pbc_offset 39 +#define SMB_transr_pbo_offset 41 +#define SMB_transr_pdi_offset 43 /* parameter displacement */ +#define SMB_transr_dbc_offset 45 +#define SMB_transr_dbo_offset 47 +#define SMB_transr_ddi_offset 49 +#define SMB_transr_suc_offset 51 +#define SMB_transr_rs2_offset 52 +#define SMB_transr_len 53 + +/* Bit masks for SMB Capabilities ... */ + +#define SMB_cap_raw_mode 0x0001 +#define SMB_cap_mpx_mode 0x0002 +#define SMB_cap_unicode 0x0004 +#define SMB_cap_large_files 0x0008 +#define SMB_cap_nt_smbs 0x0010 +#define SMB_rpc_remote_apis 0x0020 +#define SMB_cap_nt_status 0x0040 +#define SMB_cap_level_II_oplocks 0x0080 +#define SMB_cap_lock_and_read 0x0100 +#define SMB_cap_nt_find 0x0200 + +/* SMB LANMAN api call defines */ + +#define SMB_LMapi_SetUserInfo 0x0072 +#define SMB_LMapi_UserPasswordSet 0x0073 + +/* Structures and defines we use in the client interface */ + +/* The protocols we might support. Perhaps a bit ambitious, as only RFCNB */ +/* has any support so far 0(sometimes called NBT) */ + +typedef enum {SMB_RFCNB, SMB_IPXNB, SMB_NETBEUI, SMB_X25} SMB_Transport_Types; + +typedef enum {SMB_Con_FShare, SMB_Con_PShare, SMB_Con_IPC} SMB_Con_Types; + +typedef enum {SMB_State_NoState, SMB_State_Stopped, SMB_State_Started} SMB_State_Types; + +/* The following two arrays need to be in step! */ +/* We must make it possible for callers to specify these ... */ + + +extern int SMB_Types[]; + +typedef struct SMB_Status { + + union { + struct { + unsigned char ErrorClass; + unsigned char Reserved; + unsigned short Error; + } DosError; + unsigned int NtStatus; + } status; +} SMB_Status; + +#define SMBLIB_DEFAULT_DOMAIN "SMBlib_dom" +#define SMBLIB_DEFAULT_OSNAME "UNIX of some type" +#define SMBLIB_DEFAULT_LMTYPE "SMBlib LM2.1 minus a bit" +#define SMBLIB_MAX_XMIT 65535 + +#define SMB_Sec_Mode_Share 0 +#define SMB_Sec_Mode_User 1 + +typedef struct SMB_File_Def SMB_File; + +struct SMB_File_Def { + + SMB_Tree_Handle tree; + char filename[256]; /* We should malloc this ... */ + UWORD fid; + unsigned int lastmod; + unsigned int size; /* Could blow up if 64bit files supported */ + UWORD access; + off_t fileloc; + +}; + +/* global Variables for the library */ + +extern SMB_State_Types SMBlib_State; + +#ifndef SMBLIB_ERRNO +extern int SMBlib_errno; +extern int SMBlib_SMB_Error; /* last Error */ +#endif + +void SMB_Get_My_Name(char *name, int len); + +#endif /* _SMBLIB_PRIV_H_ */ diff --git a/libntlmauth/smblib-util.c b/lib/smblib/smblib-util.c similarity index 51% rename from libntlmauth/smblib-util.c rename to lib/smblib/smblib-util.c index deaaf1d36b..761b827f9b 100644 --- a/libntlmauth/smblib-util.c +++ b/lib/smblib/smblib-util.c @@ -1,48 +1,37 @@ -/* UNIX SMBlib NetBIOS implementation - * - * Version 1.0 - * SMBlib Utility 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 "config.h" -#include "libntlmauth/rfcnb.h" -#include "libntlmauth/smblib-priv.h" -#include "libntlmauth/smb-byteorder.h" -#include +/* UNIX SMBlib NetBIOS implementation -/* local functions */ -char * SMB_DOSTimToStr(int DOS_time); -char * SMB_AtrToStr(int attribs, int verbose); -int SMB_Get_Tree_MBS(SMB_Tree_Handle tree); -int SMB_Get_Max_Buf_Siz(SMB_Handle_Type Con_Handle); -int SMB_Get_Protocol_IDX(SMB_Handle_Type Con_Handle); -int SMB_Get_Protocol(SMB_Handle_Type Con_Handle); -int SMB_Figure_Protocol(char const *dialects[], int prot_index); -int SMB_TreeDisconnect(SMB_Tree_Handle Tree_Handle, int discard); -// int SMB_Get_Last_Error(void); -int SMB_Get_Last_SMB_Err(void); + Version 1.0 + SMBlib Utility Routines + Copyright (C) Richard Sharpe 1996 -/* global data structures */ +*/ + +/* + 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 "smblib/smblib.h" +#include "smblib/smblib-priv.h" +#include "rfcnb/rfcnb.h" + +#if HAVE_STRING_H +#include +#endif static int SMB_Types[] = {SMB_P_Core, SMB_P_CorePlus, @@ -59,25 +48,20 @@ static int SMB_Types[] = {SMB_P_Core, -1 }; -static char const *SMB_Prots[] = {"PC NETWORK PROGRAM 1.0", - "MICROSOFT NETWORKS 1.03", - "MICROSOFT NETWORKS 3.0", - "DOS LANMAN1.0", - "LANMAN1.0", - "DOS LM1.2X002", - "LM1.2X002", - "DOS LANMAN2.1", - "LANMAN2.1", - "Samba", - "NT LM 0.12", - "NT LANMAN 1.0", - NULL - }; +char *SMB_DOSTimToStr(int DOS_time); +char *SMB_AtrToStr(int attribs, BOOL verbose); +int SMB_Get_Tree_MBS(SMB_Tree_Handle tree); +int SMB_Get_Max_Buf_Siz(SMB_Handle_Type Con_Handle); +int SMB_Get_Protocol_IDX(SMB_Handle_Type Con_Handle); +int SMB_Get_Protocol(SMB_Handle_Type Con_Handle); +int SMB_Figure_Protocol(const char *dialects[], int prot_index); +int SMB_TreeDisconnect(SMB_Tree_Handle Tree_Handle, BOOL discard); +#if UNDEFINED /* Print out an SMB pkt in all its gory detail ... */ -#if 0 // DEAD CODE -void -SMB_Print_Pkt(FILE fd, RFCNB_Pkt * pkt, int command, int Offset, int Len) + +void SMB_Print_Pkt(FILE fd, RFCNB_Pkt *pkt, BOOL command, int Offset, int Len) + { /* Well, just how do we do this ... print it I suppose */ @@ -92,142 +76,144 @@ SMB_Print_Pkt(FILE fd, RFCNB_Pkt * pkt, int command, int Offset, int Len) /* etc */ } -#endif /* 0 */ +#endif /* Convert a DOS Date_Time to a local host type date time for printing */ -char * -SMB_DOSTimToStr(int DOS_time) +char *SMB_DOSTimToStr(int DOS_time) + { static char SMB_Time_Temp[48]; int DOS_sec, DOS_min, DOS_hour, DOS_day, DOS_month, DOS_year; SMB_Time_Temp[0] = 0; - DOS_sec = (DOS_time & 0x001F) * 2; - DOS_min = (DOS_time & 0x07E0) >> 5; - DOS_hour = ((DOS_time & 0xF800) >> 11); + DOS_sec = (DOS_time & 0x001F) * 2; + DOS_min = (DOS_time & 0x07E0) >> 5; + DOS_hour = ((DOS_time & 0xF800) >> 11); - DOS_day = (DOS_time & 0x001F0000) >> 16; + DOS_day = (DOS_time & 0x001F0000) >> 16; DOS_month = (DOS_time & 0x01E00000) >> 21; - DOS_year = ((DOS_time & 0xFE000000) >> 25) + 80; + DOS_year = ((DOS_time & 0xFE000000) >> 25) + 80; snprintf(SMB_Time_Temp, 48, "%2d/%02d/%2d %2d:%02d:%02d", DOS_day, DOS_month, - DOS_year, DOS_hour, DOS_min, DOS_sec); + DOS_year, DOS_hour, DOS_min, DOS_sec); - return (SMB_Time_Temp); + return(SMB_Time_Temp); } -/** - * Convert an attribute byte/word etc to a string ... We return a pointer - * to a static string which we guarantee is long enough. If verbose is - * true, we print out long form of strings ... - */ -char * -SMB_AtrToStr(int attribs, int verbose) +/* Convert an attribute byte/word etc to a string ... We return a pointer + to a static string which we guarantee is long enough. If verbose is + true, we print out long form of strings ... */ + +char *SMB_AtrToStr(int attribs, BOOL verbose) + { static char SMB_Attrib_Temp[128]; SMB_Attrib_Temp[0] = 0; if (attribs & SMB_FA_ROF) - strcat(SMB_Attrib_Temp, (verbose ? "Read Only " : "R")); + strcat(SMB_Attrib_Temp, (verbose?"Read Only ":"R")); if (attribs & SMB_FA_HID) - strcat(SMB_Attrib_Temp, (verbose ? "Hidden " : "H")); + strcat(SMB_Attrib_Temp, (verbose?"Hidden ":"H")); if (attribs & SMB_FA_SYS) - strcat(SMB_Attrib_Temp, (verbose ? "System " : "S")); + strcat(SMB_Attrib_Temp, (verbose?"System ":"S")); if (attribs & SMB_FA_VOL) - strcat(SMB_Attrib_Temp, (verbose ? "Volume " : "V")); + strcat(SMB_Attrib_Temp, (verbose?"Volume ":"V")); if (attribs & SMB_FA_DIR) - strcat(SMB_Attrib_Temp, (verbose ? "Directory " : "D")); + strcat(SMB_Attrib_Temp, (verbose?"Directory ":"D")); if (attribs & SMB_FA_ARC) - strcat(SMB_Attrib_Temp, (verbose ? "Archive " : "A")); + strcat(SMB_Attrib_Temp, (verbose?"Archive ":"A")); - return (SMB_Attrib_Temp); + return(SMB_Attrib_Temp); } -/** Pick up the Max Buffer Size from the Tree Structure ... */ -int -SMB_Get_Tree_MBS(SMB_Tree_Handle tree) +/* Pick up the Max Buffer Size from the Tree Structure ... */ + +int SMB_Get_Tree_MBS(SMB_Tree_Handle tree) + { if (tree != NULL) { - return (tree->mbs); + return(tree -> mbs); } else { - return (SMBlibE_BAD); + return(SMBlibE_BAD); } } -/** Pick up the Max buffer size */ -int -SMB_Get_Max_Buf_Siz(SMB_Handle_Type Con_Handle) +/* Pick up the Max buffer size */ + +int SMB_Get_Max_Buf_Siz(SMB_Handle_Type Con_Handle) + { if (Con_Handle != NULL) { - return (Con_Handle->max_xmit); + return(Con_Handle -> max_xmit); } else { - return (SMBlibE_BAD); + return(SMBlibE_BAD); } } - /* Pickup the protocol index from the connection structure */ -int -SMB_Get_Protocol_IDX(SMB_Handle_Type Con_Handle) + +int SMB_Get_Protocol_IDX(SMB_Handle_Type Con_Handle) + { if (Con_Handle != NULL) { - return (Con_Handle->prot_IDX); + return(Con_Handle -> prot_IDX); } else { - return (0xFFFF); /* Invalid protocol */ + return(0xFFFF); /* Invalid protocol */ } } -/** Pick up the protocol from the connection structure */ -int -SMB_Get_Protocol(SMB_Handle_Type Con_Handle) +/* Pick up the protocol from the connection structure */ + +int SMB_Get_Protocol(SMB_Handle_Type Con_Handle) + { if (Con_Handle != NULL) { - return (Con_Handle->protocol); + return(Con_Handle -> protocol); } else { - return (0xFFFF); /* Invalid protocol */ + return(0xFFFF); /* Invalid protocol */ } } -/** - * Figure out what protocol was accepted, given the list of dialect strings - * We offered, and the index back from the server. We allow for a user - * supplied list, and assume that it is a subset of our list - */ -int -SMB_Figure_Protocol(char const *dialects[], int prot_index) +/* Figure out what protocol was accepted, given the list of dialect strings */ +/* We offered, and the index back from the server. We allow for a user */ +/* supplied list, and assume that it is a subset of our list */ + +int SMB_Figure_Protocol(const char *dialects[], int prot_index) + { int i; - if (dialects == SMB_Prots) { /* The jobs is easy, just index into table */ + if (dialects == SMB_Prots) { /* The jobs is easy, just index into table */ - return (SMB_Types[prot_index]); - } else { /* Search through SMB_Prots looking for a match */ + return(SMB_Types[prot_index]); + } else { /* Search through SMB_Prots looking for a match */ for (i = 0; SMB_Prots[i] != NULL; i++) { - if (strcmp(dialects[prot_index], SMB_Prots[i]) == 0) { /* A match */ + if (strcmp(dialects[prot_index], SMB_Prots[i]) == 0) { /* A match */ - return (SMB_Types[i]); + return(SMB_Types[i]); } + } /* If we got here, then we are in trouble, because the protocol was not */ /* One we understand ... */ - return (SMB_P_Unknown); + return(SMB_P_Unknown); } @@ -238,9 +224,11 @@ SMB_Figure_Protocol(char const *dialects[], int prot_index) /* we return the index of the accepted protocol in NegProt, -1 indicates */ /* none acceptible, and our return value is 0 if ok, <0 if problems */ -int -SMB_Negotiate(SMB_Handle_Type Con_Handle, char const *Prots[]) +int SMB_Negotiate(SMB_Handle_Type Con_Handle, const char *Prots[]) + { +// struct SMB_Neg_Prot_Def *prot_pkt; +// struct SMB_Neg_Prot_Resp_Def *resp_pkt; struct RFCNB_Pkt *pkt; int prots_len, i, pkt_len, prot, alloc_len; char *p; @@ -250,7 +238,9 @@ SMB_Negotiate(SMB_Handle_Type Con_Handle, char const *Prots[]) prots_len = 0; for (i = 0; Prots[i] != NULL; i++) { - prots_len = prots_len + strlen(Prots[i]) + 2; /* Account for null etc */ + + prots_len = prots_len + strlen(Prots[i]) + 2; /* Account for null etc */ + } /* The -1 accounts for the one byte smb_buf we have because some systems */ @@ -262,137 +252,168 @@ SMB_Negotiate(SMB_Handle_Type Con_Handle, char const *Prots[]) /* Which is a problem, because the encryption key len eec may be long */ if (pkt_len < (SMB_hdr_wct_offset + (19 * 2) + 40)) { + alloc_len = SMB_hdr_wct_offset + (19 * 2) + 40; + } else { + alloc_len = pkt_len; + } - pkt = (struct RFCNB_Pkt *) RFCNB_Alloc_Pkt(alloc_len); + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(alloc_len); if (pkt == NULL) { + SMBlib_errno = SMBlibE_NoSpace; - return (SMBlibE_BAD); + return(SMBlibE_BAD); + } /* Now plug in the bits we need */ + memset(SMB_Hdr(pkt), 0, SMB_negp_len); - SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBnegprot; - SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle->pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid); SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0); - SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle->mid); - SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle->uid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid); *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0; + SSVAL(SMB_Hdr(pkt), SMB_negp_bcc_offset, prots_len); /* Now copy the prot strings in with the right stuff */ - p = (char *) (SMB_Hdr(pkt) + SMB_negp_buf_offset); + p = (char *)(SMB_Hdr(pkt) + SMB_negp_buf_offset); for (i = 0; Prots[i] != NULL; i++) { + *p = SMBdialectID; strcpy(p + 1, Prots[i]); - p = p + strlen(Prots[i]) + 2; /* Adjust len of p for null plus dialectID */ + p = p + strlen(Prots[i]) + 2; /* Adjust len of p for null plus dialectID */ + } /* Now send the packet and sit back ... */ - if (RFCNB_Send(Con_Handle->Trans_Connect, pkt, pkt_len) < 0) { + + if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) { + + #ifdef DEBUG fprintf(stderr, "Error sending negotiate protocol\n"); #endif + RFCNB_Free_Pkt(pkt); - SMBlib_errno = -SMBlibE_SendFailed; /* Failed, check lower layer errno */ - return (SMBlibE_BAD); + SMBlib_errno = -SMBlibE_SendFailed; /* Failed, check lower layer errno */ + return(SMBlibE_BAD); + } /* Now get the response ... */ - if (RFCNB_Recv(Con_Handle->Trans_Connect, pkt, alloc_len) < 0) { + + if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, alloc_len) < 0) { + #ifdef DEBUG fprintf(stderr, "Error receiving response to negotiate\n"); #endif + RFCNB_Free_Pkt(pkt); - SMBlib_errno = -SMBlibE_RecvFailed; /* Failed, check lower layer errno */ - return (SMBlibE_BAD); + SMBlib_errno = -SMBlibE_RecvFailed; /* Failed, check lower layer errno */ + return(SMBlibE_BAD); + } - if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ + if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ + #ifdef DEBUG fprintf(stderr, "SMB_Negotiate failed with errorclass = %i, Error Code = %i\n", CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); #endif + SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); RFCNB_Free_Pkt(pkt); SMBlib_errno = SMBlibE_Remote; - return (SMBlibE_BAD); + return(SMBlibE_BAD); + } if (SVAL(SMB_Hdr(pkt), SMB_negrCP_idx_offset) == 0xFFFF) { + #ifdef DEBUG fprintf(stderr, "None of our protocols was accepted ... "); #endif + RFCNB_Free_Pkt(pkt); SMBlib_errno = SMBlibE_NegNoProt; - return (SMBlibE_BAD); + return(SMBlibE_BAD); + } /* Now, unpack the info from the response, if any and evaluate the proto */ /* selected. We must make sure it is one we like ... */ - Con_Handle->prot_IDX = prot = SVAL(SMB_Hdr(pkt), SMB_negrCP_idx_offset); - Con_Handle->protocol = SMB_Figure_Protocol(Prots, prot); - if (Con_Handle->protocol == SMB_P_Unknown) { /* No good ... */ + Con_Handle -> prot_IDX = prot = SVAL(SMB_Hdr(pkt), SMB_negrCP_idx_offset); + Con_Handle -> protocol = SMB_Figure_Protocol(Prots, prot); + + if (Con_Handle -> protocol == SMB_P_Unknown) { /* No good ... */ + RFCNB_Free_Pkt(pkt); SMBlib_errno = SMBlibE_ProtUnknown; - return (SMBlibE_BAD); + return(SMBlibE_BAD); + } + switch (CVAL(SMB_Hdr(pkt), SMB_hdr_wct_offset)) { - case 0x01: /* No more info ... */ + case 0x01: /* No more info ... */ + break; - case 13: /* Up to and including LanMan 2.1 */ + case 13: /* Up to and including LanMan 2.1 */ - Con_Handle->Security = SVAL(SMB_Hdr(pkt), SMB_negrLM_sec_offset); - Con_Handle->encrypt_passwords = ((Con_Handle->Security & SMB_sec_encrypt_mask) != 0x00); - Con_Handle->Security = Con_Handle->Security & SMB_sec_user_mask; + Con_Handle -> Security = SVAL(SMB_Hdr(pkt), SMB_negrLM_sec_offset); + Con_Handle -> encrypt_passwords = ((Con_Handle -> Security & SMB_sec_encrypt_mask) != 0x00); + Con_Handle -> Security = Con_Handle -> Security & SMB_sec_user_mask; - Con_Handle->max_xmit = SVAL(SMB_Hdr(pkt), SMB_negrLM_mbs_offset); - Con_Handle->MaxMPX = SVAL(SMB_Hdr(pkt), SMB_negrLM_mmc_offset); - Con_Handle->MaxVC = SVAL(SMB_Hdr(pkt), SMB_negrLM_mnv_offset); - Con_Handle->Raw_Support = SVAL(SMB_Hdr(pkt), SMB_negrLM_rm_offset); - Con_Handle->SessionKey = IVAL(SMB_Hdr(pkt), SMB_negrLM_sk_offset); - Con_Handle->SvrTZ = SVAL(SMB_Hdr(pkt), SMB_negrLM_stz_offset); - Con_Handle->Encrypt_Key_Len = SVAL(SMB_Hdr(pkt), SMB_negrLM_ekl_offset); + Con_Handle -> max_xmit = SVAL(SMB_Hdr(pkt), SMB_negrLM_mbs_offset); + Con_Handle -> MaxMPX = SVAL(SMB_Hdr(pkt), SMB_negrLM_mmc_offset); + Con_Handle -> MaxVC = SVAL(SMB_Hdr(pkt), SMB_negrLM_mnv_offset); + Con_Handle -> Raw_Support = SVAL(SMB_Hdr(pkt), SMB_negrLM_rm_offset); + Con_Handle -> SessionKey = IVAL(SMB_Hdr(pkt), SMB_negrLM_sk_offset); + Con_Handle -> SvrTZ = SVAL(SMB_Hdr(pkt), SMB_negrLM_stz_offset); + Con_Handle -> Encrypt_Key_Len = SVAL(SMB_Hdr(pkt), SMB_negrLM_ekl_offset); p = (SMB_Hdr(pkt) + SMB_negrLM_buf_offset); - fprintf(stderr, "%8s", (char *) (SMB_Hdr(pkt) + SMB_negrLM_buf_offset)); memcpy(Con_Handle->Encrypt_Key, p, 8); - p = (SMB_Hdr(pkt) + SMB_negrLM_buf_offset + Con_Handle->Encrypt_Key_Len); + p = (SMB_Hdr(pkt) + SMB_negrLM_buf_offset + Con_Handle -> Encrypt_Key_Len); + + strncpy(p, Con_Handle -> Svr_PDom, sizeof(Con_Handle -> Svr_PDom) - 1); - strncpy(p, Con_Handle->Svr_PDom, sizeof(Con_Handle->Svr_PDom) - 1); break; - case 17: /* NT LM 0.12 and LN LM 1.0 */ + case 17: /* NT LM 0.12 and LN LM 1.0 */ - Con_Handle->Security = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_sec_offset); - Con_Handle->encrypt_passwords = ((Con_Handle->Security & SMB_sec_encrypt_mask) != 0x00); - Con_Handle->Security = Con_Handle->Security & SMB_sec_user_mask; + Con_Handle -> Security = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_sec_offset); + Con_Handle -> encrypt_passwords = ((Con_Handle -> Security & SMB_sec_encrypt_mask) != 0x00); + Con_Handle -> Security = Con_Handle -> Security & SMB_sec_user_mask; - Con_Handle->max_xmit = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_mbs_offset); - Con_Handle->MaxMPX = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_mmc_offset); - Con_Handle->MaxVC = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_mnv_offset); - Con_Handle->MaxRaw = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_mrs_offset); - Con_Handle->SessionKey = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_sk_offset); - Con_Handle->SvrTZ = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_stz_offset); - Con_Handle->Encrypt_Key_Len = CVAL(SMB_Hdr(pkt), SMB_negrNTLM_ekl_offset); + Con_Handle -> max_xmit = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_mbs_offset); + Con_Handle -> MaxMPX = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_mmc_offset); + Con_Handle -> MaxVC = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_mnv_offset); + Con_Handle -> MaxRaw = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_mrs_offset); + Con_Handle -> SessionKey = IVAL(SMB_Hdr(pkt), SMB_negrNTLM_sk_offset); + Con_Handle -> SvrTZ = SVAL(SMB_Hdr(pkt), SMB_negrNTLM_stz_offset); + Con_Handle -> Encrypt_Key_Len = CVAL(SMB_Hdr(pkt), SMB_negrNTLM_ekl_offset); p = (SMB_Hdr(pkt) + SMB_negrNTLM_buf_offset); memcpy(Con_Handle->Encrypt_Key, p, 8); - p = (SMB_Hdr(pkt) + SMB_negrNTLM_buf_offset + Con_Handle->Encrypt_Key_Len); - strncpy(p, Con_Handle->Svr_PDom, sizeof(Con_Handle->Svr_PDom) - 1); + p = (SMB_Hdr(pkt) + SMB_negrLM_buf_offset + Con_Handle -> Encrypt_Key_Len); + + strncpy(p, Con_Handle -> Svr_PDom, sizeof(Con_Handle -> Svr_PDom) - 1); break; @@ -411,17 +432,16 @@ SMB_Negotiate(SMB_Handle_Type Con_Handle, char const *Prots[]) #endif RFCNB_Free_Pkt(pkt); - return (0); + return(0); } /* Get our hostname */ -void -SMB_Get_My_Name(char *name, int len) -{ +void SMB_Get_My_Name(char *name, int len) - if (gethostname(name, len) < 0) { /* Error getting name */ +{ + if (gethostname(name, len) < 0) { /* Error getting name */ strncpy(name, "unknown", len); @@ -432,20 +452,23 @@ SMB_Get_My_Name(char *name, int len) perror(""); #endif + } else { + char *address; + /* only keep the portion up to the first "." */ + if (NULL != (address = strchr(name, '.'))) { + *address = '\0'; /* truncate at first '.' */ + } } - /* only keep the portion up to the first "." */ - - } /* Send a TCON to the remote server ... */ -SMB_Tree_Handle -SMB_TreeConnect(SMB_Handle_Type Con_Handle, - SMB_Tree_Handle Tree_Handle, - char *path, - char *password, - char const *device) +SMB_Tree_Handle SMB_TreeConnect(SMB_Handle_Type Con_Handle, + SMB_Tree_Handle Tree_Handle, + const char *path, + const char *password, + const char *device) + { struct RFCNB_Pkt *pkt; int param_len, pkt_len; @@ -454,16 +477,17 @@ SMB_TreeConnect(SMB_Handle_Type Con_Handle, /* Figure out how much space is needed for path, password, dev ... */ - if ((path == NULL) || (password == NULL) || (device == NULL)) { + if ((path == NULL) | (password == NULL) | (device == NULL)) { #ifdef DEBUG fprintf(stderr, "Bad parameter passed to SMB_TreeConnect\n"); #endif SMBlib_errno = SMBlibE_BadParam; - return (NULL); + return(NULL); } + /* The + 2 is because of the \0 and the marker ... */ param_len = strlen(path) + 2 + strlen(password) + 2 + strlen(device) + 2; @@ -473,25 +497,26 @@ SMB_TreeConnect(SMB_Handle_Type Con_Handle, pkt_len = SMB_tcon_len + param_len; - pkt = (struct RFCNB_Pkt *) RFCNB_Alloc_Pkt(pkt_len); + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); if (pkt == NULL) { SMBlib_errno = SMBlibE_NoSpace; - return (NULL); /* Should handle the error */ + return(NULL); /* Should handle the error */ } + /* Now allocate a tree for this to go into ... */ if (Tree_Handle == NULL) { - tree = (SMB_Tree_Handle) malloc(sizeof(struct SMB_Tree_Structure)); + tree = (SMB_Tree_Handle)malloc(sizeof(struct SMB_Tree_Structure)); if (tree == NULL) { RFCNB_Free_Pkt(pkt); SMBlib_errno = SMBlibE_NoSpace; - return (NULL); + return(NULL); } } else { @@ -500,27 +525,27 @@ SMB_TreeConnect(SMB_Handle_Type Con_Handle, } - tree->next = tree->prev = NULL; - tree->con = Con_Handle; - strncpy(tree->path, path, sizeof(tree->path)); - strncpy(tree->device_type, device, sizeof(tree->device_type)); + tree -> next = tree -> prev = NULL; + tree -> con = Con_Handle; + strncpy(tree -> path, path, sizeof(tree -> path)); + strncpy(tree -> device_type, device, sizeof(tree -> device_type)); /* Now plug in the values ... */ memset(SMB_Hdr(pkt), 0, SMB_tcon_len); - SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBtcon; - SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle->pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid); SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0); - SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle->mid); - SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle->uid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid); *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0; SSVAL(SMB_Hdr(pkt), SMB_tcon_bcc_offset, param_len); /* Now copy the param strings in with the right stuff */ - p = (char *) (SMB_Hdr(pkt) + SMB_tcon_buf_offset); + p = (char *)(SMB_Hdr(pkt) + SMB_tcon_buf_offset); *p = SMBasciiID; strcpy(p + 1, path); p = p + strlen(path) + 2; @@ -532,7 +557,7 @@ SMB_TreeConnect(SMB_Handle_Type Con_Handle, /* Now send the packet and sit back ... */ - if (RFCNB_Send(Con_Handle->Trans_Connect, pkt, pkt_len) < 0) { + if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) { #ifdef DEBUG fprintf(stderr, "Error sending TCon request\n"); @@ -542,12 +567,13 @@ SMB_TreeConnect(SMB_Handle_Type Con_Handle, free(tree); RFCNB_Free_Pkt(pkt); SMBlib_errno = -SMBlibE_SendFailed; - return (NULL); + return(NULL); } + /* Now get the response ... */ - if (RFCNB_Recv(Con_Handle->Trans_Connect, pkt, pkt_len) < 0) { + if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) { #ifdef DEBUG fprintf(stderr, "Error receiving response to TCon\n"); @@ -557,12 +583,13 @@ SMB_TreeConnect(SMB_Handle_Type Con_Handle, free(tree); RFCNB_Free_Pkt(pkt); SMBlib_errno = -SMBlibE_RecvFailed; - return (NULL); + return(NULL); } + /* Check out the response type ... */ - if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ + if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ #ifdef DEBUG fprintf(stderr, "SMB_TCon failed with errorclass = %i, Error Code = %i\n", @@ -575,69 +602,71 @@ SMB_TreeConnect(SMB_Handle_Type Con_Handle, SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); RFCNB_Free_Pkt(pkt); SMBlib_errno = SMBlibE_Remote; - return (NULL); + return(NULL); } - tree->tid = SVAL(SMB_Hdr(pkt), SMB_tconr_tid_offset); - tree->mbs = SVAL(SMB_Hdr(pkt), SMB_tconr_mbs_offset); + + tree -> tid = SVAL(SMB_Hdr(pkt), SMB_tconr_tid_offset); + tree -> mbs = SVAL(SMB_Hdr(pkt), SMB_tconr_mbs_offset); #ifdef DEBUG fprintf(stderr, "TConn succeeded, with TID=%i, Max Xmit=%i\n", - tree->tid, tree->mbs); + tree -> tid, tree -> mbs); #endif /* Now link the Tree to the Server Structure ... */ - if (Con_Handle->first_tree == NULL) { + if (Con_Handle -> first_tree == NULL) { - Con_Handle->first_tree = tree; - Con_Handle->last_tree = tree; + Con_Handle -> first_tree = tree; + Con_Handle -> last_tree = tree; } else { - Con_Handle->last_tree->next = tree; - tree->prev = Con_Handle->last_tree; - Con_Handle->last_tree = tree; + Con_Handle -> last_tree -> next = tree; + tree -> prev = Con_Handle -> last_tree; + Con_Handle -> last_tree = tree; } RFCNB_Free_Pkt(pkt); - return (tree); + return(tree); } -int -SMB_TreeDisconnect(SMB_Tree_Handle Tree_Handle, int discard) +int SMB_TreeDisconnect(SMB_Tree_Handle Tree_Handle, BOOL discard) + { struct RFCNB_Pkt *pkt; int pkt_len; pkt_len = SMB_tdis_len; - pkt = (struct RFCNB_Pkt *) RFCNB_Alloc_Pkt(pkt_len); + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); if (pkt == NULL) { SMBlib_errno = SMBlibE_NoSpace; - return (SMBlibE_BAD); /* Should handle the error */ + return(SMBlibE_BAD); /* Should handle the error */ } + /* Now plug in the values ... */ memset(SMB_Hdr(pkt), 0, SMB_tdis_len); - SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBtdis; - SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Tree_Handle->con->pid); - SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Tree_Handle->con->mid); - SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Tree_Handle->con->uid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Tree_Handle -> con -> pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Tree_Handle -> con -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Tree_Handle -> con -> uid); *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 0; - SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, Tree_Handle->tid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, Tree_Handle -> tid); SSVAL(SMB_Hdr(pkt), SMB_tcon_bcc_offset, 0); /* Now send the packet and sit back ... */ - if (RFCNB_Send(Tree_Handle->con->Trans_Connect, pkt, pkt_len) < 0) { + if (RFCNB_Send(Tree_Handle -> con -> Trans_Connect, pkt, pkt_len) < 0) { #ifdef DEBUG fprintf(stderr, "Error sending TDis request\n"); @@ -645,12 +674,13 @@ SMB_TreeDisconnect(SMB_Tree_Handle Tree_Handle, int discard) RFCNB_Free_Pkt(pkt); SMBlib_errno = -SMBlibE_SendFailed; - return (SMBlibE_BAD); + return(SMBlibE_BAD); } + /* Now get the response ... */ - if (RFCNB_Recv(Tree_Handle->con->Trans_Connect, pkt, pkt_len) < 0) { + if (RFCNB_Recv(Tree_Handle -> con -> Trans_Connect, pkt, pkt_len) < 0) { #ifdef DEBUG fprintf(stderr, "Error receiving response to TCon\n"); @@ -658,12 +688,13 @@ SMB_TreeDisconnect(SMB_Tree_Handle Tree_Handle, int discard) RFCNB_Free_Pkt(pkt); SMBlib_errno = -SMBlibE_RecvFailed; - return (SMBlibE_BAD); + return(SMBlibE_BAD); } + /* Check out the response type ... */ - if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ + if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ #ifdef DEBUG fprintf(stderr, "SMB_TDis failed with errorclass = %i, Error Code = %i\n", @@ -674,11 +705,12 @@ SMB_TreeDisconnect(SMB_Tree_Handle Tree_Handle, int discard) SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); RFCNB_Free_Pkt(pkt); SMBlib_errno = SMBlibE_Remote; - return (SMBlibE_BAD); + return(SMBlibE_BAD); } - Tree_Handle->tid = 0xFFFF; /* Invalid TID */ - Tree_Handle->mbs = 0; /* Invalid */ + + Tree_Handle -> tid = 0xFFFF; /* Invalid TID */ + Tree_Handle -> mbs = 0; /* Invalid */ #ifdef DEBUG @@ -688,42 +720,43 @@ SMB_TreeDisconnect(SMB_Tree_Handle Tree_Handle, int discard) /* What about the tree handle ? */ - if (discard) { /* Unlink it and free it ... */ + if (discard == TRUE) { /* Unlink it and free it ... */ - if (Tree_Handle->next == NULL) - Tree_Handle->con->first_tree = Tree_Handle->prev; + if (Tree_Handle -> next == NULL) + Tree_Handle -> con -> first_tree = Tree_Handle -> prev; else - Tree_Handle->next->prev = Tree_Handle->prev; + Tree_Handle -> next -> prev = Tree_Handle -> prev; - if (Tree_Handle->prev == NULL) - Tree_Handle->con->last_tree = Tree_Handle->next; + if (Tree_Handle -> prev == NULL) + Tree_Handle -> con -> last_tree = Tree_Handle -> next; else - Tree_Handle->prev->next = Tree_Handle->next; + Tree_Handle -> prev -> next = Tree_Handle -> next; } + RFCNB_Free_Pkt(pkt); - return (0); + return(0); } /* Pick up the last LMBlib error ... */ -int -SMB_Get_Last_Error() +int SMB_Get_Last_Error() + { - return (SMBlib_errno); + return(SMBlib_errno); } -/** Pick up the last error returned in an SMB packet - * We will need macros to extract error class and error code - */ -int -SMB_Get_Last_SMB_Err() +/* Pick up the last error returned in an SMB packet */ +/* We will need macros to extract error class and error code */ + +int SMB_Get_Last_SMB_Err() + { - return (SMBlib_SMB_Error); + return(SMBlib_SMB_Error); } @@ -731,7 +764,7 @@ SMB_Get_Last_SMB_Err() /* Keep this table in sync with the message codes in smblib-common.h */ -static char const *SMBlib_Error_Messages[] = { +static const char *SMBlib_Error_Messages[] = { "Request completed sucessfully.", "Server returned a non-zero SMB Error Class and Code.", @@ -751,29 +784,29 @@ static char const *SMBlib_Error_Messages[] = { NULL }; -int -SMB_Get_Error_Msg(int msg, char *msgbuf, int len) +void SMB_Get_Error_Msg(int msg, char *msgbuf, int len) + { if (msg >= 0) { strncpy(msgbuf, - SMBlib_Error_Messages[msg > SMBlibE_NoSuchMsg ? SMBlibE_NoSuchMsg : msg], + SMBlib_Error_Messages[msg>SMBlibE_NoSuchMsg?SMBlibE_NoSuchMsg:msg], len - 1); - msgbuf[len - 1] = 0; /* Make sure it is a string */ - } else { /* Add the lower layer message ... */ + msgbuf[len - 1] = 0; /* Make sure it is a string */ + } else { /* Add the lower layer message ... */ char prot_msg[1024]; - msg = -msg; /* Make it positive */ + msg = -msg; /* Make it positive */ strncpy(msgbuf, - SMBlib_Error_Messages[msg > SMBlibE_NoSuchMsg ? SMBlibE_NoSuchMsg : msg], + SMBlib_Error_Messages[msg>SMBlibE_NoSuchMsg?SMBlibE_NoSuchMsg:msg], len - 1); - msgbuf[len - 1] = 0; /* make sure it is a string */ + msgbuf[len - 1] = 0; /* make sure it is a string */ - if (strlen(msgbuf) < len) { /* If there is space, put rest in */ + if (strlen(msgbuf) < len) { /* If there is space, put rest in */ strncat(msgbuf, "\n\t", len - strlen(msgbuf)); @@ -783,5 +816,5 @@ SMB_Get_Error_Msg(int msg, char *msgbuf, int len) } } - return 0; + } diff --git a/lib/smblib/smblib.c b/lib/smblib/smblib.c new file mode 100644 index 0000000000..a9400a066f --- /dev/null +++ b/lib/smblib/smblib.c @@ -0,0 +1,600 @@ +#include "config.h" + +/* UNIX SMBlib NetBIOS implementation + + Version 1.0 + SMBlib 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. +*/ + +int SMBlib_errno; +int SMBlib_SMB_Error; +#define SMBLIB_ERRNO + +#include "smblib/smblib.h" +#include "smblib/smblib-priv.h" +#include "rfcnb/rfcnb.h" + +#include +#if HAVE_STRING_H +#include +#endif + +SMB_State_Types SMBlib_State; + +const char *SMB_Prots[] = {"PC NETWORK PROGRAM 1.0", + "MICROSOFT NETWORKS 1.03", + "MICROSOFT NETWORKS 3.0", + "DOS LANMAN1.0", + "LANMAN1.0", + "DOS LM1.2X002", + "LM1.2X002", + "DOS LANMAN2.1", + "LANMAN2.1", + "Samba", + "NT LM 0.12", + "NT LANMAN 1.0", + NULL + }; + +int SMB_Term(void); +int SMBlib_Set_Sock_NoDelay(SMB_Handle_Type Con_Handle, BOOL yn); + +/* Initialize the SMBlib package */ + +int SMB_Init() + +{ + + SMBlib_State = SMB_State_Started; + + signal(SIGPIPE, SIG_IGN); /* Ignore these ... */ + + /* If SMBLIB_Instrument is defines, turn on the instrumentation stuff */ +#ifdef SMBLIB_INSTRUMENT + + SMBlib_Instrument_Init(); + +#endif + + return 0; + +} + +int SMB_Term() + +{ + +#ifdef SMBLIB_INSTRUMENT + + SMBlib_Instrument_Term(); /* Clean up and print results */ + +#endif + + return 0; + +} + +/* SMB_Create: Create a connection structure and return for later use */ +/* We have other helper routines to set variables */ + +SMB_Handle_Type SMB_Create_Con_Handle() + +{ + + SMBlib_errno = SMBlibE_NotImpl; + return(NULL); + +} + +int SMBlib_Set_Sock_NoDelay(SMB_Handle_Type Con_Handle, BOOL yn) + +{ + + + if (RFCNB_Set_Sock_NoDelay(Con_Handle -> Trans_Connect, yn) < 0) { + +#ifdef DEBUG +#endif + + fprintf(stderr, "Setting no-delay on TCP socket failed ...\n"); + + } + + return(0); + +} + +/* SMB_Connect_Server: Connect to a server, but don't negotiate protocol */ +/* or anything else ... */ + +SMB_Handle_Type SMB_Connect_Server(SMB_Handle_Type Con_Handle, + char *server, const char *NTdomain) + +{ + SMB_Handle_Type con; + char called[80], calling[80], *address; + int i; + + /* Get a connection structure if one does not exist */ + + con = Con_Handle; + + if (Con_Handle == NULL) { + + if ((con = (struct SMB_Connect_Def *)malloc(sizeof(struct SMB_Connect_Def))) == NULL) { + + + SMBlib_errno = SMBlibE_NoSpace; + return NULL; + } + + } + + /* Init some things ... */ + + strcpy(con -> service, ""); + strcpy(con -> username, ""); + strcpy(con -> password, ""); + strcpy(con -> sock_options, ""); + strcpy(con -> address, ""); + strcpy(con -> desthost, server); + strcpy(con -> PDomain, NTdomain); + strcpy(con -> OSName, SMBLIB_DEFAULT_OSNAME); + strcpy(con -> LMType, SMBLIB_DEFAULT_LMTYPE); + con -> first_tree = con -> last_tree = NULL; + + SMB_Get_My_Name(con -> myname, sizeof(con -> myname)); + + con -> port = 0; /* No port selected */ + + /* Get some things we need for the SMB Header */ + + con -> pid = getpid(); + con -> mid = con -> pid; /* This will do for now ... */ + con -> uid = 0; /* Until we have done a logon, no uid ... */ + con -> gid = getgid(); + + /* Now connect to the remote end, but first upper case the name of the + service we are going to call, sine some servers want it in uppercase */ + + for (i=0; i < strlen(server); i++) + called[i] = toupper(server[i]); + + called[strlen(server)] = 0; /* Make it a string */ + + for (i=0; i < strlen(con -> myname); i++) + calling[i] = toupper(con -> myname[i]); + + calling[strlen(con -> myname)] = 0; /* Make it a string */ + + if (strcmp(con -> address, "") == 0) + address = con -> desthost; + else + address = con -> address; + + con -> Trans_Connect = RFCNB_Call(called, + calling, + address, /* Protocol specific */ + con -> port); + + /* Did we get one? */ + + if (con -> Trans_Connect == NULL) { + + if (Con_Handle == NULL) { + Con_Handle = NULL; + free(con); + } + SMBlib_errno = -SMBlibE_CallFailed; + return NULL; + + } + + return(con); + +} + +/* SMB_Connect: Connect to the indicated server */ +/* If Con_Handle == NULL then create a handle and connect, otherwise */ +/* use the handle passed */ + +const char *SMB_Prots_Restrict[] = {"PC NETWORK PROGRAM 1.0", + NULL + }; + + +SMB_Handle_Type SMB_Connect(SMB_Handle_Type Con_Handle, + SMB_Tree_Handle *tree, + char *service, + char *username, + char *password) + +{ + SMB_Handle_Type con; + char *host, *address; + char temp[80], called[80], calling[80]; + int i; + + /* Get a connection structure if one does not exist */ + + con = Con_Handle; + + if (Con_Handle == NULL) { + + if ((con = (struct SMB_Connect_Def *)malloc(sizeof(struct SMB_Connect_Def))) == NULL) { + + SMBlib_errno = SMBlibE_NoSpace; + return NULL; + } + + } + + /* Init some things ... */ + + strcpy(con -> service, service); + strcpy(con -> username, username); + strcpy(con -> password, password); + strcpy(con -> sock_options, ""); + strcpy(con -> address, ""); + strcpy(con -> PDomain, SMBLIB_DEFAULT_DOMAIN); + strcpy(con -> OSName, SMBLIB_DEFAULT_OSNAME); + strcpy(con -> LMType, SMBLIB_DEFAULT_LMTYPE); + con -> first_tree = con -> last_tree = NULL; + + SMB_Get_My_Name(con -> myname, sizeof(con -> myname)); + + con -> port = 0; /* No port selected */ + + /* Get some things we need for the SMB Header */ + + con -> pid = getpid(); + con -> mid = con -> pid; /* This will do for now ... */ + con -> uid = 0; /* Until we have done a logon, no uid */ + con -> gid = getgid(); + + /* Now figure out the host portion of the service */ + + strcpy(temp, service); + host = strtok(temp, "/\\"); /* Separate host name portion */ + strcpy(con -> desthost, host); + + /* Now connect to the remote end, but first upper case the name of the + service we are going to call, sine some servers want it in uppercase */ + + for (i=0; i < strlen(host); i++) + called[i] = toupper(host[i]); + + called[strlen(host)] = 0; /* Make it a string */ + + for (i=0; i < strlen(con -> myname); i++) + calling[i] = toupper(con -> myname[i]); + + calling[strlen(con -> myname)] = 0; /* Make it a string */ + + if (strcmp(con -> address, "") == 0) + address = con -> desthost; + else + address = con -> address; + + con -> Trans_Connect = RFCNB_Call(called, + calling, + address, /* Protocol specific */ + con -> port); + + /* Did we get one? */ + + if (con -> Trans_Connect == NULL) { + + if (Con_Handle == NULL) { + free(con); + Con_Handle = NULL; + } + SMBlib_errno = -SMBlibE_CallFailed; + return NULL; + + } + + /* Now, negotiate the protocol */ + + if (SMB_Negotiate(con, SMB_Prots_Restrict) < 0) { + + /* Hmmm what should we do here ... We have a connection, but could not + negotiate ... */ + + return NULL; + + } + + /* Now connect to the service ... */ + + if ((*tree = SMB_TreeConnect(con, NULL, service, password, "A:")) == NULL) { + + return NULL; + + } + + return(con); + +} + +/* Logon to the server. That is, do a session setup if we can. We do not do */ +/* Unicode yet! */ + +int SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName, + char *PassWord, const char *NtDomain, int PreCrypted) + +{ + struct RFCNB_Pkt *pkt; + int param_len, pkt_len, pass_len; + char *p, pword[128]; + + /* First we need a packet etc ... but we need to know what protocol has */ + /* been negotiated to figure out if we can do it and what SMB format to */ + /* use ... */ + + if (Con_Handle -> protocol < SMB_P_LanMan1) { + + SMBlib_errno = SMBlibE_ProtLow; + return(SMBlibE_BAD); + + } + + if (PreCrypted) { + pass_len = 24; + memcpy(pword, PassWord, 24); + } else { + strcpy(pword, PassWord); +#ifdef PAM_SMB_ENC_PASS + if (Con_Handle->encrypt_passwords) { + pass_len = 24; + SMBencrypt((uchar *) PassWord, (uchar *) Con_Handle->Encrypt_Key, (uchar *) pword); + } else +#endif + pass_len = strlen(pword); + } + + /* Now build the correct structure */ + + if (Con_Handle -> protocol < SMB_P_NT1) { + + /* We don't handle encrypted passwords ... */ + + param_len = strlen(UserName) + 1 + pass_len + 1 + + (NtDomain!=NULL ? strlen(NtDomain) : strlen(Con_Handle->PDomain)) + 1 + + strlen(Con_Handle -> OSName) + 1; + + pkt_len = SMB_ssetpLM_len + param_len; + + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); + + if (pkt == NULL) { + + SMBlib_errno = SMBlibE_NoSpace; + return(SMBlibE_BAD); /* Should handle the error */ + + } + + memset(SMB_Hdr(pkt), 0, SMB_ssetpLM_len); + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX; + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid); + *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 10; + *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF; /* No extra command */ + SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0); + + SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mbs_offset, SMBLIB_MAX_XMIT); + SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mmc_offset, 2); + SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_vcn_offset, Con_Handle -> pid); + SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_snk_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_pwl_offset, pass_len + 1); + SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_res_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_bcc_offset, param_len); + + /* Now copy the param strings in with the right stuff */ + + p = (char *)(SMB_Hdr(pkt) + SMB_ssetpLM_buf_offset); + + /* Copy in password, then the rest. Password has a null at end */ + + memcpy(p, pword, pass_len); + + p = p + pass_len + 1; + + strcpy(p, UserName); + p = p + strlen(UserName); + *p = 0; + + p = p + 1; + + if (NtDomain != NULL) { + strcpy(p, Con_Handle -> PDomain); + p = p + strlen(Con_Handle -> PDomain); + } else { + strcpy(p, NtDomain); + p = p + strlen(NtDomain); + } + *p = 0; + p = p + 1; + + strcpy(p, Con_Handle -> OSName); + p = p + strlen(Con_Handle -> OSName); + *p = 0; + + } else { + + /* We don't admit to UNICODE support ... */ + + param_len = strlen(UserName) + 1 + pass_len + + strlen(Con_Handle -> PDomain) + 1 + + strlen(Con_Handle -> OSName) + 1 + + strlen(Con_Handle -> LMType) + 1; + + pkt_len = SMB_ssetpNTLM_len + param_len; + + pkt = (struct RFCNB_Pkt *)RFCNB_Alloc_Pkt(pkt_len); + + if (pkt == NULL) { + + SMBlib_errno = SMBlibE_NoSpace; + return(-1); /* Should handle the error */ + + } + + memset(SMB_Hdr(pkt), 0, SMB_ssetpNTLM_len); + SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ + *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX; + SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle -> pid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle -> mid); + SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle -> uid); + *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 13; + *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF; /* No extra command */ + SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0); + + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mbs_offset, SMBLIB_MAX_XMIT); + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mmc_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_vcn_offset, 1); /* Thanks Tridge! */ + SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_snk_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cipl_offset, pass_len); + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cspl_offset, 0); + SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_res_offset, 0); + SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cap_offset, 0); + SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_bcc_offset, param_len); + + /* Now copy the param strings in with the right stuff */ + + p = (char *)(SMB_Hdr(pkt) + SMB_ssetpNTLM_buf_offset); + + /* Copy in password, then the rest. Password has no null at end */ + + memcpy(p, pword, pass_len); + + p = p + pass_len; + + strcpy(p, UserName); + p = p + strlen(UserName); + *p = 0; + + p = p + 1; + + strcpy(p, Con_Handle -> PDomain); + p = p + strlen(Con_Handle -> PDomain); + *p = 0; + p = p + 1; + + strcpy(p, Con_Handle -> OSName); + p = p + strlen(Con_Handle -> OSName); + *p = 0; + p = p + 1; + + strcpy(p, Con_Handle -> LMType); + p = p + strlen(Con_Handle -> LMType); + *p = 0; + + } + + /* Now send it and get a response */ + + if (RFCNB_Send(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error sending SessSetupX request\n"); +#endif + + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_SendFailed; + return(SMBlibE_BAD); + + } + + /* Now get the response ... */ + + if (RFCNB_Recv(Con_Handle -> Trans_Connect, pkt, pkt_len) < 0) { + +#ifdef DEBUG + fprintf(stderr, "Error receiving response to SessSetupAndX\n"); +#endif + + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_RecvFailed; + return(SMBlibE_BAD); + + } + + /* Check out the response type ... */ + + if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ + +#ifdef DEBUG + fprintf(stderr, "SMB_SessSetupAndX failed with errorclass = %i, Error Code = %i\n", + CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), + SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); +#endif + + SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); + RFCNB_Free_Pkt(pkt); + SMBlib_errno = SMBlibE_Remote; + return(SMBlibE_BAD); + + } + + /** @@@ mdz: check for guest login { **/ + if (SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset) & 0x1) { + /* do we allow guest login? NO! */ + return (SMBlibE_BAD); + } + /** @@@ mdz: } **/ + +#ifdef DEBUG + fprintf(stderr, "SessSetupAndX response. Action = %i\n", + SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset)); +#endif + + /* Now pick up the UID for future reference ... */ + + Con_Handle -> uid = SVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset); + RFCNB_Free_Pkt(pkt); + + return(0); + +} + + +/* Disconnect from the server, and disconnect all tree connects */ + +int SMB_Discon(SMB_Handle_Type Con_Handle, BOOL KeepHandle) + +{ + + /* We just disconnect the connection for now ... */ + + RFCNB_Hangup(Con_Handle -> Trans_Connect); + + if (!KeepHandle) + free(Con_Handle); + + return(0); + +} diff --git a/helpers/basic_auth/MSNT/smblib.h b/lib/smblib/smblib.h similarity index 58% rename from helpers/basic_auth/MSNT/smblib.h rename to lib/smblib/smblib.h index aaa4742d3a..7a8915f30a 100644 --- a/helpers/basic_auth/MSNT/smblib.h +++ b/lib/smblib/smblib.h @@ -1,30 +1,38 @@ /* UNIX SMBlib NetBIOS implementation - * - * Version 1.0 - * SMBlib Defines - * - * Copyright (C) Richard Sharpe 1996 - * - */ + + Version 1.0 + SMBlib Defines + + 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. - */ + 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. +*/ + +#ifndef _SMBLIB_SMBLIB_H +#define _SMBLIB_SMBLIB_H #include "std-defines.h" #include "smblib-common.h" +#include "smblib/smbencrypt.h" + +#ifdef __cplusplus +extern "C" { +#endif /* Just define all the entry points */ @@ -34,25 +42,38 @@ SMB_Handle_Type SMB_Create_Con_Handle(void); /* Connect to a server, but do not do a tree con etc ... */ -SMB_Handle_Type SMB_Connect_Server(SMB_Handle_Type, char *server, char *NTdomain); +SMB_Handle_Type SMB_Connect_Server(SMB_Handle_Type Con_Handle, + char *server, + const char *NTdomain); /* Connect to a server and give us back a handle. If Con == NULL, create */ /* The handle and populate it with defaults */ SMB_Handle_Type SMB_Connect(SMB_Handle_Type Con_Handle, - SMB_Tree_Handle * tree, + SMB_Tree_Handle *tree, char *service, char *username, char *password); +int SMB_Init(void); + +int SMB_Logon_Server(SMB_Handle_Type Con_Handle, + char *UserName, + char *PassWord, + const char *NtDomain, + int PreCrypted); + /* Negotiate a protocol */ int SMB_Negotiate(SMB_Handle_Type Con_Handle, const char *Prots[]); /* Connect to a tree ... */ -SMB_Tree_Handle SMB_TreeConnect(SMB_Handle_Type con_handle, SMB_Tree_Handle tree_handle, - char *path, char *password, const char *dev); +SMB_Tree_Handle SMB_TreeConnect(SMB_Handle_Type con, + SMB_Tree_Handle tree, + const char *path, + const char *password, + const char *dev); /* Disconnect a tree ... */ @@ -97,9 +118,7 @@ void SMB_Get_Error_Msg(int msg, char *msgbuf, int len); void *SMB_Logon_And_TCon(void *con, void *tree, char *user, char *pass, char *service, char *st); -void SMB_Get_My_Name(char *, int); - -int SMB_Init(void); - -extern int SMB_Logon_Server(SMB_Handle_Type, char *, char *); - +#ifdef __cplusplus +} +#endif +#endif /* _SMBLIB_SMBLIB_H */ diff --git a/lib/smblib/std-defines.h b/lib/smblib/std-defines.h new file mode 100644 index 0000000000..977ffbd84e --- /dev/null +++ b/lib/smblib/std-defines.h @@ -0,0 +1,46 @@ +#ifndef _SMBLIB_STD_DEFINES_H +#define _SMBLIB_STD_DEFINES_H + +#include "config.h" + +/* RFCNB Standard includes ... */ +/* + + SMBlib Standard Includes + + Copyright (C) 1996, Richard Sharpe +*/ +/* One day we will conditionalize these on OS types ... */ + +/* + 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. +*/ + +#define BOOL int + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TRUE 1 +#define FALSE 0 + +#endif /* _SMBLIB_STD_DEFINES_H */ diff --git a/lib/smblib/usage.txt b/lib/smblib/usage.txt new file mode 100644 index 0000000000..0804e77322 --- /dev/null +++ b/lib/smblib/usage.txt @@ -0,0 +1,229 @@ +Using SMBlib +Richard Sharpe + +This file describes how to use the SMBlib routines. It takes the form of a +program that might use many of thr routines with text describing the routines +used. + +I wrote it in an attempt to understand more about the SMB protocol and +the RFCNB (NBT) protocol underlying it. My manager approved my posting this +as long as there was no suggestion that Digital is responsible for this code +not that any warranties are offered by Digital. So, I put a GPL on the code. + +DISCLAIMER + +To restate, this code is offered as is, and no warranties are implied, either +by Digital Equipment Corporation or by Richard Sharpe. Neither +Digital Equipment Corporation nor Richard Sharpe can be held liable for +any consequences resulting from the use of this code. + +END Disclaimer + +I have pulled this code from other test routines, and I make no guarantee that +what I have here will actually compile. It is simply meant to show you how to +use SMBlib. + +STARING A PROGRAM + +You will need some includes ... + +#include +#include + +#include "SMBlib-SOURCE-DIR/smblib.h" + +INITIALIZING SMBlib + + SMB_Init() + +This initializes the SMBlib routines. + +CONNECTING TO A SERVER + +First, you have to connect to a share on a server. There are a couple of ways +of doing this. The easiest is: + + P1 P2 P3 P4 + + con = SMB_Connect(NULL, service_name, "Guest", password); + +where: + + P1 is a handle to a connection structure you might already have. NULL + if you want SMB_Connect to create one. + + P2 is the name of the service you want to connect to, in the form of: + + \\server-name\share + + P3 is the account name to log on as. This is really ignored by SMB_Connect + at the moment. + + P4 is the password to use in connecting to the share. + +SMB_Connect connects to the server, negotiates the Core Protocol, and connects +to the tree represented by the share that is specified. + +If a problem occurs, it returns NULL. You can check for errors doing the +following. + + void *con; + + if (con == NULL) { /* Error ... */ + + fprintf(stderr, "Unable to connect ... \n"); + + error = SMB_Get_Last_Error(); /* Find out the problem */ + +Pick up the error from SMBlib and decode it. + + if (error == SMBlibE_Remote) { /* Pick up the class and code */ + + SMB_Error = SMB_Get_Last_SMB_Err(); + + fprintf(stderr, "\tError Class = %i, Error Code = %i\n", + SMBlib_Error_Class(SMB_Error), SMBlib_Error_Code(SMB_Error)); + + } + else { /* Some error code from SMBlib ... */ + + SMB_Get_Error_Msg(error, error_message, sizeof(error_message) - 1); + + fprintf(stderr, "%s\n", error_message); + + } + + exit(1); /* Or whatever else you want to do ... */ + + } + +If you want to connect the hard way, you will need to call three routines, +SMB_Connect_Server, SMB_Negotiate, and SMB_TreeConnect. An example is: + + char *SMB_Prots[] = {"PC NETWORK PROGRAM 1.0", + "MICROSOFT NETWORKS 1.03", + "MICROSOFT NETWORKS 3.0", + "LANMAN1.0", + "LM1.2X002", + "Samba", + "NT LM 0.12", + "NT LANMAN 1.0", + NULL}; + +Here we connect to the server, whose name is in the variable server. + + con = SMB_Connect_Server(NULL, server); + +Here we do some primitive error checking. Use the example above for better +error checking. + + if (con == NULL) { /* Error ... */ + + fprintf(stderr, "Unable to connect to server \"%s\" ... \n", server); + RFCNB_Get_Error(err_string, sizeof(err_string)); + printf("Error in calling: %s ...\n", err_string); + exit(1); + + } + +Here we negotiate a protocol. We pass a list of the protocol strings we will +accepty as the second parameter. + + /* Now do a negotiate ... */ + + fprintf(stderr, "Now we negotiate a protocol ... \n"); + + if (SMB_Negotiate(con, SMB_Prots) < 0) { /* An error */ + + fprintf(stderr, "Unable to negotiate a protocol ...\n"); + RFCNB_Get_Error(err_string, sizeof(err_string)); + printf("Error in calling: %s ...\n", err_string); + exit(1); + + } + +If we wnat to find out the protocol that was negotiated then we can do the +following: + + protocol = SMB_Get_Protocol_IDX(con); + +This returns us the index of the protocol in SMB_Prots that was accepted, or +0xFFFF if connection handle is invalid. + + /* Now we do a logon ... */ + + fprintf(stderr, "Now try to logon as %s ...\n", user); + + if (SMB_Logon_Server(con, user, password) < 0) { + +This code will logon to an NT 3.51 server or to Samba or to a LAN Manager for +UNIX 2.2 server. It is the only part of SMBlib that knows about NT LM 0.12 +or LM1.2X002 at this stage. + + fprintf(stderr, "Unable to logon to server ...\n"); + RFCNB_Get_Error(err_string, sizeof(err_string)); + printf("Error in logging on: %s ...\n", err_string); + exit(1); + + } + + sprintf(service_unc, "\\\\%s\\%s", server, service); + +Now we connect to a tree. This takes the connection handle, a service name, a +password, and a service type (A:, LPT:, etc). If you want a Microsoft +developed server to connect you, you better use A: for the service type for a +disk service. + + void *tree; + + if (tree = SMB_TreeConnect(con, service, password, service_type) == NULL) { + + fprintf(stderr, "Unable to connect to the tree ...\n"); + RFCNB_Get_Error(err_string, sizeof(err_string)); + fprintf(stderr, " Error trying to connect: %s \n", err_string); + } + +OPENING FILES + +To open a file on the server, use the following call, which gives back a file +handle: + + P1 P2 P3 P4 P5 + + file = SMB_Open(tree, NULL, file_name, SMB_AMODE_OPENRW, SMB_FA_ORD); + +where: + + P1 is the tree handle from an earlier SMB_TreeConnect + + P2 is a file handle or NULL. If NULL is passed, a new file handle will be + created + + P3 is the file you want opened. + + P4 is the mode that you want it opened under. See smblib-common.h for the + defines. + + P5 is the type of file, whether an ordinary (normal), hidden, system, etc. + +If SMB_Open returns NULL, an error has occurred, so use the sort of error +handling code shown for SMB_Connect above. + +There are many more things that can be done. See the program test_smblib.c for +examples of doing all of the following: + +CLOSING FILES + + READING FILES + + WRITING FILES + + DELETING FILES + + CREATING FILES + + CREATING DIRECTORIES + + DELETING DIRECTORIES + + SEARCHING DIRECTORIES \ No newline at end of file diff --git a/libntlmauth/Makefile.am b/libntlmauth/Makefile.am deleted file mode 100644 index 6773731fbd..0000000000 --- a/libntlmauth/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -include $(top_srcdir)/src/Common.am -include $(top_srcdir)/src/TestHeaders.am - -noinst_LIBRARIES = libntlmauth.a - -libntlmauth_a_SOURCES = \ - ntlmauth.cc \ - ntlmauth.h \ - rfcnb.h \ - rfcnb-io.c \ - rfcnb-priv.h \ - rfcnb-session.c \ - rfcnb-util.c \ - smb-byteorder.h \ - smb-des.c \ - smb-des.h \ - smb-encrypt.c \ - smb.h \ - smblib.c \ - smblib-priv.h \ - smblib-util.c \ - smblmauth.c \ - smblmauth.h \ - smb-md4.c \ - smb-md4.h \ - support_bits.cci diff --git a/libntlmauth/rfcnb-io.c b/libntlmauth/rfcnb-io.c deleted file mode 100644 index b449b29ba3..0000000000 --- a/libntlmauth/rfcnb-io.c +++ /dev/null @@ -1,398 +0,0 @@ -/* UNIX RFCNB (RFC1001/RFC1002) NEtBIOS implementation - * - * Version 1.0 - * RFCNB IO 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 "config.h" -#include "libntlmauth/rfcnb-priv.h" - -#include -#include -#include - -/* local functions */ -void rfcnb_alarm(int sig); -int RFCNB_Set_Timeout(int seconds); -int RFCNB_Discard_Rest(struct RFCNB_Con *con, int len); - -/* local globals */ - -int RFCNB_Timeout = 0; /**< Timeout in seconds ... */ - -void -rfcnb_alarm(int sig) -{ - fprintf(stderr, "IO Timed out ...\n"); -} - -/** Set timeout value and setup signal handling */ -int -RFCNB_Set_Timeout(int seconds) -{ - /* If we are on a Bezerkeley system, use sigvec, else sigaction */ -#if HAVE_SIGACTION - struct sigaction inact, outact; -#else - struct sigvec invec, outvec; -#endif - - RFCNB_Timeout = seconds; - - if (RFCNB_Timeout > 0) { /* Set up handler to ignore but not restart */ - -#if HAVE_SIGACTION - inact.sa_handler = (void (*)()) rfcnb_alarm; - sigemptyset(&inact.sa_mask); - inact.sa_flags = 0; /* Don't restart */ - - if (sigaction(SIGALRM, &inact, &outact) < 0) - return (-1); -#else - invec.sv_handler = (void (*)()) rfcnb_alarm; - invec.sv_mask = 0; - invec.sv_flags = SV_INTERRUPT; - - if (sigvec(SIGALRM, &invec, &outvec) < 0) - return (-1); -#endif - - } - return (0); - -} - -/** Discard the rest of an incoming packet as we do not have space for it - * in the buffer we allocated or were passed ... - */ -int -RFCNB_Discard_Rest(struct RFCNB_Con *con, int len) -{ - char temp[100]; /* Read into here */ - int rest, this_read, bytes_read; - - /* len is the amount we should read */ - -#ifdef RFCNB_DEBUG - fprintf(stderr, "Discard_Rest called to discard: %i\n", len); -#endif - - rest = len; - - while (rest > 0) { - - this_read = (rest > sizeof(temp) ? sizeof(temp) : rest); - - bytes_read = read(con->fd, temp, this_read); - - if (bytes_read <= 0) { /* Error so return */ - - if (bytes_read < 0) - RFCNB_errno = RFCNBE_BadRead; - else - RFCNB_errno = RFCNBE_ConGone; - - RFCNB_saved_errno = errno; - return (RFCNBE_Bad); - - } - rest = rest - bytes_read; - - } - - return (0); - -} - - -/** Send an RFCNB packet to the connection. - * - * We just send each of the blocks linked together ... - * - * If we can, try to send it as one iovec ... - * - */ -int -RFCNB_Put_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len) -{ - int len_sent, tot_sent, this_len; - struct RFCNB_Pkt *pkt_ptr; - char *this_data; - int i; - struct iovec io_list[10]; /* We should never have more */ - /* If we do, this will blow up ... */ - - /* Try to send the data ... We only send as many bytes as len claims */ - /* We should try to stuff it into an IOVEC and send as one write */ - - - pkt_ptr = pkt; - len_sent = tot_sent = 0; /* Nothing sent so far */ - i = 0; - - while ((pkt_ptr != NULL) & (i < 10)) { /* Watch that magic number! */ - - this_len = pkt_ptr->len; - this_data = pkt_ptr->data; - if ((tot_sent + this_len) > len) - this_len = len - tot_sent; /* Adjust so we don't send too much */ - - /* Now plug into the iovec ... */ - - io_list[i].iov_len = this_len; - io_list[i].iov_base = this_data; - i++; - - tot_sent += this_len; - - if (tot_sent == len) - break; /* Let's not send too much */ - - pkt_ptr = pkt_ptr->next; - - } - -#ifdef RFCNB_DEBUG - fprintf(stderr, "Frags = %i, tot_sent = %i\n", i, tot_sent); -#endif - - /* Set up an alarm if timeouts are set ... */ - - if (RFCNB_Timeout > 0) - alarm(RFCNB_Timeout); - - if ((len_sent = writev(con->fd, io_list, i)) < 0) { /* An error */ - - con->rfc_errno = errno; - if (errno == EINTR) /* We were interrupted ... */ - RFCNB_errno = RFCNBE_Timeout; - else - RFCNB_errno = RFCNBE_BadWrite; - RFCNB_saved_errno = errno; - return (RFCNBE_Bad); - - } - if (len_sent < tot_sent) { /* Less than we wanted */ - if (errno == EINTR) /* We were interrupted */ - RFCNB_errno = RFCNBE_Timeout; - else - RFCNB_errno = RFCNBE_BadWrite; - RFCNB_saved_errno = errno; - return (RFCNBE_Bad); - } - if (RFCNB_Timeout > 0) - alarm(0); /* Reset that sucker */ - -#ifdef RFCNB_DEBUG - - fprintf(stderr, "Len sent = %i ...\n", len_sent); - RFCNB_Print_Pkt(stderr, "sent", pkt, len_sent); /* Print what send ... */ - -#endif - - return (len_sent); - -} - -/** Read an RFCNB packet off the connection. - * - * We read the first 4 bytes, that tells us the length, then read the - * rest. We should implement a timeout, but we don't just yet - * - */ -int -RFCNB_Get_Pkt(struct RFCNB_Con *con, struct RFCNB_Pkt *pkt, int len) -{ - int read_len, pkt_len; - char hdr[RFCNB_Pkt_Hdr_Len]; /* Local space for the header */ - struct RFCNB_Pkt *pkt_frag; - int more, this_time, offset, frag_len, this_len; - int seen_keep_alive = 1; - - /* Read that header straight into the buffer */ - - if (len < RFCNB_Pkt_Hdr_Len) { /* What a bozo */ - -#ifdef RFCNB_DEBUG - fprintf(stderr, "Trying to read less than a packet:"); - perror(""); -#endif - RFCNB_errno = RFCNBE_BadParam; - return (RFCNBE_Bad); - - } - /* We discard keep alives here ... */ - - if (RFCNB_Timeout > 0) - alarm(RFCNB_Timeout); - - while (seen_keep_alive) { - - if ((read_len = read(con->fd, hdr, sizeof(hdr))) < 0) { /* Problems */ -#ifdef RFCNB_DEBUG - fprintf(stderr, "Reading the packet, we got:"); - perror(""); -#endif - if (errno == EINTR) - RFCNB_errno = RFCNBE_Timeout; - else - RFCNB_errno = RFCNBE_BadRead; - RFCNB_saved_errno = errno; - return (RFCNBE_Bad); - - } - /* Now we check out what we got */ - - if (read_len == 0) { /* Connection closed, send back eof? */ - -#ifdef RFCNB_DEBUG - fprintf(stderr, "Connection closed reading\n"); -#endif - - if (errno == EINTR) - RFCNB_errno = RFCNBE_Timeout; - else - RFCNB_errno = RFCNBE_ConGone; - RFCNB_saved_errno = errno; - return (RFCNBE_Bad); - - } - if (RFCNB_Pkt_Type(hdr) == RFCNB_SESSION_KEEP_ALIVE) { - -#ifdef RFCNB_DEBUG - fprintf(stderr, "RFCNB KEEP ALIVE received\n"); -#endif - - } else { - seen_keep_alive = 0; - } - - } - - /* What if we got less than or equal to a hdr size in bytes? */ - - if (read_len < sizeof(hdr)) { /* We got a small packet */ - - /* Now we need to copy the hdr portion we got into the supplied packet */ - - memcpy(pkt->data, hdr, read_len); /*Copy data */ - -#ifdef RFCNB_DEBUG - RFCNB_Print_Pkt(stderr, "rcvd", pkt, read_len); -#endif - - return (read_len); - - } - /* Now, if we got at least a hdr size, alloc space for rest, if we need it */ - - pkt_len = RFCNB_Pkt_Len(hdr); - -#ifdef RFCNB_DEBUG - fprintf(stderr, "Reading Pkt: Length = %i\n", pkt_len); -#endif - - /* Now copy in the hdr */ - - memcpy(pkt->data, hdr, sizeof(hdr)); - - /* Get the rest of the packet ... first figure out how big our buf is? */ - /* And make sure that we handle the fragments properly ... Sure should */ - /* use an iovec ... */ - - if (len < pkt_len) /* Only get as much as we have space for */ - more = len - RFCNB_Pkt_Hdr_Len; - else - more = pkt_len; - - this_time = 0; - - /* We read for each fragment ... */ - - if (pkt->len == read_len) { /* If this frag was exact size */ - pkt_frag = pkt->next; /* Stick next lot in next frag */ - offset = 0; /* then we start at 0 in next */ - } else { - pkt_frag = pkt; /* Otherwise use rest of this frag */ - offset = RFCNB_Pkt_Hdr_Len; /* Otherwise skip the header */ - } - - frag_len = pkt_frag->len; - - if (more <= frag_len) /* If len left to get less than frag space */ - this_len = more; /* Get the rest ... */ - else - this_len = frag_len - offset; - - while (more > 0) { - - if ((this_time = read(con->fd, (pkt_frag->data) + offset, this_len)) <= 0) { /* Problems */ - - if (errno == EINTR) { - - RFCNB_errno = RFCNB_Timeout; - - } else { - if (this_time < 0) - RFCNB_errno = RFCNBE_BadRead; - else - RFCNB_errno = RFCNBE_ConGone; - } - - RFCNB_saved_errno = errno; - return (RFCNBE_Bad); - - } -#ifdef RFCNB_DEBUG - fprintf(stderr, "Frag_Len = %i, this_time = %i, this_len = %i, more = %i\n", frag_len, - this_time, this_len, more); -#endif - - read_len = read_len + this_time; /* How much have we read ... */ - - /* Now set up the next part */ - - if (pkt_frag->next == NULL) - break; /* That's it here */ - - pkt_frag = pkt_frag->next; - this_len = pkt_frag->len; - offset = 0; - - more = more - this_time; - - } - -#ifdef RFCNB_DEBUG - fprintf(stderr, "Pkt Len = %i, read_len = %i\n", pkt_len, read_len); - RFCNB_Print_Pkt(stderr, "rcvd", pkt, read_len + sizeof(hdr)); -#endif - - if (read_len < (pkt_len + sizeof(hdr))) { /* Discard the rest */ - - return (RFCNB_Discard_Rest(con, (pkt_len + sizeof(hdr)) - read_len)); - - } - if (RFCNB_Timeout > 0) - alarm(0); /* Reset that sucker */ - - return (read_len + sizeof(RFCNB_Hdr)); -} diff --git a/libntlmauth/rfcnb-priv.h b/libntlmauth/rfcnb-priv.h deleted file mode 100644 index 24dbfb94b6..0000000000 --- a/libntlmauth/rfcnb-priv.h +++ /dev/null @@ -1,169 +0,0 @@ -#ifndef __RFCNB_H__ -#define __RFCNB_H__ - -/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation - * - * Version 1.0 - * RFCNB Defines - * - * 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. - */ - -/* The Public API stuff */ -#include "libntlmauth/rfcnb.h" - -/* The internals */ -#include "libntlmauth/smb-byteorder.h" - -#if HAVE_NETINET_IN_H -#include -#endif - -#ifdef RFCNB_PORT -#define RFCNB_Default_Port RFCNB_PORT -#else -#define RFCNB_Default_Port 139 -#endif - -#define RFCNB_MAX_STATS 1 - -/* Protocol defines we need */ - -#define RFCNB_SESSION_MESSAGE 0 -#define RFCNB_SESSION_REQUEST 0x81 -#define RFCNB_SESSION_ACK 0x82 -#define RFCNB_SESSION_REJ 0x83 -#define RFCNB_SESSION_RETARGET 0x84 -#define RFCNB_SESSION_KEEP_ALIVE 0x85 - -/* Structures */ - -typedef char RFCNB_Hdr[4]; /* The header is 4 bytes long with */ -/* char[0] as the type, char[1] the */ -/* flags, and char[2..3] the length */ - -/* Macros to extract things from the header. These are for portability - * between architecture types where we are worried about byte order */ - -#define RFCNB_Pkt_Hdr_Len 4 -#define RFCNB_Pkt_Sess_Len 72 -#define RFCNB_Pkt_Retarg_Len 10 -#define RFCNB_Pkt_Nack_Len 5 -#define RFCNB_Pkt_Type_Offset 0 -#define RFCNB_Pkt_Flags_Offset 1 -#define RFCNB_Pkt_Len_Offset 2 /* Length is 2 bytes plus a flag bit */ -#define RFCNB_Pkt_N1Len_Offset 4 -#define RFCNB_Pkt_Called_Offset 5 -#define RFCNB_Pkt_N2Len_Offset 38 -#define RFCNB_Pkt_Calling_Offset 39 -#define RFCNB_Pkt_Error_Offset 4 -#define RFCNB_Pkt_IP_Offset 4 -#define RFCNB_Pkt_Port_Offset 8 - -/* The next macro isolates the length of a packet, including the bit in the - * flags */ - -#define RFCNB_Pkt_Len(p) (PVAL(p, 3) | (PVAL(p, 2) << 8) | \ - ((PVAL(p, RFCNB_Pkt_Flags_Offset) & 0x01) << 16)) - -#define RFCNB_Put_Pkt_Len(p, v) (p[1] = (((v) >> 16) & 1)); \ - (p[2] = (((v) >> 8) & 0xFF)); \ - (p[3] = ((v) & 0xFF)); - -#define RFCNB_Pkt_Type(p) (CVAL(p, RFCNB_Pkt_Type_Offset)) - -/*typedef struct RFCNB_Hdr { - * - * unsigned char type; - * unsigned char flags; - * int16 len; - * - * } RFCNB_Hdr; - * - * typedef struct RFCNB_Sess_Pkt { - * unsigned char type; - * unsigned char flags; - * int16 length; - * unsigned char n1_len; - * char called_name[33]; - * unsigned char n2_len; - * char calling_name[33]; - * } RFCNB_Sess_Pkt; - * - * - * typedef struct RFCNB_Nack_Pkt { - * - * struct RFCNB_Hdr hdr; - * unsigned char error; - * - * } RFCNB_Nack_Pkt; - * - * typedef struct RFCNB_Retarget_Pkt { - * - * struct RFCNB_Hdr hdr; - * int dest_ip; - * unsigned char port; - * - * } RFCNB_Redir_Pkt; */ - -/* Static variables */ - -/* Only declare this if not defined */ - -#ifndef RFCNB_ERRNO -extern int RFCNB_errno; -extern int RFCNB_saved_errno; /* Save this from point of error */ -#endif - -/* I/O functions */ -extern int RFCNB_Put_Pkt(RFCNB_Con *con, RFCNB_Pkt *pkt, int len); - -extern int RFCNB_Get_Pkt(RFCNB_Con *con, RFCNB_Pkt *pkt, int len); - -extern void RFCNB_Free_Pkt(RFCNB_Pkt *pkt); - -/* Util functions */ - -void RFCNB_CvtPad_Name(char *name1, char *name2); - -void RFCNB_AName_To_NBName(char *AName, char *NBName); - -void RFCNB_NBName_To_AName(char *NBName, char *AName); - -void RFCNB_Print_Hex(FILE * fd, RFCNB_Pkt *pkt, int Offset, int Len); - -RFCNB_Pkt *RFCNB_Alloc_Pkt(int n); - -void RFCNB_Print_Pkt(FILE * fd, char *dirn, RFCNB_Pkt *pkt, int len); - -int RFCNB_Name_To_IP(char *host, struct in_addr *Dest_IP); - -int RFCNB_Close(int socket); - -int RFCNB_IP_Connect(struct in_addr Dest_IP, int port); - -int RFCNB_Session_Req(RFCNB_Con *con, - char *Called_Name, - char *Calling_Name, - int * redirect, - struct in_addr *Dest_IP, - int *port); - -#endif /* __RFCNB_H__ */ diff --git a/libntlmauth/rfcnb-session.c b/libntlmauth/rfcnb-session.c deleted file mode 100644 index 38e569c4fe..0000000000 --- a/libntlmauth/rfcnb-session.c +++ /dev/null @@ -1,389 +0,0 @@ -/* 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 "config.h" -#include "libntlmauth/rfcnb-priv.h" - -#include -#include - -int RFCNB_errno = 0; -int RFCNB_saved_errno = 0; -//#define RFCNB_ERRNO - - -/* local functions */ -int RFCNB_Get_Last_Errno(void); -void RFCNB_Get_Error_Msg(int code, char *msg_buf, int len); -void RFCNB_Register_Print_Routine(void (*fn) ()); - -/* global data structures */ - -char const * RFCNB_Error_Strings[] = { - - "RFCNBE_OK: Routine completed successfully.", - "RFCNBE_NoSpace: No space available for a malloc call.", - "RFCNBE_BadName: NetBIOS name could not be translated to IP address.", - "RFCNBE_BadRead: Read system call returned an error. Check errno.", - "RFCNBE_BadWrite: Write system call returned an error. Check errno.", - "RFCNBE_ProtErr: A protocol error has occurred.", - "RFCNBE_ConGone: Connection dropped during a read or write system call.", - "RFCNBE_BadHandle: Bad connection handle passed.", - "RFCNBE_BadSocket: Problems creating socket.", - "RFCNBE_ConnectFailed: Connection failed. See errno.", - "RFCNBE_CallRejNLOCN: Call rejected. Not listening on called name.", - "RFCNBE_CallRejNLFCN: Call rejected. Not listening for called name.", - "RFCNBE_CallRejCNNP: Call rejected. Called name not present.", - "RFCNBE_CallRejInfRes: Call rejected. Name present, but insufficient resources.", - "RFCNBE_CallRejUnSpec: Call rejected. Unspecified error.", - "RFCNBE_BadParam: Bad parameters passed to a routine.", - "RFCNBE_Timeout: IO Operation timed out ..." - -}; - -int RFCNB_Stats[RFCNB_MAX_STATS]; - -void (*Prot_Print_Routine) () = NULL; /* Pointer to print routine */ - -/* 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 ... - */ - -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; - int 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) { /* If the Called Address = "" */ - 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 */ - free(con); - return (NULL); - - } - /* Now connect to the remote end */ - - redirect = 1; /* Fudge this one so we go once through */ - - while (redirect) { /* Connect and get session info etc */ - - redirect = 0; /* 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; - free(con); - 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 */ - free(con); - 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.. */ - RFCNB_Close(con->fd); /* Close it */ - free(con); - 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 ... */ - -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 ... */ - -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 */ - -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; - - -} - -/* Set TCP_NODELAY on the socket */ - -int -RFCNB_Set_Sock_NoDelay(struct RFCNB_Con *con_Handle, int yn) -{ - - return (setsockopt(con_Handle->fd, IPPROTO_TCP, TCP_NODELAY, - (char *) &yn, sizeof(yn))); - -} - - -/* Listen for a connection on a port???, when */ -/* the connection comes in, we return with the connection */ - -void * -RFCNB_Listen() -{ - fprintf(stderr, "RFCNB_Listen NOT IMPLEMENTED as yet!\n"); - return NULL; -} - -/* Pick up the last error response as a string, hmmm, this routine should */ -/* have been different ... */ - -void -RFCNB_Get_Error(char *buffer, int buf_len) -{ - if (RFCNB_saved_errno <= 0) { - snprintf(buffer, buf_len, "%s", RFCNB_Error_Strings[RFCNB_errno]); - } else { - snprintf(buffer, buf_len, "%s\n\terrno:%s", RFCNB_Error_Strings[RFCNB_errno], - strerror(RFCNB_saved_errno)); - } -} - -/* Pick up the last error response and returns as a code */ - -int -RFCNB_Get_Last_Error() -{ - - return (RFCNB_errno); - -} - -/* Pick up saved errno as well */ - -int -RFCNB_Get_Last_Errno() -{ - - return (RFCNB_saved_errno); - -} - -/* Pick up the last error response and return in string ... */ - -void -RFCNB_Get_Error_Msg(int code, char *msg_buf, int len) -{ - - strncpy(msg_buf, RFCNB_Error_Strings[abs(code)], len); - -} - -/* Register a higher level protocol print routine */ - -void -RFCNB_Register_Print_Routine(void (*fn) ()) -{ - - Prot_Print_Routine = fn; - -} diff --git a/libntlmauth/rfcnb-util.c b/libntlmauth/rfcnb-util.c deleted file mode 100644 index 5af572c917..0000000000 --- a/libntlmauth/rfcnb-util.c +++ /dev/null @@ -1,519 +0,0 @@ -/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation - * - * Version 1.0 - * RFCNB Utility 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 "config.h" -#include "libntlmauth/rfcnb-priv.h" - -#include -#include - -extern void (*Prot_Print_Routine) (); /* Pointer to protocol print routine */ - -/* Convert name and pad to 16 chars as needed */ -/* Name 1 is a C string with null termination, name 2 may not be */ -/* If SysName is true, then put a <00> on end, else space> */ - -void -RFCNB_CvtPad_Name(char *name1, char *name2) -{ - char c, c1, c2; - int i, len; - - len = strlen(name1); - - for (i = 0; i < 16; i++) { - - if (i >= len) { - - c1 = 'C'; - c2 = 'A'; /* CA is a space */ - - } else { - - c = name1[i]; - c1 = (char) ((int) c / 16 + (int) 'A'); - c2 = (char) ((int) c % 16 + (int) 'A'); - } - - name2[i * 2] = c1; - name2[i * 2 + 1] = c2; - - } - - name2[32] = 0; /* Put in the nll ... */ - -} - -/* Converts an Ascii NB Name (16 chars) to an RFCNB Name (32 chars) - * Uses the encoding in RFC1001. Each nibble of byte is added to 'A' - * to produce the next byte in the name. - * - * This routine assumes that AName is 16 bytes long and that NBName has - * space for 32 chars, so be careful ... - * - */ - -void -RFCNB_AName_To_NBName(char *AName, char *NBName) -{ - char c, c1, c2; - int i; - - for (i = 0; i < 16; i++) { - - c = AName[i]; - - c1 = (char) ((c >> 4) + 'A'); - c2 = (char) ((c & 0xF) + 'A'); - - NBName[i * 2] = c1; - NBName[i * 2 + 1] = c2; - } - - NBName[32] = 0; /* Put in a null */ - -} - -/* Do the reverse of the above ... */ - -void -RFCNB_NBName_To_AName(char *NBName, char *AName) -{ - char c, c1, c2; - int i; - - for (i = 0; i < 16; i++) { - - c1 = NBName[i * 2]; - c2 = NBName[i * 2 + 1]; - - c = (char) (((int) c1 - (int) 'A') * 16 + ((int) c2 - (int) 'A')); - - AName[i] = c; - - } - - AName[i] = 0; /* Put a null on the end ... */ - -} - -/* Print a string of bytes in HEX etc */ - -void -RFCNB_Print_Hex(FILE * fd, struct RFCNB_Pkt *pkt, int Offset, int Len) -{ - char c1, c2, outbuf1[33]; - unsigned char c; - int i, j; - struct RFCNB_Pkt *pkt_ptr = pkt; - static char Hex_List[17] = "0123456789ABCDEF"; - - j = 0; - - /* We only want to print as much as sepcified in Len */ - - while (pkt_ptr != NULL) { - - for (i = 0; - i < ((Len > (pkt_ptr->len) ? pkt_ptr->len : Len) - Offset); - i++) { - - c = pkt_ptr->data[i + Offset]; - c1 = Hex_List[c >> 4]; - c2 = Hex_List[c & 0xF]; - - outbuf1[j++] = c1; - outbuf1[j++] = c2; - - if (j == 32) { /* Print and reset */ - outbuf1[j] = 0; - fprintf(fd, " %s\n", outbuf1); - j = 0; - } - } - - Offset = 0; - Len = Len - pkt_ptr->len; /* Reduce amount by this much */ - pkt_ptr = pkt_ptr->next; - - } - - /* Print last lot in the buffer ... */ - - if (j > 0) { - - outbuf1[j] = 0; - fprintf(fd, " %s\n", outbuf1); - - } - fprintf(fd, "\n"); - -} - -/* Get a packet of size n */ - -struct RFCNB_Pkt * -RFCNB_Alloc_Pkt(int n) { - RFCNB_Pkt *pkt; - - if ((pkt = (struct RFCNB_Pkt *) malloc(sizeof(struct RFCNB_Pkt))) == NULL) { - - RFCNB_errno = RFCNBE_NoSpace; - RFCNB_saved_errno = errno; - return (NULL); - - } - pkt->next = NULL; - pkt->len = n; - - if (n == 0) - return (pkt); - - if ((pkt->data = (char *) malloc(n)) == NULL) { - - RFCNB_errno = RFCNBE_NoSpace; - RFCNB_saved_errno = errno; - free(pkt); - return (NULL); - - } - return (pkt); - -} - -/* Free up a packet */ - -void -RFCNB_Free_Pkt(struct RFCNB_Pkt *pkt) -{ - struct RFCNB_Pkt *pkt_next; - char *data_ptr; - - while (pkt != NULL) { - - pkt_next = pkt->next; - - data_ptr = pkt->data; - - if (data_ptr != NULL) - free(data_ptr); - - free(pkt); - - pkt = pkt_next; - - } - -} - -/* Print an RFCNB packet */ - -void -RFCNB_Print_Pkt(FILE * fd, char *dirn, struct RFCNB_Pkt *pkt, int len) -{ - char lname[17]; - - /* We assume that the first fragment is the RFCNB Header */ - /* We should loop through the fragments printing them out */ - - fprintf(fd, "RFCNB Pkt %s:", dirn); - - switch (RFCNB_Pkt_Type(pkt->data)) { - - case RFCNB_SESSION_MESSAGE: - - fprintf(fd, "SESSION MESSAGE: Length = %i\n", RFCNB_Pkt_Len(pkt->data)); - RFCNB_Print_Hex(fd, pkt, RFCNB_Pkt_Hdr_Len, -#ifdef RFCNB_PRINT_DATA - RFCNB_Pkt_Len(pkt->data) - RFCNB_Pkt_Hdr_Len); -#else - 40); -#endif - - if (Prot_Print_Routine != 0) { /* Print the rest of the packet */ - - Prot_Print_Routine(fd, strcmp(dirn, "sent"), pkt, RFCNB_Pkt_Hdr_Len, - RFCNB_Pkt_Len(pkt->data) - RFCNB_Pkt_Hdr_Len); - - } - break; - - case RFCNB_SESSION_REQUEST: - - fprintf(fd, "SESSION REQUEST: Length = %i\n", - RFCNB_Pkt_Len(pkt->data)); - RFCNB_NBName_To_AName((char *) (pkt->data + RFCNB_Pkt_Called_Offset), lname); - fprintf(fd, " Called Name: %s\n", lname); - RFCNB_NBName_To_AName((char *) (pkt->data + RFCNB_Pkt_Calling_Offset), lname); - fprintf(fd, " Calling Name: %s\n", lname); - - break; - - case RFCNB_SESSION_ACK: - - fprintf(fd, "RFCNB SESSION ACK: Length = %i\n", - RFCNB_Pkt_Len(pkt->data)); - - break; - - case RFCNB_SESSION_REJ: - fprintf(fd, "RFCNB SESSION REJECT: Length = %i\n", - RFCNB_Pkt_Len(pkt->data)); - - if (RFCNB_Pkt_Len(pkt->data) < 1) { - fprintf(fd, " Protocol Error, short Reject packet!\n"); - } else { - fprintf(fd, " Error = %x\n", CVAL(pkt->data, RFCNB_Pkt_Error_Offset)); - } - - break; - - case RFCNB_SESSION_RETARGET: - - fprintf(fd, "RFCNB SESSION RETARGET: Length = %i\n", - RFCNB_Pkt_Len(pkt->data)); - - /* Print out the IP address etc and the port? */ - - break; - - case RFCNB_SESSION_KEEP_ALIVE: - - fprintf(fd, "RFCNB SESSION KEEP ALIVE: Length = %i\n", - RFCNB_Pkt_Len(pkt->data)); - break; - - default: - - break; - } - -} - -/* Resolve a name into an address */ - -int -RFCNB_Name_To_IP(char *host, struct in_addr *Dest_IP) -{ - int addr; /* Assumes IP4, 32 bit network addresses */ - struct hostent *hp; - - /* Use inet_addr to try to convert the address */ - - if ((addr = inet_addr(host)) == INADDR_NONE) { /* Oh well, a good try :-) */ - - /* Now try a name look up with gethostbyname */ - - if ((hp = gethostbyname(host)) == NULL) { /* Not in DNS */ - - /* Try NetBIOS name lookup, how the hell do we do that? */ - - RFCNB_errno = RFCNBE_BadName; /* Is this right? */ - RFCNB_saved_errno = errno; - return (RFCNBE_Bad); - - } else { /* We got a name */ - Dest_IP->s_addr = (*((struct in_addr*)hp->h_addr_list[0])).s_addr; - } - } else { /* It was an IP address */ - Dest_IP->s_addr = addr; - } - - return 0; - -} - -/* Disconnect the TCP connection to the server */ - -int -RFCNB_Close(int aSocket) -{ - - close(aSocket); - - /* If we want to do error recovery, here is where we put it */ - - return 0; - -} - -/* Connect to the server specified in the IP address. - * Not sure how to handle socket options etc. */ - -int -RFCNB_IP_Connect(struct in_addr Dest_IP, int port) -{ - struct sockaddr_in Socket; - int fd; - - /* Create a socket */ - - if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { /* Handle the error */ - - RFCNB_errno = RFCNBE_BadSocket; - RFCNB_saved_errno = errno; - return (RFCNBE_Bad); - } - memset((char *) &Socket, 0, sizeof(Socket)); - memcpy((char *) &Socket.sin_addr, (char *) &Dest_IP, sizeof(Dest_IP)); - - Socket.sin_port = htons(port); - Socket.sin_family = PF_INET; - - /* Now connect to the destination */ - - if (connect(fd, (struct sockaddr *) &Socket, sizeof(Socket)) < 0) { /* Error */ - - close(fd); - RFCNB_errno = RFCNBE_ConnectFailed; - RFCNB_saved_errno = errno; - return (RFCNBE_Bad); - } - return (fd); - -} - -/* handle the details of establishing the RFCNB session with remote - * end - * - */ - -int -RFCNB_Session_Req(struct RFCNB_Con *con, - char *Called_Name, - char *Calling_Name, - int * redirect, - struct in_addr *Dest_IP, - int *port) -{ - char *sess_pkt; - - /* Response packet should be no more than 9 bytes, make 16 jic */ - - char resp[16]; - int len; - struct RFCNB_Pkt *pkt, res_pkt; - - /* We build and send the session request, then read the response */ - - pkt = RFCNB_Alloc_Pkt(RFCNB_Pkt_Sess_Len); - - if (pkt == NULL) { - - return (RFCNBE_Bad); /* Leave the error that RFCNB_Alloc_Pkt gives) */ - - } - sess_pkt = pkt->data; /* Get pointer to packet proper */ - - sess_pkt[RFCNB_Pkt_Type_Offset] = RFCNB_SESSION_REQUEST; - RFCNB_Put_Pkt_Len(sess_pkt, RFCNB_Pkt_Sess_Len - RFCNB_Pkt_Hdr_Len); - sess_pkt[RFCNB_Pkt_N1Len_Offset] = 32; - sess_pkt[RFCNB_Pkt_N2Len_Offset] = 32; - - RFCNB_CvtPad_Name(Called_Name, (sess_pkt + RFCNB_Pkt_Called_Offset)); - RFCNB_CvtPad_Name(Calling_Name, (sess_pkt + RFCNB_Pkt_Calling_Offset)); - - /* Now send the packet */ - -#ifdef RFCNB_DEBUG - - fprintf(stderr, "Sending packet: "); - -#endif - - if ((len = RFCNB_Put_Pkt(con, pkt, RFCNB_Pkt_Sess_Len)) < 0) { - - return (RFCNBE_Bad); /* Should be able to write that lot ... */ - - } -#ifdef RFCNB_DEBUG - - fprintf(stderr, "Getting packet.\n"); - -#endif - - res_pkt.data = resp; - res_pkt.len = sizeof(resp); - res_pkt.next = NULL; - - if ((len = RFCNB_Get_Pkt(con, &res_pkt, sizeof(resp))) < 0) { - - return (RFCNBE_Bad); - - } - /* Now analyze the packet ... */ - - switch (RFCNB_Pkt_Type(resp)) { - - case RFCNB_SESSION_REJ: /* Didnt like us ... too bad */ - - /* Why did we get rejected ? */ - - switch (CVAL(resp, RFCNB_Pkt_Error_Offset)) { - - case 0x80: - RFCNB_errno = RFCNBE_CallRejNLOCN; - break; - case 0x81: - RFCNB_errno = RFCNBE_CallRejNLFCN; - break; - case 0x82: - RFCNB_errno = RFCNBE_CallRejCNNP; - break; - case 0x83: - RFCNB_errno = RFCNBE_CallRejInfRes; - break; - case 0x8F: - RFCNB_errno = RFCNBE_CallRejUnSpec; - break; - default: - RFCNB_errno = RFCNBE_ProtErr; - break; - } - - return (RFCNBE_Bad); - break; - - case RFCNB_SESSION_ACK: /* Got what we wanted ... */ - - return (0); - break; - - case RFCNB_SESSION_RETARGET: /* Go elsewhere */ - - *redirect = 1; /* Copy port and ip addr */ - - memcpy(Dest_IP, (resp + RFCNB_Pkt_IP_Offset), sizeof(struct in_addr)); - *port = SVAL(resp, RFCNB_Pkt_Port_Offset); - - return (0); - break; - - default: /* A protocol error */ - - RFCNB_errno = RFCNBE_ProtErr; - return (RFCNBE_Bad); - break; - } -} diff --git a/libntlmauth/rfcnb.h b/libntlmauth/rfcnb.h deleted file mode 100644 index c1a1aeb855..0000000000 --- a/libntlmauth/rfcnb.h +++ /dev/null @@ -1,149 +0,0 @@ -/* UNIX RFCNB (RFC1001/RFC1002) NetBIOS implementation - * - * Version 1.0 - * RFCNB Defines - * - * 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. - */ - -#ifndef _LIBNTLMAUTH_RFCNB_H -#define _LIBNTLMAUTH_RFCNB_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if HAVE_NETINET_IN_H -#include -#endif - -/* API Defines we need */ - -#ifdef __cplusplus -extern "C" { -#endif - - /* Error responses */ - /* these should follow the spec ... is there one ? */ - -#define RFCNBE_Bad -1 /* Bad response */ -#define RFCNBE_OK 0 /* Routine completed successfully. */ -#define RFCNBE_NoSpace 1 /* Could not allocate space for a struct */ -#define RFCNBE_BadName 2 /* Could not translate a name */ -#define RFCNBE_BadRead 3 /* Read sys call failed */ -#define RFCNBE_BadWrite 4 /* Write Sys call failed */ -#define RFCNBE_ProtErr 5 /* Protocol Error */ -#define RFCNBE_ConGone 6 /* Connection dropped */ -#define RFCNBE_BadHandle 7 /* Handle passed was bad */ -#define RFCNBE_BadSocket 8 /* Problems creating socket */ -#define RFCNBE_ConnectFailed 9 /* Connect failed */ -#define RFCNBE_CallRejNLOCN 10 /* Call rejected, not listening on CN */ -#define RFCNBE_CallRejNLFCN 11 /* Call rejected, not listening for CN */ -#define RFCNBE_CallRejCNNP 12 /* Call rejected, called name not present */ -#define RFCNBE_CallRejInfRes 13 /* Call rejetced, name ok, no resources */ -#define RFCNBE_CallRejUnSpec 14 /* Call rejected, unspecified error */ -#define RFCNBE_BadParam 15 /* Bad parameters passed ... */ -#define RFCNBE_Timeout 16 /* IO Timed out */ - - /* Text strings for the error responses */ - extern char const *RFCNB_Error_Strings[]; - /* - * static char *RFCNB_Error_Strings[] = { - * - * "RFCNBE_OK: Routine completed successfully.", - * "RFCNBE_NoSpace: No space available for a malloc call.", - * "RFCNBE_BadName: NetBIOS name could not be translated to IP address.", - * "RFCNBE_BadRead: Read system call returned an error. Check errno.", - * "RFCNBE_BadWrite: Write system call returned an error. Check errno.", - * "RFCNBE_ProtErr: A protocol error has occurred.", - * "RFCNBE_ConGone: Connection dropped during a read or write system call.", - * "RFCNBE_BadHandle: Bad connection handle passed.", - * "RFCNBE_BadSocket: Problems creating socket.", - * "RFCNBE_ConnectFailed: Connection failed. See errno.", - * "RFCNBE_CallRejNLOCN: Call rejected. Not listening on called name.", - * "RFCNBE_CallRejNLFCN: Call rejected. Not listening for called name.", - * "RFCNBE_CallRejCNNP: Call rejected. Called name not present.", - * "RFCNBE_CallRejInfRes: Call rejected. Name present, but insufficient resources.", - * "RFCNBE_CallRejUnSpec: Call rejected. Unspecified error.", - * "RFCNBE_BadParam: Bad parameters passed to a routine.", - * "RFCNBE_Timeout: IO Operation timed out ..." - * - * }; - */ - -#define RFCNB_Default_Port 139 - - /* API Structures */ - - typedef struct redirect_addr * redirect_ptr; - - struct redirect_addr { - struct in_addr ip_addr; - int port; - redirect_ptr next; - }; - - typedef struct RFCNB_Con { - int fd; /* File descripter for TCP/IP connection */ - int rfc_errno; /* last error */ - int timeout; /* How many milli-secs before IO times out */ - int redirects; /* How many times we were redirected */ - struct redirect_addr *redirect_list; /* First is first address */ - struct redirect_addr *last_addr; - } RFCNB_Con; - - typedef struct RFCNB_Pkt { - char *data; /* The data in this portion */ - int len; - struct RFCNB_Pkt *next; - } RFCNB_Pkt; - - /* API Definition of routines we define */ - - void *RFCNB_Call(char *Called_Name, char *Calling_Name, char *Called_Address, int port); - - int RFCNB_Send(RFCNB_Con *Con_Handle, RFCNB_Pkt *Data, int Length); - - int RFCNB_Recv(void *Con_Handle, RFCNB_Pkt *Data, int Length); - - int RFCNB_Hangup(RFCNB_Con *con_Handle); - - void *RFCNB_Listen(void); - - void RFCNB_Get_Error(char *buffer, int buf_len); - - int RFCNB_Get_Last_Error(void); - - RFCNB_Pkt *RFCNB_Alloc_Pkt(int n); - - void RFCNB_Free_Pkt(RFCNB_Pkt *pkt); - - int RFCNB_Set_Sock_NoDelay(RFCNB_Con *con_Handle, int yn); - -#ifdef __cplusplus -}; -#endif - -#endif /* _LIBNTLMAUTH_RFCNB_H */ diff --git a/libntlmauth/smb-byteorder.h b/libntlmauth/smb-byteorder.h deleted file mode 100644 index e1f52a669d..0000000000 --- a/libntlmauth/smb-byteorder.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Unix SMB/Netbios implementation. - * Version 1.9. - * SMB Byte handling - * Copyright (C) Andrew Tridgell 1992-1995 - * - * 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. - */ -#ifndef _LIBNTLMAUTH_SMB_BYTEORER_H -#define _LIBNTLMAUTH_SMB_BYTEORER_H - -/* - * This file implements macros for machine independent short and - * int manipulation - */ - -#undef CAREFUL_ALIGNMENT - -/* we know that the 386 can handle misalignment and has the "right" - * byteorder */ -#ifdef __i386__ -#define CAREFUL_ALIGNMENT 0 -#endif - -#ifndef CAREFUL_ALIGNMENT -#define CAREFUL_ALIGNMENT 1 -#endif - -#define CVAL(buf,pos) (((unsigned char *)(buf))[pos]) -#define PVAL(buf,pos) ((unsigned)CVAL(buf,pos)) -#define SCVAL(buf,pos,val) (CVAL(buf,pos) = (val)) - - -#if CAREFUL_ALIGNMENT -#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8) -#define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16) -#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8) -#define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16)) -#define SVALS(buf,pos) ((int16_t)SVAL(buf,pos)) -#define IVALS(buf,pos) ((int32_t)IVAL(buf,pos)) -#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((uint16_t)(val))) -#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32_t)(val))) -#define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16_t)(val))) -#define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32_t)(val))) -#else -/* this handles things for architectures like the 386 that can handle - * alignment errors */ -/* - * WARNING: This section is dependent on the length of int16 and int32 - * being correct - */ -#define SVAL(buf,pos) (*(uint16_t *)((char *)(buf) + (pos))) -#define IVAL(buf,pos) (*(uint32_t *)((char *)(buf) + (pos))) -#define SVALS(buf,pos) (*(int16_t *)((char *)(buf) + (pos))) -#define IVALS(buf,pos) (*(int32_t *)((char *)(buf) + (pos))) -#define SSVAL(buf,pos,val) SVAL(buf,pos)=((uint16_t)(val)) -#define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32_t)(val)) -#define SSVALS(buf,pos,val) SVALS(buf,pos)=((int16_t)(val)) -#define SIVALS(buf,pos,val) IVALS(buf,pos)=((int32_t)(val)) -#endif - - -/* now the reverse routines - these are used in nmb packets (mostly) */ -#define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF)) -#define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16))) - -#define RSVAL(buf,pos) SREV(SVAL(buf,pos)) -#define RIVAL(buf,pos) IREV(IVAL(buf,pos)) -#define RSSVAL(buf,pos,val) SSVAL(buf,pos,SREV(val)) -#define RSIVAL(buf,pos,val) SIVAL(buf,pos,IREV(val)) - -#endif /* LIBNTLMAUTH_SMB_BYTEORER_H */ diff --git a/libntlmauth/smb-des.c b/libntlmauth/smb-des.c deleted file mode 100644 index 5c4f068ead..0000000000 --- a/libntlmauth/smb-des.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Unix SMB/Netbios implementation. - * Version 1.9. - * - * a partial implementation of DES designed for use in the - * SMB authentication protocol - * - * Copyright (C) Andrew Tridgell 1997 - * - * 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. - */ - - -/* NOTES: - * - * This code makes no attempt to be fast! In fact, it is a very - * slow implementation - * - * This code is NOT a complete DES implementation. It implements only - * the minimum necessary for SMB authentication, as used by all SMB - * products (including every copy of Microsoft Windows95 ever sold) - * - * In particular, it can only do a unchained forward DES pass. This - * means it is not possible to use this code for encryption/decryption - * of data, instead it is only useful as a "hash" algorithm. - * - * There is no entry point into this code that allows normal DES operation. - * - * I believe this means that this code does not come under ITAR - * regulations but this is NOT a legal opinion. If you are concerned - * about the applicability of ITAR regulations to this code then you - * should confirm it for yourself (and maybe let me know if you come - * up with a different answer to the one above) - */ -#include "config.h" -#include "libntlmauth/smb-des.h" - -/* local functions */ -void cred_hash1(unsigned char *out, unsigned char *in, unsigned char *key); -void cred_hash2(unsigned char *out, unsigned char *in, unsigned char *key); - - -static int perm1[56] = {57, 49, 41, 33, 25, 17, 9, - 1, 58, 50, 42, 34, 26, 18, - 10, 2, 59, 51, 43, 35, 27, - 19, 11, 3, 60, 52, 44, 36, - 63, 55, 47, 39, 31, 23, 15, - 7, 62, 54, 46, 38, 30, 22, - 14, 6, 61, 53, 45, 37, 29, - 21, 13, 5, 28, 20, 12, 4 - }; - -static int perm2[48] = {14, 17, 11, 24, 1, 5, - 3, 28, 15, 6, 21, 10, - 23, 19, 12, 4, 26, 8, - 16, 7, 27, 20, 13, 2, - 41, 52, 31, 37, 47, 55, - 30, 40, 51, 45, 33, 48, - 44, 49, 39, 56, 34, 53, - 46, 42, 50, 36, 29, 32 - }; - -static int perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, - 60, 52, 44, 36, 28, 20, 12, 4, - 62, 54, 46, 38, 30, 22, 14, 6, - 64, 56, 48, 40, 32, 24, 16, 8, - 57, 49, 41, 33, 25, 17, 9, 1, - 59, 51, 43, 35, 27, 19, 11, 3, - 61, 53, 45, 37, 29, 21, 13, 5, - 63, 55, 47, 39, 31, 23, 15, 7 - }; - -static int perm4[48] = {32, 1, 2, 3, 4, 5, - 4, 5, 6, 7, 8, 9, - 8, 9, 10, 11, 12, 13, - 12, 13, 14, 15, 16, 17, - 16, 17, 18, 19, 20, 21, - 20, 21, 22, 23, 24, 25, - 24, 25, 26, 27, 28, 29, - 28, 29, 30, 31, 32, 1 - }; - -static int perm5[32] = {16, 7, 20, 21, - 29, 12, 28, 17, - 1, 15, 23, 26, - 5, 18, 31, 10, - 2, 8, 24, 14, - 32, 27, 3, 9, - 19, 13, 30, 6, - 22, 11, 4, 25 - }; - - -static int perm6[64] = {40, 8, 48, 16, 56, 24, 64, 32, - 39, 7, 47, 15, 55, 23, 63, 31, - 38, 6, 46, 14, 54, 22, 62, 30, - 37, 5, 45, 13, 53, 21, 61, 29, - 36, 4, 44, 12, 52, 20, 60, 28, - 35, 3, 43, 11, 51, 19, 59, 27, - 34, 2, 42, 10, 50, 18, 58, 26, - 33, 1, 41, 9, 49, 17, 57, 25 - }; - - -static int sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; - -static int sbox[8][4][16] = { - { - {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, - {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, - {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, - {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}, - - { - {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, - {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, - {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, - {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}, - - { - {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, - {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, - {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, - {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}, - - { - {7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, - {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, - {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, - {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}, - - { - {2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, - {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, - {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, - {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}, - - { - {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, - {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, - {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, - {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}, - - { - {4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, - {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, - {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, - {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}, - - { - {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, - {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, - {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, - {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}} -}; - -static void -permute(char *out, char *in, int *p, int n) -{ - int i; - for (i = 0; i < n; i++) - out[i] = in[p[i] - 1]; -} - -static void -lshift(char *d, int count, int n) -{ - char out[64]; - int i; - for (i = 0; i < n; i++) - out[i] = d[(i + count) % n]; - for (i = 0; i < n; i++) - d[i] = out[i]; -} - -static void -concat(char *out, char *in1, char *in2, int l1, int l2) -{ - while (l1--) - *out++ = *in1++; - while (l2--) - *out++ = *in2++; -} - -static void -xor(char *out, char *in1, char *in2, int n) -{ - int i; - for (i = 0; i < n; i++) - out[i] = in1[i] ^ in2[i]; -} - -static void -dohash(char *out, char *in, char *key) -{ - int i, j, k; - char pk1[56]; - char c[28]; - char d[28]; - char cd[56]; - char ki[16][48]; - char pd1[64]; - char l[32], r[32]; - char rl[64]; - - permute(pk1, key, perm1, 56); - - for (i = 0; i < 28; i++) - c[i] = pk1[i]; - for (i = 0; i < 28; i++) - d[i] = pk1[i + 28]; - - for (i = 0; i < 16; i++) { - lshift(c, sc[i], 28); - lshift(d, sc[i], 28); - - concat(cd, c, d, 28, 28); - permute(ki[i], cd, perm2, 48); - } - - permute(pd1, in, perm3, 64); - - for (j = 0; j < 32; j++) { - l[j] = pd1[j]; - r[j] = pd1[j + 32]; - } - - for (i = 0; i < 16; i++) { - char er[48]; - char erk[48]; - char b[8][6]; - char cb[32]; - char pcb[32]; - char r2[32]; - - permute(er, r, perm4, 48); - - xor(erk, er, ki[i], 48); - - for (j = 0; j < 8; j++) - for (k = 0; k < 6; k++) - b[j][k] = erk[j * 6 + k]; - - for (j = 0; j < 8; j++) { - int m, n; - m = (b[j][0] << 1) | b[j][5]; - - n = (b[j][1] << 3) | (b[j][2] << 2) | (b[j][3] << 1) | b[j][4]; - - for (k = 0; k < 4; k++) - b[j][k] = (sbox[j][m][n] & (1 << (3 - k))) ? 1 : 0; - } - - for (j = 0; j < 8; j++) - for (k = 0; k < 4; k++) - cb[j * 4 + k] = b[j][k]; - permute(pcb, cb, perm5, 32); - - xor(r2, l, pcb, 32); - - for (j = 0; j < 32; j++) - l[j] = r[j]; - - for (j = 0; j < 32; j++) - r[j] = r2[j]; - } - - concat(rl, r, l, 32, 32); - - permute(out, rl, perm6, 64); -} - -static void -str_to_key(unsigned char *str, unsigned char *key) -{ - int i; - - key[0] = str[0] >> 1; - key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2); - key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3); - key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4); - key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5); - key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6); - key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7); - key[7] = str[6] & 0x7F; - for (i = 0; i < 8; i++) { - key[i] = (key[i] << 1); - } -} - - -static void -smbhash(unsigned char *out, unsigned char *in, unsigned char *key) -{ - int i; - char outb[64]; - char inb[64]; - char keyb[64]; - unsigned char key2[8]; - - str_to_key(key, key2); - - for (i = 0; i < 64; i++) { - inb[i] = (in[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0; - keyb[i] = (key2[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0; - outb[i] = 0; - } - - dohash(outb, inb, keyb); - - for (i = 0; i < 8; i++) { - out[i] = 0; - } - - for (i = 0; i < 64; i++) { - if (outb[i]) - out[i / 8] |= (1 << (7 - (i % 8))); - } -} - -void -E_P16(unsigned char *p14, unsigned char *p16) -{ - unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; - smbhash(p16, sp8, p14); - smbhash(p16 + 8, sp8, p14 + 7); -} - -void -E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24) -{ - smbhash(p24, c8, p21); - smbhash(p24 + 8, c8, p21 + 7); - smbhash(p24 + 16, c8, p21 + 14); -} - -void -cred_hash1(unsigned char *out, unsigned char *in, unsigned char *key) -{ - unsigned char buf[8]; - - smbhash(buf, in, key); - smbhash(out, buf, key + 9); -} - -void -cred_hash2(unsigned char *out, unsigned char *in, unsigned char *key) -{ - unsigned char buf[8]; - static unsigned char key2[8]; - - smbhash(buf, in, key); - key2[0] = key[7]; - smbhash(out, buf, key2); -} diff --git a/libntlmauth/smb-des.h b/libntlmauth/smb-des.h deleted file mode 100644 index 057fc22101..0000000000 --- a/libntlmauth/smb-des.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __SMB_LM_SMBVAL_SMBDES_H -#define __SMB_LM_SMBVAL_SMBDES_H - -extern void E_P16(unsigned char *p14, unsigned char *p16); -extern void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); - -#endif /* __SMB_LM_SMBVAL_SMBDES_H */ diff --git a/libntlmauth/smb-encrypt.c b/libntlmauth/smb-encrypt.c deleted file mode 100644 index 6c2024305d..0000000000 --- a/libntlmauth/smb-encrypt.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Unix SMB/Netbios implementation. - * Version 1.9. - * SMB parameters and setup - * Copyright (C) Andrew Tridgell 1992-1997 - * Modified by Jeremy Allison 1995. - * - * 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 "config.h" -#include "libntlmauth/smb-byteorder.h" -#include "libntlmauth/smb-des.h" -#include "libntlmauth/smb-md4.h" -#include "libntlmauth/smblib-priv.h" - -#include -#include -#include -#include -#include -#include - -extern int DEBUGLEVEL; - -/* local functions */ -char *StrnCpy(char *dest, char *src, int n); -void strupper(char *s); -void E_md4hash(unsigned char * passwd, unsigned char * p16); -void nt_lm_owf_gen(char *pwd, char *nt_p16, char *p16); - -/* - * This implements the X/Open SMB password encryption - * It takes a password, a 8 byte "crypt key" and puts 24 bytes of - * encrypted password into p24 */ -void -SMBencrypt(unsigned char * passwd, unsigned char * c8, unsigned char * p24) -{ - unsigned char p14[15], p21[21]; - - memset(p21, '\0', 21); - memset(p14, '\0', 14); - StrnCpy((char *) p14, (char *) passwd, 14); - - strupper((char *) p14); - E_P16(p14, p21); - E_P24(p21, c8, p24); -} - -/* Routines for Windows NT MD4 Hash functions. */ -static int -_my_wcslen(int16_t * str) -{ - int len = 0; - while (*str++ != 0) - len++; - return len; -} - -/* - * Convert a string into an NT UNICODE string. - * Note that regardless of processor type - * this must be in intel (little-endian) - * format. - */ - -static int -_my_mbstowcs(int16_t * dst, unsigned char * src, int len) -{ - int i; - int16_t val; - - for (i = 0; i < len; i++) { - val = *src; - SSVAL(dst, 0, val); - dst++; - src++; - if (val == 0) - break; - } - return i; -} - -/** - * Creates the MD4 Hash of the users password in NT UNICODE. - */ -void -E_md4hash(unsigned char * passwd, unsigned char * p16) -{ - int len; - int16_t wpwd[129]; - - /* Password cannot be longer than 128 characters */ - len = strlen((char *) passwd); - if (len > 128) - len = 128; - /* Password must be converted to NT unicode */ - _my_mbstowcs(wpwd, passwd, len); - wpwd[len] = 0; /* Ensure string is null terminated */ - /* Calculate length in bytes */ - len = _my_wcslen(wpwd) * sizeof(int16_t); - - mdfour(p16, (unsigned char *) wpwd, len); -} - -/* Does the NT MD4 hash then des encryption. */ -void -SMBNTencrypt(unsigned char * passwd, unsigned char * c8, unsigned char * p24) -{ - unsigned char p21[21]; - - memset(p21, '\0', 21); - - E_md4hash(passwd, p21); - E_P24(p21, c8, p24); -} - -/** Does both the NT and LM owfs of a user's password */ -void -nt_lm_owf_gen(char *pwd, char *nt_p16, char *p16) -{ - char passwd[130]; - StrnCpy(passwd, pwd, sizeof(passwd) - 1); - - /* Calculate the MD4 hash (NT compatible) of the password */ - memset(nt_p16, '\0', 16); - E_md4hash((unsigned char *) passwd, (unsigned char *) nt_p16); - - /* Mangle the passwords into Lanman format */ - passwd[14] = '\0'; - strupper(passwd); - - /* Calculate the SMB (lanman) hash functions of the password */ - - memset(p16, '\0', 16); - E_P16((unsigned char *) passwd, (unsigned char *) p16); - - /* clear out local copy of user's password (just being paranoid). */ - memset(passwd, 0, sizeof(passwd)); -} - -/**************************************************************************** -line strncpy but always null terminates. Make sure there is room! -****************************************************************************/ -char * -StrnCpy(char *dest, char *src, int n) -{ - char *d = dest; - if (!dest) - return (NULL); - if (!src) { - *dest = 0; - return (dest); - } - while (n-- && (*d++ = *src++)); - *d = 0; - return (dest); -} - -void -strupper(char *s) -{ - while (*s) { - /* - * #if !defined(KANJI_WIN95_COMPATIBILITY) - * if(lp_client_code_page() == KANJI_CODEPAGE) - * { - * - * if (is_shift_jis (*s)) - * { - * if (is_sj_lower (s[0], s[1])) - * s[1] = sj_toupper2 (s[1]); - * s += 2; - * } - * else if (is_kana (*s)) - * { - * s++; - * } - * else - * { - * if (islower(*s)) - * *s = toupper(*s); - * s++; - * } - * } - * else - * #endif *//* KANJI_WIN95_COMPATIBILITY */ - { - if (islower((int)(unsigned char)*s)) - *s = xtoupper(*s); - s++; - } - } -} diff --git a/libntlmauth/smb-md4.c b/libntlmauth/smb-md4.c deleted file mode 100644 index 9c06b809aa..0000000000 --- a/libntlmauth/smb-md4.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Unix SMB/Netbios implementation. - * Version 1.9. - * a implementation of MD4 designed for use in the SMB authentication protocol - * Copyright (C) Andrew Tridgell 1997 - * - * 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. - */ - - -/* NOTE: This code makes no attempt to be fast! - * - * It assumes that a int is at least 32 bits long - */ -#include "config.h" -#include "libntlmauth/smblib-priv.h" -#include "libntlmauth/smb-md4.h" - -#include - -static uint32_t A, B, C, D; - -static uint32_t -F(uint32_t X, uint32_t Y, uint32_t Z) -{ - return (X & Y) | ((~X) & Z); -} - -static uint32_t -G(uint32_t X, uint32_t Y, uint32_t Z) -{ - return (X & Y) | (X & Z) | (Y & Z); -} - -static uint32_t -H(uint32_t X, uint32_t Y, uint32_t Z) -{ - return X ^ Y ^ Z; -} - -static uint32_t -lshift(uint32_t x, int s) -{ - x &= 0xFFFFFFFF; - return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s)); -} - -#define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s) -#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + (uint32_t)0x5A827999,s) -#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (uint32_t)0x6ED9EBA1,s) - -/* this applies md4 to 64 byte chunks */ -static void -mdfour64(uint32_t * M) -{ - int j; - uint32_t AA, BB, CC, DD; - uint32_t X[16]; - - for (j = 0; j < 16; j++) - X[j] = M[j]; - - AA = A; - BB = B; - CC = C; - DD = D; - - ROUND1(A, B, C, D, 0, 3); - ROUND1(D, A, B, C, 1, 7); - ROUND1(C, D, A, B, 2, 11); - ROUND1(B, C, D, A, 3, 19); - ROUND1(A, B, C, D, 4, 3); - ROUND1(D, A, B, C, 5, 7); - ROUND1(C, D, A, B, 6, 11); - ROUND1(B, C, D, A, 7, 19); - ROUND1(A, B, C, D, 8, 3); - ROUND1(D, A, B, C, 9, 7); - ROUND1(C, D, A, B, 10, 11); - ROUND1(B, C, D, A, 11, 19); - ROUND1(A, B, C, D, 12, 3); - ROUND1(D, A, B, C, 13, 7); - ROUND1(C, D, A, B, 14, 11); - ROUND1(B, C, D, A, 15, 19); - - ROUND2(A, B, C, D, 0, 3); - ROUND2(D, A, B, C, 4, 5); - ROUND2(C, D, A, B, 8, 9); - ROUND2(B, C, D, A, 12, 13); - ROUND2(A, B, C, D, 1, 3); - ROUND2(D, A, B, C, 5, 5); - ROUND2(C, D, A, B, 9, 9); - ROUND2(B, C, D, A, 13, 13); - ROUND2(A, B, C, D, 2, 3); - ROUND2(D, A, B, C, 6, 5); - ROUND2(C, D, A, B, 10, 9); - ROUND2(B, C, D, A, 14, 13); - ROUND2(A, B, C, D, 3, 3); - ROUND2(D, A, B, C, 7, 5); - ROUND2(C, D, A, B, 11, 9); - ROUND2(B, C, D, A, 15, 13); - - ROUND3(A, B, C, D, 0, 3); - ROUND3(D, A, B, C, 8, 9); - ROUND3(C, D, A, B, 4, 11); - ROUND3(B, C, D, A, 12, 15); - ROUND3(A, B, C, D, 2, 3); - ROUND3(D, A, B, C, 10, 9); - ROUND3(C, D, A, B, 6, 11); - ROUND3(B, C, D, A, 14, 15); - ROUND3(A, B, C, D, 1, 3); - ROUND3(D, A, B, C, 9, 9); - ROUND3(C, D, A, B, 5, 11); - ROUND3(B, C, D, A, 13, 15); - ROUND3(A, B, C, D, 3, 3); - ROUND3(D, A, B, C, 11, 9); - ROUND3(C, D, A, B, 7, 11); - ROUND3(B, C, D, A, 15, 15); - - A += AA; - B += BB; - C += CC; - D += DD; - - A &= 0xFFFFFFFF; - B &= 0xFFFFFFFF; - C &= 0xFFFFFFFF; - D &= 0xFFFFFFFF; - - for (j = 0; j < 16; j++) - X[j] = 0; -} - -static void -copy64(uint32_t * M, unsigned char *in) -{ - int i; - - for (i = 0; i < 16; i++) - M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) | - (in[i * 4 + 1] << 8) | (in[i * 4 + 0] << 0); -} - -static void -copy4(unsigned char *out, uint32_t x) -{ - out[0] = x & 0xFF; - out[1] = (x >> 8) & 0xFF; - out[2] = (x >> 16) & 0xFF; - out[3] = (x >> 24) & 0xFF; -} - -/* produce a md4 message digest from data of length n bytes */ -void -mdfour(unsigned char *out, unsigned char *in, int n) -{ - unsigned char buf[128]; - uint32_t M[16]; - uint32_t b = n * 8; - int i; - - A = 0x67452301; - B = 0xefcdab89; - C = 0x98badcfe; - D = 0x10325476; - - while (n > 64) { - copy64(M, in); - mdfour64(M); - in += 64; - n -= 64; - } - - for (i = 0; i < 128; i++) - buf[i] = 0; - memcpy(buf, in, n); - buf[n] = 0x80; - - if (n <= 55) { - copy4(buf + 56, b); - copy64(M, buf); - mdfour64(M); - } else { - copy4(buf + 120, b); - copy64(M, buf); - mdfour64(M); - copy64(M, buf + 64); - mdfour64(M); - } - - for (i = 0; i < 128; i++) - buf[i] = 0; - copy64(M, buf); - - copy4(out, A); - copy4(out + 4, B); - copy4(out + 8, C); - copy4(out + 12, D); - - A = B = C = D = 0; -} diff --git a/libntlmauth/smb.h b/libntlmauth/smb.h deleted file mode 100644 index dd841fcb23..0000000000 --- a/libntlmauth/smb.h +++ /dev/null @@ -1,358 +0,0 @@ -/* UNIX SMBlib NetBIOS implementation - * - * Version 1.0 - * SMBlib Defines - * - * 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. - */ -#ifndef _SMBVAL_SMBLIB_H -#define _SMBVAL_SMBLIB_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef PRIVATE_API -#define SMBLIB_DEFAULT_DOMAIN "anydom" -#endif /* PRIVATE_API */ - -#ifdef __cplusplus -extern "C" { -#endif - - /* To get the error class we want the first 8 bits */ - /* Because we just grab 4bytes from the SMB header, we have to re-order */ - /* here, but it makes the NtStatus part easier in future */ - -#define SMBlib_Error_Class(p) (p & 0x000000FF) - - /* To get the error code, we want the bottom 16 bits */ - -#define SMBlib_Error_Code(p) (((unsigned int)p & 0xFFFF0000) >>16) - - /* Error CLASS codes and etc ... */ - -#define SMBC_SUCCESS 0 -#define SMBC_ERRDOS 0x01 -#define SMBC_ERRSRV 0x02 -#define SMBC_ERRHRD 0x03 -#define SMBC_ERRCMD 0xFF - - /* Success error codes */ - -#define SMBS_BUFFERED 0x54 -#define SMBS_LOGGED 0x55 -#define SMBS_DISPLAYED 0x56 - - /* ERRDOS Error codes */ - -#define SMBD_badfunc 0x01 -#define SMBD_badfile 0x02 -#define SMBD_badpath 0x03 -#define SMBD_nofids 0x04 -#define SMBD_noaccess 0x05 -#define SMBD_badfid 0x06 -#define SMBD_badmcb 0x07 -#define SMBD_nomem 0x08 -#define SMBD_badmem 0x09 -#define SMBD_badenv 0x0A -#define SMBD_badformat 0x0B -#define SMBD_badaccess 0x0C -#define SMBD_baddata 0x0D -#define SMBD_reserved 0x0E -#define SMBD_baddrive 0x0F -#define SMBD_remcd 0x10 -#define SMBD_diffdevice 0x11 -#define SMBD_nofiles 0x12 -#define SMBD_badshare 0x20 -#define SMBD_errlock 0x21 -#define SMBD_filexists 0x50 - - /* Server errors ... */ - -#define SMBV_error 0x01 /* Generic error */ -#define SMBV_badpw 0x02 -#define SMBV_badtype 0x03 -#define SMBV_access 0x04 -#define SMBV_invnid 0x05 -#define SMBV_invnetname 0x06 -#define SMBV_invdevice 0x07 -#define SMBV_qfull 0x31 -#define SMBV_qtoobig 0x32 -#define SMBV_qeof 0x33 -#define SMBV_invpfid 0x34 -#define SMBV_paused 0x51 -#define SMBV_msgoff 0x52 -#define SMBV_noroom 0x53 -#define SMBV_rmuns 0x57 -#define SMBV_nosupport 0xFFFF - - /* Hardware error codes ... */ - -#define SMBH_nowrite 0x13 -#define SMBH_badunit 0x14 -#define SMBH_notready 0x15 -#define SMBH_badcmd 0x16 -#define SMBH_data 0x17 -#define SMBH_badreq 0x18 -#define SMBH_seek 0x19 -#define SMBH_badmedia 0x1A -#define SMBH_badsector 0x1B -#define SMBH_nopaper 0x1C -#define SMBH_write 0x1D -#define SMBH_read 0x1E -#define SMBH_general 0x1F -#define SMBH_badshare 0x20 - - /* Access mode defines ... */ - -#define SMB_AMODE_WTRU 0x4000 -#define SMB_AMODE_NOCACHE 0x1000 -#define SMB_AMODE_COMPAT 0x0000 -#define SMB_AMODE_DENYRWX 0x0010 -#define SMB_AMODE_DENYW 0x0020 -#define SMB_AMODE_DENYRX 0x0030 -#define SMB_AMODE_DENYNONE 0x0040 -#define SMB_AMODE_OPENR 0x0000 -#define SMB_AMODE_OPENW 0x0001 -#define SMB_AMODE_OPENRW 0x0002 -#define SMB_AMODE_OPENX 0x0003 -#define SMB_AMODE_FCBOPEN 0x00FF -#define SMB_AMODE_LOCUNKN 0x0000 -#define SMB_AMODE_LOCMSEQ 0x0100 -#define SMB_AMODE_LOCMRAN 0x0200 -#define SMB_AMODE_LOCRAL 0x0300 - - /* File attribute encoding ... */ - -#define SMB_FA_ORD 0x00 -#define SMB_FA_ROF 0x01 -#define SMB_FA_HID 0x02 -#define SMB_FA_SYS 0x04 -#define SMB_FA_VOL 0x08 -#define SMB_FA_DIR 0x10 -#define SMB_FA_ARC 0x20 - - /* Define the protocol types ... */ - -#define SMB_P_Unknown -1 /* Hmmm, is this smart? */ -#define SMB_P_Core 0 -#define SMB_P_CorePlus 1 -#define SMB_P_DOSLanMan1 2 -#define SMB_P_LanMan1 3 -#define SMB_P_DOSLanMan2 4 -#define SMB_P_LanMan2 5 -#define SMB_P_DOSLanMan2_1 6 -#define SMB_P_LanMan2_1 7 -#define SMB_P_NT1 8 - - /* SMBlib return codes */ - /* We want something that indicates whether or not the return code was a */ - /* remote error, a local error in SMBlib or returned from lower layer ... */ - /* Wonder if this will work ... */ - /* SMBlibE_Remote = 1 indicates remote error */ - /* SMBlibE_ values < 0 indicate local error with more info available */ - /* SMBlibE_ values >1 indicate local from SMBlib code errors? */ - -#define SMBlibE_Success 0 -#define SMBlibE_Remote 1 /* Remote error, get more info from con */ -#define SMBlibE_BAD -1 -#define SMBlibE_LowerLayer 2 /* Lower layer error */ -#define SMBlibE_NotImpl 3 /* Function not yet implemented */ -#define SMBlibE_ProtLow 4 /* Protocol negotiated does not support req */ -#define SMBlibE_NoSpace 5 /* No space to allocate a structure */ -#define SMBlibE_BadParam 6 /* Bad parameters */ -#define SMBlibE_NegNoProt 7 /* None of our protocols was liked */ -#define SMBlibE_SendFailed 8 /* Sending an SMB failed */ -#define SMBlibE_RecvFailed 9 /* Receiving an SMB failed */ -#define SMBlibE_GuestOnly 10 /* Logged in as guest */ -#define SMBlibE_CallFailed 11 /* Call remote end failed */ -#define SMBlibE_ProtUnknown 12 /* Protocol unknown */ -#define SMBlibE_NoSuchMsg 13 /* Keep this up to date */ - - typedef struct { /* A structure for a Dirent */ - - unsigned char resume_key[21]; /* Don't touch this */ - unsigned char file_attributes; /* Attributes of file */ - unsigned int date_time; /* date and time of last mod */ - unsigned int size; - char filename[13]; /* The name of the file */ - - } SMB_CP_dirent; - - /* Handle Structures */ - - typedef struct SMB_Tree_Structure * SMB_Tree_Handle; - typedef struct SMB_Connect_Def * SMB_Handle_Type; - - struct SMB_Tree_Structure { - SMB_Tree_Handle next, prev; - SMB_Handle_Type con; - char path[129]; - char device_type[20]; - int mbs; /* Local MBS */ - int tid; - }; - - struct SMB_Connect_Def { - SMB_Handle_Type Next_Con, Prev_Con; /* Next and previous conn */ - int protocol; /* What is the protocol */ - int prot_IDX; /* And what is the index */ - void *Trans_Connect; /* The connection */ - - /* All these strings should be malloc'd */ - - char service[80], username[80], password[80], desthost[80], sock_options[80]; - char address[80], myname[80]; - - SMB_Tree_Handle first_tree, last_tree; /* List of trees on this server */ - - int gid; /* Group ID, do we need it? */ - int mid; /* Multiplex ID? We might need one per con */ - int pid; /* Process ID */ - - int uid; /* Authenticated user id. */ - - /* It is pretty clear that we need to bust some of */ - /* these out into a per TCon record, as there may */ - /* be multiple TCon's per server, etc ... later */ - - int port; /* port to use in case not default, this is a TCPism! */ - - int max_xmit; /* Max xmit permitted by server */ - int Security; /* 0 = share, 1 = user */ - int Raw_Support; /* bit 0 = 1 = Read Raw supported, 1 = 1 Write raw */ - int16_t encrypt_passwords; /* TRUE/FALSE. FALSE = don't */ - int MaxMPX, MaxVC, MaxRaw; - unsigned int SessionKey, Capabilities; - int SvrTZ; /* Server Time Zone */ - int Encrypt_Key_Len; - char Encrypt_Key[80], Domain[80], PDomain[80], OSName[80], LMType[40]; - char Svr_OS[80], Svr_LMType[80], Svr_PDom[80]; - }; - - /* Initialize the SMBlib package */ - int SMB_Init(void); - - /* Create a handle to allow us to set/override some parameters ... */ - SMB_Handle_Type SMB_Create_Con_Handle(); - - /* Connect to a server, but do not do a tree con etc ... */ - SMB_Handle_Type SMB_Connect_Server(SMB_Handle_Type Con_Handle, - char *server, - char *NTdomain); - - /* Connect to a server and give us back a handle. If Con == NULL, create */ - /* The handle and populate it with defaults */ - SMB_Handle_Type SMB_Connect(SMB_Handle_Type Con_Handle, - SMB_Tree_Handle * tree, - char *service, - char *username, - char *password); - - int SMB_Logon_Server(SMB_Handle_Type Con_Handle, - char *UserName, - char *PassWord, - char *UserDomain, - int precrypted); - - /* Negotiate a protocol */ - int SMB_Negotiate(SMB_Handle_Type con, char const *Prots[]); - - /* Connect to a tree ... */ - SMB_Tree_Handle SMB_TreeConnect(SMB_Handle_Type con, - SMB_Tree_Handle tree, - char *path, - char *password, - char const *device); - - - /* Disconnect a tree ... */ - int SMB_TreeDisconect(void *tree_handle); - - /* Open a file */ - void *SMB_Open(void *tree_handle, - void *file_handle, - char *file_name, - unsigned short mode, - unsigned short search); - - /* Close a file */ - int SMB_Close(void *file_handle); - - /* Disconnect from server. Has flag to specify whether or not we keep the */ - /* handle. */ - int SMB_Discon(SMB_Handle_Type Con, - int KeepHandle); - - void *SMB_Create(void *Tree_Handle, - void *File_Handle, - char *file_name, - short search); - - int SMB_Delete(void *tree, - char *file_name, - short search); - - int SMB_Create_Dir(void *tree, - char *dir_name); - - int SMB_Delete_Dir(void *tree, - char *dir_name); - - int SMB_Check_Dir(void *tree, - char *dir_name); - - int SMB_Get_Last_Error(); - - int SMB_Get_Last_SMB_Err(); - - int SMB_Get_Error_Msg(int msg, - char *msgbuf, - int len); - - void *SMB_Logon_And_TCon(SMB_Handle_Type Con_Handle, - void *tree, - char *user, - char *pass, - char *service, - char *st); - - /* Encryption Functions */ - - void SMBencrypt(unsigned char * passwd, - unsigned char * c8, - unsigned char * p24); - - void SMBNTencrypt(unsigned char * passwd, - unsigned char * c8, - unsigned char * p24); - -#ifdef __cplusplus -} -#endif - -#endif /* _SMBVAL_SMBLIB_H */ diff --git a/libntlmauth/smblib-priv.h b/libntlmauth/smblib-priv.h deleted file mode 100644 index b83864ce17..0000000000 --- a/libntlmauth/smblib-priv.h +++ /dev/null @@ -1,592 +0,0 @@ -#ifndef __SMBLIB_PRIV_H__ -#define __SMBLIB_PRIV_H__ - -/* UNIX SMBlib NetBIOS implementation - * - * Version 1.0 - * SMBlib private Defines - * - * 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. - */ - -/* The public API bits */ -#define PRIVATE_API -#include "libntlmauth/smb.h" - -//#include "std-defines.h" -#include - -//#include "byteorder.h" /* Hmmm ... not good */ - -#ifndef max -#define max(a,b) ((a) < (b) ? (b) : (a)) -#endif - -#define SMB_DEF_IDF 0x424D53FF /* "\377SMB" */ - -/* Core protocol commands */ - -#define SMBmkdir 0x00 /* create directory */ -#define SMBrmdir 0x01 /* delete directory */ -#define SMBopen 0x02 /* open file */ -#define SMBcreate 0x03 /* create file */ -#define SMBclose 0x04 /* close file */ -#define SMBflush 0x05 /* flush file */ -#define SMBunlink 0x06 /* delete file */ -#define SMBmv 0x07 /* rename file */ -#define SMBgetatr 0x08 /* get file attributes */ -#define SMBsetatr 0x09 /* set file attributes */ -#define SMBread 0x0A /* read from file */ -#define SMBwrite 0x0B /* write to file */ -#define SMBlock 0x0C /* lock byte range */ -#define SMBunlock 0x0D /* unlock byte range */ -#define SMBctemp 0x0E /* create temporary file */ -#define SMBmknew 0x0F /* make new file */ -#define SMBchkpth 0x10 /* check directory path */ -#define SMBexit 0x11 /* process exit */ -#define SMBlseek 0x12 /* seek */ -#define SMBtcon 0x70 /* tree connect */ -#define SMBtdis 0x71 /* tree disconnect */ -#define SMBnegprot 0x72 /* negotiate protocol */ -#define SMBdskattr 0x80 /* get disk attributes */ -#define SMBsearch 0x81 /* search directory */ -#define SMBsplopen 0xC0 /* open print spool file */ -#define SMBsplwr 0xC1 /* write to print spool file */ -#define SMBsplclose 0xC2 /* close print spool file */ -#define SMBsplretq 0xC3 /* return print queue */ -#define SMBsends 0xD0 /* send single block message */ -#define SMBsendb 0xD1 /* send broadcast message */ -#define SMBfwdname 0xD2 /* forward user name */ -#define SMBcancelf 0xD3 /* cancel forward */ -#define SMBgetmac 0xD4 /* get machine name */ -#define SMBsendstrt 0xD5 /* send start of multi-block message */ -#define SMBsendend 0xD6 /* send end of multi-block message */ -#define SMBsendtxt 0xD7 /* send text of multi-block message */ - -/* CorePlus protocol */ - -#define SMBlockread 0x13 /* Lock a range and read it */ -#define SMBwriteunlock 0x14 /* Unlock a range and then write */ -#define SMBreadbraw 0x1a /* read a block of data without smb header ohead */ -#define SMBwritebraw 0x1d /* write a block of data without smb header ohead */ -#define SMBwritec 0x20 /* secondary write request */ -#define SMBwriteclose 0x2c /* write a file and then close it */ - -/* DOS Extended Protocol */ - -#define SMBreadBraw 0x1A /* read block raw */ -#define SMBreadBmpx 0x1B /* read block multiplexed */ -#define SMBreadBs 0x1C /* read block (secondary response) */ -#define SMBwriteBraw 0x1D /* write block raw */ -#define SMBwriteBmpx 0x1E /* write block multiplexed */ -#define SMBwriteBs 0x1F /* write block (secondary request) */ -#define SMBwriteC 0x20 /* write complete response */ -#define SMBsetattrE 0x22 /* set file attributes expanded */ -#define SMBgetattrE 0x23 /* get file attributes expanded */ -#define SMBlockingX 0x24 /* lock/unlock byte ranges and X */ -#define SMBtrans 0x25 /* transaction - name, bytes in/out */ -#define SMBtranss 0x26 /* transaction (secondary request/response) */ -#define SMBioctl 0x27 /* IOCTL */ -#define SMBioctls 0x28 /* IOCTL (secondary request/response) */ -#define SMBcopy 0x29 /* copy */ -#define SMBmove 0x2A /* move */ -#define SMBecho 0x2B /* echo */ -#define SMBopenX 0x2D /* open and X */ -#define SMBreadX 0x2E /* read and X */ -#define SMBwriteX 0x2F /* write and X */ -#define SMBsesssetupX 0x73 /* Session Set Up & X (including User Logon) */ -#define SMBtconX 0x75 /* tree connect and X */ -#define SMBffirst 0x82 /* find first */ -#define SMBfunique 0x83 /* find unique */ -#define SMBfclose 0x84 /* find close */ -#define SMBinvalid 0xFE /* invalid command */ - -/* Any more ? */ - -#define SMBdatablockID 0x01 /* A data block identifier */ -#define SMBdialectID 0x02 /* A dialect id */ -#define SMBpathnameID 0x03 /* A pathname ID */ -#define SMBasciiID 0x04 /* An ascii string ID */ -#define SMBvariableblockID 0x05 /* A variable block ID */ - -/* some other defines we need */ - -/* Flags defines ... */ - -#define SMB_FLG2_NON_DOS 0x01 /* We know non dos names */ -#define SMB_FLG2_EXT_ATR 0x02 /* We know about Extended Attributes */ -#define SMB_FLG2_LNG_NAM 0x04 /* Long names ? */ - -/* Not good */ -#if 0 -typedef unsigned short WORD; -typedef unsigned short UWORD; -typedef unsigned int ULONG; -typedef unsigned char BYTE; -typedef unsigned char UCHAR; -#endif - -/* Some macros to allow access to actual packet data so that we */ -/* can change the underlying representation of packets. */ -/* */ -/* The current formats vying for attention are a fragment */ -/* approach where the SMB header is a fragment linked to the */ -/* data portion with the transport protocol (rfcnb or whatever) */ -/* being linked on the front. */ -/* */ -/* The other approach is where the whole packet is one array */ -/* of bytes with space allowed on the front for the packet */ -/* headers. */ - -#define SMB_Hdr(p) (char *)(p -> data) - -/* SMB Hdr def for File Sharing Protocol? From MS and Intel, */ -/* Intel PN 138446 Doc Version 2.0, Nov 7, 1988. This def also */ -/* applies to LANMAN1.0 as well as the Core Protocol */ -/* The spec states that wct and bcc must be present, even if 0 */ - -/* We define these as offsets into a char SMB[] array for the */ -/* sake of portability */ - -/* NOTE!. Some of the length defines, SMB__len do not include */ -/* the data that follows in the SMB packet, so the code will have to */ -/* take that into account. */ - -#define SMB_hdr_idf_offset 0 /* 0xFF,'SMB' 0-3 */ -#define SMB_hdr_com_offset 4 /* BYTE 4 */ -#define SMB_hdr_rcls_offset 5 /* BYTE 5 */ -#define SMB_hdr_reh_offset 6 /* BYTE 6 */ -#define SMB_hdr_err_offset 7 /* WORD 7 */ -#define SMB_hdr_reb_offset 9 /* BYTE 9 */ -#define SMB_hdr_flg_offset 9 /* same as reb ... */ -#define SMB_hdr_res_offset 10 /* 7 WORDs 10 */ -#define SMB_hdr_res0_offset 10 /* WORD 10 */ -#define SMB_hdr_flg2_offset 10 /* WORD */ -#define SMB_hdr_res1_offset 12 /* WORD 12 */ -#define SMB_hdr_res2_offset 14 -#define SMB_hdr_res3_offset 16 -#define SMB_hdr_res4_offset 18 -#define SMB_hdr_res5_offset 20 -#define SMB_hdr_res6_offset 22 -#define SMB_hdr_tid_offset 24 -#define SMB_hdr_pid_offset 26 -#define SMB_hdr_uid_offset 28 -#define SMB_hdr_mid_offset 30 -#define SMB_hdr_wct_offset 32 - -#define SMB_hdr_len 33 /* 33 byte header? */ - -#define SMB_hdr_axc_offset 33 /* AndX Command */ -#define SMB_hdr_axr_offset 34 /* AndX Reserved */ -#define SMB_hdr_axo_offset 35 /* Offset from start to WCT of AndX cmd */ - -/* Format of the Negotiate Protocol SMB */ - -#define SMB_negp_bcc_offset 33 -#define SMB_negp_buf_offset 35 /* Where the buffer starts */ -#define SMB_negp_len 35 /* plus the data */ - -/* Format of the Negotiate Response SMB, for CoreProtocol, LM1.2 and */ -/* NT LM 0.12. wct will be 1 for CoreProtocol, 13 for LM 1.2, and 17 */ -/* for NT LM 0.12 */ - -#define SMB_negrCP_idx_offset 33 /* Response to the neg req */ -#define SMB_negrCP_bcc_offset 35 -#define SMB_negrLM_idx_offset 33 /* dialect index */ -#define SMB_negrLM_sec_offset 35 /* Security mode */ -#define SMB_sec_user_mask 0x01 /* 0 = share, 1 = user */ -#define SMB_sec_encrypt_mask 0x02 /* pick out encrypt */ -#define SMB_negrLM_mbs_offset 37 /* max buffer size */ -#define SMB_negrLM_mmc_offset 39 /* max mpx count */ -#define SMB_negrLM_mnv_offset 41 /* max number of VCs */ -#define SMB_negrLM_rm_offset 43 /* raw mode support bit vec */ -#define SMB_read_raw_mask 0x01 -#define SMB_write_raw_mask 0x02 -#define SMB_negrLM_sk_offset 45 /* session key, 32 bits */ -#define SMB_negrLM_st_offset 49 /* Current server time */ -#define SMB_negrLM_sd_offset 51 /* Current server date */ -#define SMB_negrLM_stz_offset 53 /* Server Time Zone */ -#define SMB_negrLM_ekl_offset 55 /* encryption key length */ -#define SMB_negrLM_res_offset 57 /* reserved */ -#define SMB_negrLM_bcc_offset 59 /* bcc */ -#define SMB_negrLM_len 61 /* 61 bytes ? */ -#define SMB_negrLM_buf_offset 61 /* Where the fun begins */ - -#define SMB_negrNTLM_idx_offset 33 /* Selected protocol */ -#define SMB_negrNTLM_sec_offset 35 /* Security more */ -#define SMB_negrNTLM_mmc_offset 36 /* Different format above */ -#define SMB_negrNTLM_mnv_offset 38 /* Max VCs */ -#define SMB_negrNTLM_mbs_offset 40 /* MBS now a long */ -#define SMB_negrNTLM_mrs_offset 44 /* Max raw size */ -#define SMB_negrNTLM_sk_offset 48 /* Session Key */ -#define SMB_negrNTLM_cap_offset 52 /* Capabilities */ -#define SMB_negrNTLM_stl_offset 56 /* Server time low */ -#define SMB_negrNTLM_sth_offset 60 /* Server time high */ -#define SMB_negrNTLM_stz_offset 64 /* Server time zone */ -#define SMB_negrNTLM_ekl_offset 66 /* Encrypt key len */ -#define SMB_negrNTLM_bcc_offset 67 /* Bcc */ -#define SMB_negrNTLM_len 69 -#define SMB_negrNTLM_buf_offset 69 - -/* Offsets related to Tree Connect */ - -#define SMB_tcon_bcc_offset 33 -#define SMB_tcon_buf_offset 35 /* where the data is for tcon */ -#define SMB_tcon_len 35 /* plus the data */ - -#define SMB_tconr_mbs_offset 33 /* max buffer size */ -#define SMB_tconr_tid_offset 35 /* returned tree id */ -#define SMB_tconr_bcc_offset 37 -#define SMB_tconr_len 39 - -#define SMB_tconx_axc_offset 33 /* And X Command */ -#define SMB_tconx_axr_offset 34 /* reserved */ -#define SMB_tconx_axo_offset 35 /* Next command offset */ -#define SMB_tconx_flg_offset 37 /* Flags, bit0=1 means disc TID */ -#define SMB_tconx_pwl_offset 39 /* Password length */ -#define SMB_tconx_bcc_offset 41 /* bcc */ -#define SMB_tconx_buf_offset 43 /* buffer */ -#define SMB_tconx_len 43 /* up to data ... */ - -#define SMB_tconxr_axc_offset 33 /* Where the AndX Command is */ -#define SMB_tconxr_axr_offset 34 /* Reserved */ -#define SMB_tconxr_axo_offset 35 /* AndX offset location */ - -/* Offsets related to tree_disconnect */ - -#define SMB_tdis_bcc_offset 33 /* bcc */ -#define SMB_tdis_len 35 /* total len */ - -#define SMB_tdisr_bcc_offset 33 /* bcc */ -#define SMB_tdisr_len 35 - -/* Offsets related to Open Request */ - -#define SMB_open_mod_offset 33 /* Mode to open with */ -#define SMB_open_atr_offset 35 /* Attributes of file */ -#define SMB_open_bcc_offset 37 /* bcc */ -#define SMB_open_buf_offset 39 /* File name */ -#define SMB_open_len 39 /* Plus the file name */ - -#define SMB_openx_axc_offset 33 /* Next command */ -#define SMB_openx_axr_offset 34 /* Reserved */ -#define SMB_openx_axo_offset 35 /* offset of next wct */ -#define SMB_openx_flg_offset 37 /* Flags, bit0 = need more info */ -/* bit1 = exclusive oplock */ -/* bit2 = batch oplock */ -#define SMB_openx_mod_offset 39 /* mode to open with */ -#define SMB_openx_atr_offset 41 /* search attributes */ -#define SMB_openx_fat_offset 43 /* File attributes */ -#define SMB_openx_tim_offset 45 /* time and date of creat */ -#define SMB_openx_ofn_offset 49 /* Open function */ -#define SMB_openx_als_offset 51 /* Space to allocate on */ -#define SMB_openx_res_offset 55 /* reserved */ -#define SMB_openx_bcc_offset 63 /* bcc */ -#define SMB_openx_buf_offset 65 /* Where file name goes */ -#define SMB_openx_len 65 - -#define SMB_openr_fid_offset 33 /* FID returned */ -#define SMB_openr_atr_offset 35 /* Attributes opened with */ -#define SMB_openr_tim_offset 37 /* Last mod time of file */ -#define SMB_openr_fsz_offset 41 /* File size 4 bytes */ -#define SMB_openr_acc_offset 45 /* Access allowed */ -#define SMB_openr_bcc_offset 47 -#define SMB_openr_len 49 - -#define SMB_openxr_axc_offset 33 /* And X command */ -#define SMB_openxr_axr_offset 34 /* reserved */ -#define SMB_openxr_axo_offset 35 /* offset to next command */ -#define SMB_openxr_fid_offset 37 /* FID returned */ -#define SMB_openxr_fat_offset 39 /* File attributes returned */ -#define SMB_openxr_tim_offset 41 /* File creation date etc */ -#define SMB_openxr_fsz_offset 45 /* Size of file */ -#define SMB_openxr_acc_offset 49 /* Access granted */ - -#define SMB_clos_fid_offset 33 /* FID to close */ -#define SMB_clos_tim_offset 35 /* Last mod time */ -#define SMB_clos_bcc_offset 39 /* bcc */ -#define SMB_clos_len 41 - -/* Offsets related to Write requests */ - -#define SMB_write_fid_offset 33 /* FID to write */ -#define SMB_write_cnt_offset 35 /* bytes to write */ -#define SMB_write_ofs_offset 37 /* location to write to */ -#define SMB_write_clf_offset 41 /* advisory count left */ -#define SMB_write_bcc_offset 43 /* bcc = data bytes + 3 */ -#define SMB_write_buf_offset 45 /* Data=0x01, len, data */ -#define SMB_write_len 45 /* plus the data ... */ - -#define SMB_writr_cnt_offset 33 /* Count of bytes written */ -#define SMB_writr_bcc_offset 35 /* bcc */ -#define SMB_writr_len 37 - -/* Offsets related to read requests */ - -#define SMB_read_fid_offset 33 /* FID of file to read */ -#define SMB_read_cnt_offset 35 /* count of words to read */ -#define SMB_read_ofs_offset 37 /* Where to read from */ -#define SMB_read_clf_offset 41 /* Advisory count to go */ -#define SMB_read_bcc_offset 43 -#define SMB_read_len 45 - -#define SMB_readr_cnt_offset 33 /* Count of bytes returned */ -#define SMB_readr_res_offset 35 /* 4 shorts reserved, 8 bytes */ -#define SMB_readr_bcc_offset 43 /* bcc */ -#define SMB_readr_bff_offset 45 /* buffer format char = 0x01 */ -#define SMB_readr_len_offset 46 /* buffer len */ -#define SMB_readr_len 45 /* length of the readr before data */ - -/* Offsets for Create file */ - -#define SMB_creat_atr_offset 33 /* Attributes of new file ... */ -#define SMB_creat_tim_offset 35 /* Time of creation */ -#define SMB_creat_dat_offset 37 /* 4004BCE :-) */ -#define SMB_creat_bcc_offset 39 /* bcc */ -#define SMB_creat_buf_offset 41 -#define SMB_creat_len 41 /* Before the data */ - -#define SMB_creatr_fid_offset 33 /* FID of created file */ - -/* Offsets for Delete file */ - -#define SMB_delet_sat_offset 33 /* search attribites */ -#define SMB_delet_bcc_offset 35 /* bcc */ -#define SMB_delet_buf_offset 37 -#define SMB_delet_len 37 - -/* Offsets for SESSION_SETUP_ANDX for both LM and NT LM protocols */ - -#define SMB_ssetpLM_mbs_offset 37 /* Max buffer Size, allow for AndX */ -#define SMB_ssetpLM_mmc_offset 39 /* max multiplex count */ -#define SMB_ssetpLM_vcn_offset 41 /* VC number if new VC */ -#define SMB_ssetpLM_snk_offset 43 /* Session Key */ -#define SMB_ssetpLM_pwl_offset 47 /* password length */ -#define SMB_ssetpLM_res_offset 49 /* reserved */ -#define SMB_ssetpLM_bcc_offset 53 /* bcc */ -#define SMB_ssetpLM_len 55 /* before data ... */ -#define SMB_ssetpLM_buf_offset 55 - -#define SMB_ssetpNTLM_mbs_offset 37 /* Max Buffer Size for NT LM 0.12 */ -/* and above */ -#define SMB_ssetpNTLM_mmc_offset 39 /* Max Multiplex count */ -#define SMB_ssetpNTLM_vcn_offset 41 /* VC Number */ -#define SMB_ssetpNTLM_snk_offset 43 /* Session key */ -#define SMB_ssetpNTLM_cipl_offset 47 /* Case Insensitive PW Len */ -#define SMB_ssetpNTLM_cspl_offset 49 /* Unicode pw len */ -#define SMB_ssetpNTLM_res_offset 51 /* reserved */ -#define SMB_ssetpNTLM_cap_offset 55 /* server capabilities */ -#define SMB_ssetpNTLM_bcc_offset 59 /* bcc */ -#define SMB_ssetpNTLM_len 61 /* before data */ -#define SMB_ssetpNTLM_buf_offset 61 - -#define SMB_ssetpr_axo_offset 35 /* Offset of next response ... */ -#define SMB_ssetpr_act_offset 37 /* action, bit 0 = 1 => guest */ -#define SMB_ssetpr_bcc_offset 39 /* bcc */ -#define SMB_ssetpr_buf_offset 41 /* Native OS etc */ - -/* Offsets for SMB create directory */ - -#define SMB_creatdir_bcc_offset 33 /* only a bcc here */ -#define SMB_creatdir_buf_offset 35 /* Where things start */ -#define SMB_creatdir_len 35 - -/* Offsets for SMB delete directory */ - -#define SMB_deletdir_bcc_offset 33 /* only a bcc here */ -#define SMB_deletdir_buf_offset 35 /* where things start */ -#define SMB_deletdir_len 35 - -/* Offsets for SMB check directory */ - -#define SMB_checkdir_bcc_offset 33 /* Only a bcc here */ -#define SMB_checkdir_buf_offset 35 /* where things start */ -#define SMB_checkdir_len 35 - -/* Offsets for SMB search */ - -#define SMB_search_mdc_offset 33 /* Max Dir ents to return */ -#define SMB_search_atr_offset 35 /* Search attributes */ -#define SMB_search_bcc_offset 37 /* bcc */ -#define SMB_search_buf_offset 39 /* where the action is */ -#define SMB_search_len 39 - -#define SMB_searchr_dec_offset 33 /* Dir ents returned */ -#define SMB_searchr_bcc_offset 35 /* bcc */ -#define SMB_searchr_buf_offset 37 /* Where the action starts */ -#define SMB_searchr_len 37 /* before the dir ents */ - -#define SMB_searchr_dirent_len 43 /* 53 bytes */ - -/* Defines for SMB transact and transact2 calls */ - -#define SMB_trans_tpc_offset 33 /* Total param count */ -#define SMB_trans_tdc_offset 35 /* total Data count */ -#define SMB_trans_mpc_offset 37 /* Max params bytes to return */ -#define SMB_trans_mdc_offset 39 /* Max data bytes to return */ -#define SMB_trans_msc_offset 41 /* Max setup words to return */ -#define SMB_trans_rs1_offset 42 /* Reserved byte */ -#define SMB_trans_flg_offset 43 /* flags */ -#define SMB_trans_tmo_offset 45 /* Timeout, long */ -#define SMB_trans_rs2_offset 49 /* Next reserved */ -#define SMB_trans_pbc_offset 51 /* Param Byte count in buf */ -#define SMB_trans_pbo_offset 53 /* Offset to param bytes */ -#define SMB_trans_dbc_offset 55 /* Data byte count in buf */ -#define SMB_trans_dbo_offset 57 /* Data byte offset */ -#define SMB_trans_suc_offset 59 /* Setup count - byte */ -#define SMB_trans_rs3_offset 60 /* Reserved to pad ... */ -#define SMB_trans_len 61 /* Up to setup, still need bcc */ - -#define SMB_transr_tpc_offset 33 /* Total param bytes returned */ -#define SMB_transr_tdc_offset 35 -#define SMB_transr_rs1_offset 37 -#define SMB_transr_pbc_offset 39 -#define SMB_transr_pbo_offset 41 -#define SMB_transr_pdi_offset 43 /* parameter displacement */ -#define SMB_transr_dbc_offset 45 -#define SMB_transr_dbo_offset 47 -#define SMB_transr_ddi_offset 49 -#define SMB_transr_suc_offset 51 -#define SMB_transr_rs2_offset 52 -#define SMB_transr_len 53 - -/* Bit masks for SMB Capabilities ... */ - -#define SMB_cap_raw_mode 0x0001 -#define SMB_cap_mpx_mode 0x0002 -#define SMB_cap_unicode 0x0004 -#define SMB_cap_large_files 0x0008 -#define SMB_cap_nt_smbs 0x0010 -#define SMB_rpc_remote_apis 0x0020 -#define SMB_cap_nt_status 0x0040 -#define SMB_cap_level_II_oplocks 0x0080 -#define SMB_cap_lock_and_read 0x0100 -#define SMB_cap_nt_find 0x0200 - -/* SMB LANMAN api call defines */ - -#define SMB_LMapi_SetUserInfo 0x0072 -#define SMB_LMapi_UserPasswordSet 0x0073 - -/* Structures and defines we use in the client interface */ - -/* The protocols we might support. Perhaps a bit ambitious, as only RFCNB */ -/* has any support so far 0(sometimes called NBT) */ - -typedef enum { - SMB_RFCNB, SMB_IPXNB, SMB_NETBEUI, SMB_X25 -} SMB_Transport_Types; - -typedef enum { - SMB_Con_FShare, SMB_Con_PShare, SMB_Con_IPC -} SMB_Con_Types; - -typedef enum { - SMB_State_NoState, SMB_State_Stopped, SMB_State_Started -} SMB_State_Types; - -/* The following two arrays need to be in step! */ -/* We must make it possible for callers to specify these ... */ - -#if 0 -extern char const *SMB_Prots[]; - -/* - * static char *SMB_Prots[] = {"PC NETWORK PROGRAM 1.0", - * "MICROSOFT NETWORKS 1.03", - * "MICROSOFT NETWORKS 3.0", - * "DOS LANMAN1.0", - * "LANMAN1.0", - * "DOS LM1.2X002", - * "LM1.2X002", - * "DOS LANMAN2.1", - * "LANMAN2.1", - * "Samba", - * "NT LM 0.12", - * "NT LANMAN 1.0", - * NULL}; - */ -extern int SMB_Types[]; - -/* - * static int SMB_Types[] = {SMB_P_Core, - * SMB_P_CorePlus, - * SMB_P_DOSLanMan1, - * SMB_P_DOSLanMan1, - * SMB_P_LanMan1, - * SMB_P_DOSLanMan2, - * SMB_P_LanMan2, - * SMB_P_LanMan2_1, - * SMB_P_LanMan2_1, - * SMB_P_NT1, - * SMB_P_NT1, - * SMB_P_NT1, - * -1}; - */ -#endif - -typedef struct SMB_Status { - - union { - struct { - unsigned char ErrorClass; - unsigned char Reserved; - unsigned short Error; - } DosError; - unsigned int NtStatus; - } status; -} SMB_Status; - -#if 0 -// #ifndef SMBLIB_DEFAULT_DOMAIN -#define SMBLIB_DEFAULT_DOMAIN "STAFF" -#endif -#define SMBLIB_DEFAULT_OSNAME "UNIX of some type" -#define SMBLIB_DEFAULT_LMTYPE "SMBlib LM2.1 minus a bit" -#define SMBLIB_MAX_XMIT 65535 - -#define SMB_Sec_Mode_Share 0 -#define SMB_Sec_Mode_User 1 - -typedef struct SMB_File_Def SMB_File; - -struct SMB_File_Def { - SMB_Tree_Handle tree; - char filename[256]; /* We should malloc this ... */ - unsigned short /*UWORD*/ fid; - unsigned int lastmod; - unsigned int size; /* Could blow up if 64bit files supported */ - unsigned short /*UWORD*/ access; - off_t fileloc; -}; - -/* global Variables for the library */ -extern SMB_State_Types SMBlib_State; -extern int SMBlib_errno; -extern int SMBlib_SMB_Error; /* last Error */ - -extern void SMB_Get_My_Name(char *name, int len); -extern int SMB_Discon(SMB_Handle_Type Con_Handle, int KeepHandle); - -extern int SMB_Get_Error_Msg(int msg, char *msgbuf, int len); - -extern int SMB_Get_Last_Error(void); - -#endif /* __SMBLIB_PRIV_H__ */ diff --git a/libntlmauth/smblib.c b/libntlmauth/smblib.c deleted file mode 100644 index 4a6da58036..0000000000 --- a/libntlmauth/smblib.c +++ /dev/null @@ -1,510 +0,0 @@ - -/* UNIX SMBlib NetBIOS implementation - * - * Version 1.0 - * SMBlib 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 "config.h" - -#include "libntlmauth/rfcnb.h" -#include "libntlmauth/smblib-priv.h" -#include "libntlmauth/smb-byteorder.h" -//#include "smbencrypt.h" - -#include -#include -#include - -int SMBlib_errno; -int SMBlib_SMB_Error; -SMB_State_Types SMBlib_State; - -/* local functions */ -int SMB_Term(void); -SMB_Handle_Type SMB_Create_Con_Handle(void); -int SMBlib_Set_Sock_NoDelay(SMB_Handle_Type Con_Handle, int yn); - - -/** Initialize the SMBlib package */ - -int -SMB_Init() -{ - SMBlib_State = SMB_State_Started; - signal(SIGPIPE, SIG_IGN); /* Ignore these ... */ - - /* If SMBLIB_Instrument is defines, turn on the instrumentation stuff */ -#ifdef SMBLIB_INSTRUMENT - SMBlib_Instrument_Init(); -#endif - return 0; -} - -int -SMB_Term() -{ -#ifdef SMBLIB_INSTRUMENT - SMBlib_Instrument_Term(); /* Clean up and print results */ -#endif - return 0; -} - -/** - * SMB_Create: Create a connection structure and return for later use - * We have other helper routines to set variables - */ -SMB_Handle_Type -SMB_Create_Con_Handle() -{ - SMBlib_errno = SMBlibE_NotImpl; - return (NULL); -} - -int -SMBlib_Set_Sock_NoDelay(SMB_Handle_Type Con_Handle, int yn) -{ - if (RFCNB_Set_Sock_NoDelay(Con_Handle->Trans_Connect, yn) < 0) { - fprintf(stderr, "Setting no-delay on TCP socket failed ...\n"); - } - return (0); -} - -/* SMB_Connect_Server: Connect to a server, but don't negotiate protocol */ -/* or anything else ... */ -SMB_Handle_Type -SMB_Connect_Server(SMB_Handle_Type Con_Handle, - char *server, char *NTdomain) -{ - SMB_Handle_Type con; - char called[80], calling[80], *address; - int i; - - /* Get a connection structure if one does not exist */ - con = Con_Handle; - - if (Con_Handle == NULL) { - if ((con = (struct SMB_Connect_Def *) malloc(sizeof(struct SMB_Connect_Def))) == NULL) { - SMBlib_errno = SMBlibE_NoSpace; - return NULL; - } - } - - /* Init some things ... */ - strcpy(con->service, ""); - strcpy(con->username, ""); - strcpy(con->password, ""); - strcpy(con->sock_options, ""); - strcpy(con->address, ""); - strcpy(con->desthost, server); - strcpy(con->PDomain, NTdomain); - strcpy(con->OSName, SMBLIB_DEFAULT_OSNAME); - strcpy(con->LMType, SMBLIB_DEFAULT_LMTYPE); - con->first_tree = con->last_tree = NULL; - - /* ugh. This is horribly broken. */ - /* SMB_Get_My_Name(con -> myname, sizeof(con -> myname)); */ - /* hacked by Kinkie */ - i = gethostname(con->myname, sizeof(con->myname)); - if (i == -1) { - strcpy(con->myname, "unknown"); - } else { - if (NULL != (address = strchr(con->myname, '.'))) { - *address = '\0'; /* truncate at first '.' */ - } - } - - con->port = 0; /* No port selected */ - - /* Get some things we need for the SMB Header */ - con->pid = getpid(); - con->mid = con->pid; /* This will do for now ... */ - con->uid = 0; /* Until we have done a logon, no uid ... */ - con->gid = getgid(); - - /* Now connect to the remote end, but first upper case the name of the - * service we are going to call, sine some servers want it in uppercase */ - - for (i = 0; i < strlen(server); i++) - called[i] = xtoupper(server[i]); - - called[strlen(server)] = 0; /* Make it a string */ - - for (i = 0; i < strlen(con->myname); i++) - calling[i] = xtoupper(con->myname[i]); - - calling[strlen(con->myname)] = 0; /* Make it a string */ - - if (strcmp(con->address, "") == 0) - address = con->desthost; - else - address = con->address; - - con->Trans_Connect = RFCNB_Call(called, - calling, - address, /* Protocol specific */ - con->port); - - /* Did we get one? */ - if (con->Trans_Connect == NULL) { - if (Con_Handle == NULL) { - Con_Handle = NULL; - free(con); - } - SMBlib_errno = -SMBlibE_CallFailed; - return NULL; - - } - return (con); -} - -/* SMB_Connect: Connect to the indicated server */ -/* If Con_Handle == NULL then create a handle and connect, otherwise */ -/* use the handle passed */ - -char const *SMB_Prots_Restrict[] = {"PC NETWORK PROGRAM 1.0", - NULL - }; - - -SMB_Handle_Type -SMB_Connect(SMB_Handle_Type Con_Handle, - SMB_Tree_Handle * tree, - char *service, - char *username, - char *password) -{ - SMB_Handle_Type con; - char *host, *address; - char temp[80], called[80], calling[80]; - int i; - - /* Get a connection structure if one does not exist */ - con = Con_Handle; - - if (Con_Handle == NULL) { - if ((con = (struct SMB_Connect_Def *) malloc(sizeof(struct SMB_Connect_Def))) == NULL) { - SMBlib_errno = SMBlibE_NoSpace; - return NULL; - } - } - - /* Init some things ... */ - strcpy(con->service, service); - strcpy(con->username, username); - strcpy(con->password, password); - strcpy(con->sock_options, ""); - strcpy(con->address, ""); - strcpy(con->PDomain, SMBLIB_DEFAULT_DOMAIN); - strcpy(con->OSName, SMBLIB_DEFAULT_OSNAME); - strcpy(con->LMType, SMBLIB_DEFAULT_LMTYPE); - con->first_tree = con->last_tree = NULL; - - SMB_Get_My_Name(con->myname, sizeof(con->myname)); - - con->port = 0; /* No port selected */ - - /* Get some things we need for the SMB Header */ - con->pid = getpid(); - con->mid = con->pid; /* This will do for now ... */ - con->uid = 0; /* Until we have done a logon, no uid */ - con->gid = getgid(); - - /* Now figure out the host portion of the service */ - strcpy(temp, service); - host = (char *) strtok(temp, "/\\"); /* Separate host name portion */ - strcpy(con->desthost, host); - - /* Now connect to the remote end, but first upper case the name of the - * service we are going to call, sine some servers want it in uppercase */ - - for (i = 0; i < strlen(host); i++) - called[i] = xtoupper(host[i]); - - called[strlen(host)] = 0; /* Make it a string */ - - for (i = 0; i < strlen(con->myname); i++) - calling[i] = xtoupper(con->myname[i]); - - calling[strlen(con->myname)] = 0; /* Make it a string */ - - if (strcmp(con->address, "") == 0) - address = con->desthost; - else - address = con->address; - - con->Trans_Connect = RFCNB_Call(called, - calling, - address, /* Protocol specific */ - con->port); - - /* Did we get one? */ - - if (con->Trans_Connect == NULL) { - if (Con_Handle == NULL) { - free(con); - Con_Handle = NULL; - } - SMBlib_errno = -SMBlibE_CallFailed; - return NULL; - } - - /* Now, negotiate the protocol */ - if (SMB_Negotiate(con, SMB_Prots_Restrict) < 0) { - - /* Hmmm what should we do here ... We have a connection, but could not - * negotiate ... */ - return NULL; - } - - /* Now connect to the service ... */ - if ((*tree = SMB_TreeConnect(con, NULL, service, password, "A:")) == NULL) { - return NULL; - } - return (con); -} - -/* Logon to the server. That is, do a session setup if we can. We do not do */ -/* Unicode yet! */ -int -SMB_Logon_Server(SMB_Handle_Type Con_Handle, char *UserName, - char *PassWord, char *UserDomain, int precrypted) -{ - struct RFCNB_Pkt *pkt; - int param_len, pkt_len, pass_len; - char *p, pword[128]; - - /* First we need a packet etc ... but we need to know what protocol has */ - /* been negotiated to figure out if we can do it and what SMB format to */ - /* use ... */ - if (Con_Handle->protocol < SMB_P_LanMan1) { - SMBlib_errno = SMBlibE_ProtLow; - return (SMBlibE_BAD); - } - if (precrypted) { - pass_len = 24; - memcpy(pword, PassWord, 24); - } else { - strcpy(pword, PassWord); - if (Con_Handle->encrypt_passwords) { - pass_len = 24; - SMBencrypt((unsigned char *) PassWord, (unsigned char *) Con_Handle->Encrypt_Key, (unsigned char *) pword); - } else - pass_len = strlen(pword); - } - - /* Now build the correct structure */ - if (Con_Handle->protocol < SMB_P_NT1) { - - param_len = strlen(UserName) + 1 + pass_len + 1 + - strlen(UserDomain) + 1 + - strlen(Con_Handle->OSName) + 1; - - pkt_len = SMB_ssetpLM_len + param_len; - - pkt = (struct RFCNB_Pkt *) RFCNB_Alloc_Pkt(pkt_len); - - if (pkt == NULL) { - - SMBlib_errno = SMBlibE_NoSpace; - fprintf(stderr, "SMB_Logon_server: Couldn't allocate packet\n"); - return (SMBlibE_BAD); /* Should handle the error */ - } - memset(SMB_Hdr(pkt), 0, SMB_ssetpLM_len); - SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ - *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX; - SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle->pid); - SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0); - SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle->mid); - SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle->uid); - *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 10; - *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF; /* No extra command */ - SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0); - - SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mbs_offset, SMBLIB_MAX_XMIT); - SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_mmc_offset, 2); - SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_vcn_offset, Con_Handle->pid); - SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_snk_offset, 0); - SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_pwl_offset, pass_len + 1); - SIVAL(SMB_Hdr(pkt), SMB_ssetpLM_res_offset, 0); - SSVAL(SMB_Hdr(pkt), SMB_ssetpLM_bcc_offset, param_len); - - /* Now copy the param strings in with the right stuff */ - - p = (char *) (SMB_Hdr(pkt) + SMB_ssetpLM_buf_offset); - - /* Copy in password, then the rest. Password has a null at end */ - - memcpy(p, pword, pass_len); - - p = p + pass_len + 1; - - strcpy(p, UserName); - p = p + strlen(UserName); - *p = 0; - - p = p + 1; - - strcpy(p, UserDomain); - p = p + strlen(UserDomain); - *p = 0; - p = p + 1; - - strcpy(p, Con_Handle->OSName); - p = p + strlen(Con_Handle->OSName); - *p = 0; - - } else { - - /* We don't admit to UNICODE support ... */ - - param_len = strlen(UserName) + 1 + pass_len + - strlen(UserDomain) + 1 + - strlen(Con_Handle->OSName) + 1 + - strlen(Con_Handle->LMType) + 1; - - pkt_len = SMB_ssetpNTLM_len + param_len; - - pkt = (struct RFCNB_Pkt *) RFCNB_Alloc_Pkt(pkt_len); - - if (pkt == NULL) { - - SMBlib_errno = SMBlibE_NoSpace; - fprintf(stderr, "SMB_Logon_server: Couldn't allocate packet\n"); - return (-1); /* Should handle the error */ - } - memset(SMB_Hdr(pkt), 0, SMB_ssetpNTLM_len); - SIVAL(SMB_Hdr(pkt), SMB_hdr_idf_offset, SMB_DEF_IDF); /* Plunk in IDF */ - *(SMB_Hdr(pkt) + SMB_hdr_com_offset) = SMBsesssetupX; - SSVAL(SMB_Hdr(pkt), SMB_hdr_pid_offset, Con_Handle->pid); - SSVAL(SMB_Hdr(pkt), SMB_hdr_tid_offset, 0); - SSVAL(SMB_Hdr(pkt), SMB_hdr_mid_offset, Con_Handle->mid); - SSVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset, Con_Handle->uid); - *(SMB_Hdr(pkt) + SMB_hdr_wct_offset) = 13; - *(SMB_Hdr(pkt) + SMB_hdr_axc_offset) = 0xFF; /* No extra command */ - SSVAL(SMB_Hdr(pkt), SMB_hdr_axo_offset, 0); - - SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mbs_offset, SMBLIB_MAX_XMIT); - SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_mmc_offset, 0); - SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_vcn_offset, 1); /* Thanks Tridge! */ - SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_snk_offset, 0); - SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cipl_offset, pass_len); - SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cspl_offset, 0); - SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_res_offset, 0); - SIVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_cap_offset, 0); - SSVAL(SMB_Hdr(pkt), SMB_ssetpNTLM_bcc_offset, param_len); - - /* Now copy the param strings in with the right stuff */ - - p = (char *) (SMB_Hdr(pkt) + SMB_ssetpNTLM_buf_offset); - - /* Copy in password, then the rest. Password has no null at end */ - - memcpy(p, pword, pass_len); - - p = p + pass_len; - - strcpy(p, UserName); - p = p + strlen(UserName); - *p = 0; - - p = p + 1; - - strcpy(p, UserDomain); - p = p + strlen(UserDomain); - *p = 0; - p = p + 1; - - strcpy(p, Con_Handle->OSName); - p = p + strlen(Con_Handle->OSName); - *p = 0; - p = p + 1; - - strcpy(p, Con_Handle->LMType); - p = p + strlen(Con_Handle->LMType); - *p = 0; - - } - - /* Now send it and get a response */ - if (RFCNB_Send(Con_Handle->Trans_Connect, pkt, pkt_len) < 0) { -#ifdef DEBUG - fprintf(stderr, "Error sending SessSetupX request\n"); -#endif - RFCNB_Free_Pkt(pkt); - SMBlib_errno = SMBlibE_SendFailed; - return (SMBlibE_BAD); - } - - /* Now get the response ... */ - if (RFCNB_Recv(Con_Handle->Trans_Connect, pkt, pkt_len) < 0) { -#ifdef DEBUG - fprintf(stderr, "Error receiving response to SessSetupAndX\n"); -#endif - RFCNB_Free_Pkt(pkt); - SMBlib_errno = SMBlibE_RecvFailed; - return (SMBlibE_BAD); - } - - /* Check out the response type ... */ - if (CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset) != SMBC_SUCCESS) { /* Process error */ -#ifdef DEBUG - fprintf(stderr, "SMB_SessSetupAndX failed with errorclass = %i, Error Code = %i\n", - CVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset), - SVAL(SMB_Hdr(pkt), SMB_hdr_err_offset)); -#endif - SMBlib_SMB_Error = IVAL(SMB_Hdr(pkt), SMB_hdr_rcls_offset); - RFCNB_Free_Pkt(pkt); - SMBlib_errno = SMBlibE_Remote; - return (SMBlibE_BAD); - } - - /** @@@ mdz: check for guest login { **/ - if (SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset) & 0x1) { - /* do we allow guest login? NO! */ - return (SMBlibE_BAD); - } - /** @@@ mdz: } **/ - -#ifdef DEBUG - fprintf(stderr, "SessSetupAndX response. Action = %i\n", - SVAL(SMB_Hdr(pkt), SMB_ssetpr_act_offset)); -#endif - - /* Now pick up the UID for future reference ... */ - Con_Handle->uid = SVAL(SMB_Hdr(pkt), SMB_hdr_uid_offset); - RFCNB_Free_Pkt(pkt); - return (0); -} - -/* Disconnect from the server, and disconnect all tree connects */ -int -SMB_Discon(SMB_Handle_Type Con_Handle, int KeepHandle) -{ - /* We just disconnect the connection for now ... */ - if (Con_Handle != NULL) - RFCNB_Hangup(Con_Handle->Trans_Connect); - - if (!KeepHandle) - free(Con_Handle); - - return (0); -} diff --git a/libntlmauth/smblmauth.c b/libntlmauth/smblmauth.c deleted file mode 100644 index 01c855b2ce..0000000000 --- a/libntlmauth/smblmauth.c +++ /dev/null @@ -1,115 +0,0 @@ -#include "config.h" -#include "libntlmauth/ntlmauth.h" -#include "libntlmauth/smblmauth.h" -#include "libntlmauth/smb.h" - -#if HAVE_SYS_TYPES_H -#include -#endif -#if HAVE_UNISTD_H -#include -#endif -#if HAVE_SYSLOG_H -#include -#endif -#if HAVE_STRING_H -#include -#endif - -/** Do a full authentication sequence against the given server with user/pass/domain. - * Password is pre-encrypted. - */ -int -smblm_authenticate_atomic(char *username, char *password, char *server, char *backup, char *domain) -{ - int pass_is_precrypted_p = 0; - char const *supportedDialects[] = { - /* "PC NETWORK PROGRAM 1.0", */ - /* "MICROSOFT NETWORKS 1.03", */ - /* "MICROSOFT NETWORKS 3.0", */ - "LANMAN1.0", - "LM1.2X002", - "Samba", - /* "NT LM 0.12", */ - /* "NT LANMAN 1.0", */ - NULL - }; - SMB_Handle_Type con; - - SMB_Init(); - con = SMB_Connect_Server(NULL, server, domain); - if (con == NULL) { /* Error ... */ - con = SMB_Connect_Server(NULL, backup, domain); - if (con == NULL) { - return SMBLM_ERR_SERVER; - } - } - if (SMB_Negotiate(con, supportedDialects) < 0) { /* An error */ - SMB_Discon(con, 0); - return SMBLM_ERR_PROTOCOL; - } - /* Test for a server in share level mode do not authenticate against it */ - if (con->Security == 0) { - SMB_Discon(con, 0); - return SMBLM_ERR_PROTOCOL; - } - if (SMB_Logon_Server(con, username, password, domain, pass_is_precrypted_p) < 0) { - SMB_Discon(con, 0); - return SMBLM_ERR_LOGON; - } - SMB_Discon(con, 0); - return SMBLM_ERR_NONE; -} - -/** Fetches a SMB LanMan challenge nonce from the given server. */ -void * -smblm_get_nonce(char *server, char *backup, char *domain, char *nonce) -{ - char const *SMB_Prots[] = { - /* "PC NETWORK PROGRAM 1.0", */ - /* "MICROSOFT NETWORKS 1.03", */ - /* "MICROSOFT NETWORKS 3.0", */ - "LANMAN1.0", - "LM1.2X002", - "Samba", - /* "NT LM 0.12", */ - /* "NT LANMAN 1.0", */ - NULL - }; - SMB_Handle_Type con; - - SMB_Init(); - con = SMB_Connect_Server(NULL, server, domain); - if (con == NULL) { /* Error ... */ - con = SMB_Connect_Server(NULL, backup, domain); - if (con == NULL) { - return (NULL); - } - } - - if (SMB_Negotiate(con, SMB_Prots) < 0) { /* An error */ - SMB_Discon(con, 0); - return (NULL); - } - - /* Test for a server in share level mode do not authenticate against it */ - if (con->Security == 0) { - SMB_Discon(con, 0); - return (NULL); - } - - memcpy(nonce, con->Encrypt_Key, 8); - return (con); -} - -/** Authenticate with given username/password */ -int -smblm_authenticate(void *handle, char *username, char *password, int flag) -{ - SMB_Handle_Type con = handle; - - if (SMB_Logon_Server(con, username, password, NULL, flag) < 0) { - return SMBLM_ERR_LOGON; - } - return SMBLM_ERR_NONE; -} diff --git a/libntlmauth/smblmauth.h b/libntlmauth/smblmauth.h deleted file mode 100644 index c3ccc86016..0000000000 --- a/libntlmauth/smblmauth.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _LIBNTLMAUTH_SMBLMAUTH_H -#define _LIBNTLMAUTH_SMBLMAUTH_H - -/* TODO: copyright. who owns this? there was none in the original code!! */ -/* Maybe Richard Sharpe or maybe not. */ - -/* SMB LM Error Codes */ -#define SMBLM_ERR_NONE 0 -#define SMBLM_ERR_SERVER 1 -#define SMBLM_ERR_PROTOCOL 2 -#define SMBLM_ERR_LOGON 3 - -/** - * Connect to a SMB LanMan server and authenticate the provided credentials. - * - * TODO: const-correctness on the parameters. - */ -extern int smblm_authenticate_atomic(char *username, - char *password, - char *server, - char *backup, - char *domain); - -/** Fetches a SMB LanMan challenge nonce from the given server. */ -void * smblm_get_nonce(char *server, - char *backup, - char *domain, - char *nonce); - -/** Authenticate with given username/password */ -int smblm_authenticate(void *handle, - char *username, - char *password, - int flag); - -/** Disconnect a handle from use */ -#define smblm_disconnect(x) SMB_Discon(X, 0) - -#endif /* _LIBNTLMAUTH_SMBLMAUTH_H */