#
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]*
Makefile \
compat/Makefile \
lib/Makefile \
- libntlmauth/Makefile \
+ lib/ntlmauth/Makefile \
+ lib/rfcnb/Makefile \
+ lib/smblib/Makefile \
scripts/Makefile \
src/Makefile \
src/base/Makefile \
<item>getpwnam_auth - basic_getpwname_auth - Authenticate with local system user accounts.
<item>squid_ldap_auth - basic_ldap_auth - Authenticate with LDAP user accounts.
<item>MSNT-multi-domain - basic_msnt_multi_domain_auth - Authenticate with any one of multiple Windows Domain Controllers.
+ <item>msnt_auth - basic_msnt_auth - Authenticate with Windows Domain Controllers selected by username.
<item>ncsa_auth - basic_ncsa_auth - Authenticate with NCSA httpd-style password file.
<item>yp_auth - basic_nis_auth - Authenticate with NIS security system.
<item>pam_auth - basic_pam_auth - Authenticate with the system PAM infrastructure.
- <item>pop3.pl - basic_pop3_auth - Authenticate with a mail server POP3/SMTP credentials
+ <item>pop3.pl - basic_pop3_auth - Authenticate with a mail server POP3/SMTP credentials.
<item>squid_radius_auth - basic_radius_auth - Authenticate with RADIUS.
<item>squid_sasl_auth - basic_sasl_auth - Authenticate with SASL.
<item>smb_auth - basic_smb_auth - Authenticate with Samba SMB.
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 \
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 \
+++ /dev/null
-/* md4.c */
-void mdfour(unsigned char *out, unsigned char *in, int n);
+++ /dev/null
-/* 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_ */
+++ /dev/null
-/* 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_ */
+++ /dev/null
-/* 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 <features.h> */
-#include "std-includes.h"
-#include "rfcnb-priv.h"
-#include "rfcnb-util.h"
-#include "rfcnb-io.h"
-#include <sys/uio.h>
-#include <sys/signal.h>
-#include <string.h>
-#include <syslog.h>
-#include <signal.h>
-
-
-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));
-}
+++ /dev/null
-/* 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);
+++ /dev/null
-/* 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
+++ /dev/null
-/* 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);
+++ /dev/null
-/* 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);
-
+++ /dev/null
-/* 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 <netinet/tcp.h>
-#include "rfcnb-priv.h"
-#include "rfcnb-util.h"
-#include "rfcnb-io.h"
-#include "rfcnb.h"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-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
+++ /dev/null
-/* 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_ */
+++ /dev/null
-/* 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 <sys/types.h>
-#include <unistd.h>
-
-#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_<protreq>_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_ */
+++ /dev/null
-/* 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 <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-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));
-
- }
- }
-
-}
+++ /dev/null
-/* 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 <stdlib.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <string.h>
-#include <signal.h>
-
-#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);
-
-}
+++ /dev/null
-/* 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 <netdb.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <signal.h>
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <strings.h>
-
-#define TRUE 1
-#define FALSE 0
-
-#endif /* _STD_DEFINES_H_ */
+++ /dev/null
-/* 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 <netdb.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <signal.h>
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#define TRUE 1
-#define FALSE 0
-
-/* Pick up define for INADDR_NONE */
-
-#ifndef INADDR_NONE
-#define INADDR_NONE -1
-#endif
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<const char * const *>(a);
+ const char * const *B = static_cast<const char * const *>(b);
return strcasecmp(*A, *B);
}
/* grow the list if necessary */
if (0 == uf->Alloc) {
uf->Alloc = 256;
- uf->names = calloc(uf->Alloc, sizeof(*uf->names));
+ uf->names = static_cast<char**>(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<char**>(realloc(uf->names, uf->Alloc * sizeof(*uf->names)));
/* zero out the newly allocated memory */
memset(&uf->names[uf->Alloc >> 1],
'\0',
#include "config.h"
+#if HAVE_SYS_TYPES_H
#include <sys/types.h>
+#endif
+#if HAVE_UNISTD_H
#include <unistd.h>
+#endif
+#if HAVE_SYSLOG_H
#include <syslog.h>
-#include "smblib-priv.h"
-#include "smblib.h"
+#endif
+#include "smblib/smblib.h"
#include "valid.h"
int
"NT LANMAN 1.0",
NULL
};
- void *con;
+ SMB_Handle_Type con;
SMB_Init();
con = SMB_Connect_Server(NULL, SERVER, DOMAIN);
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);
}
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)
#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
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
*/
#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 <string.h>
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
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
--- /dev/null
+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
#include <strings.h>
#endif
-#include "libntlmauth/ntlmauth.h"
+#include "ntlmauth/ntlmauth.h"
#include "util.h" /* for base64-related stuff */
/* ************************************************************************* */
--- /dev/null
+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.
--- /dev/null
+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
--- /dev/null
+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 ...
+
+
+
--- /dev/null
+/*
+ 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))
--- /dev/null
+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.
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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_ */
--- /dev/null
+#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 <sys/uio.h>
+#include <sys/signal.h>
+
+#if HAVE_STRING_H
+#include <string.h>
+#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));
+}
--- /dev/null
+/* 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);
--- /dev/null
+/* 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 */
+#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 <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
+ 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 <arpa/inet.h>
+#endif
+#if HAVE_STRING_H
#include <string.h>
+#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.",
"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;
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;
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;
}
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);
}
-#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];
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;
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;
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? */
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:
}
}
-#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;
/* 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 */
}
/* 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;
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;
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");
#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;
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;
}
}
+
+
+
+
+
+
+
+
+
--- /dev/null
+/* 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);
+
--- /dev/null
+/* 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 */
--- /dev/null
+#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 <netinet/tcp.h>
+#include "rfcnb/rfcnb.h"
+#include "rfcnb/rfcnb-priv.h"
+#include "rfcnb/rfcnb-io.h"
+#include "rfcnb/rfcnb-util.h"
+
+#if HAVE_STRING_H
+#include <string.h>
+#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;
+
+}
--- /dev/null
+/* 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 <netdb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#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 */
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
+
+
+
+
--- /dev/null
+/* 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 <signal.h>
+
+
+/* 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);
+
+}
+
--- /dev/null
+/* 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 <signal.h>
+
+
+/* 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);
+
+}
+
--- /dev/null
+/* 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);
+
+}
--- /dev/null
+/* 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 <sys/types.h>
+#include <unistd.h>
+
+#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 <user> -l <pwd-len-max> 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.");
+
+}
*/
#include <string.h>
-#include "md4.h"
+#include "smblib/md4.h"
/* NOTE: This code makes no attempt to be fast!
*
--- /dev/null
+/* 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 <stdio.h>
+
+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));
+
+}
+#include "config.h"
+
/*
* Unix SMB/Netbios implementation.
* Version 1.9.
#include <sys/vfs.h>
#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);
/* Routines for Windows NT MD4 Hash functions. */
static int
-_my_wcslen(int16 * str)
+_my_wcslen(int16_t * str)
{
int len = 0;
while (*str++ != 0)
*/
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;
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);
_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);
}
-/* 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 */
--- /dev/null
+/* 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)
+
+{
+
+
+}
--- /dev/null
+/* 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 */
--- /dev/null
+/* 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 <sys/types.h>
+#include <unistd.h>
+
+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_<protreq>_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_ */
-/* 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 <string.h>
+/* 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 <string.h>
+#endif
static int SMB_Types[] = {SMB_P_Core,
SMB_P_CorePlus,
-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 */
/* 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);
}
/* 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;
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 */
/* 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;
#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);
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;
/* 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;
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 {
}
- 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;
/* 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");
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");
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",
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");
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");
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",
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
/* 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);
}
/* 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.",
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));
}
}
- return 0;
+
}
--- /dev/null
+#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 <signal.h>
+#if HAVE_STRING_H
+#include <string.h>
+#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);
+
+}
/* 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 */
/* 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 ... */
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 */
--- /dev/null
+#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 <netdb.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <strings.h>
+
+#define TRUE 1
+#define FALSE 0
+
+#endif /* _SMBLIB_STD_DEFINES_H */
--- /dev/null
+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 <sys/types.h>
+#include <unistd.h>
+
+#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
+++ /dev/null
-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
+++ /dev/null
-/* 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 <sys/uio.h>
-#include <sys/signal.h>
-#include <string.h>
-
-/* 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));
-}
+++ /dev/null
-#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 <netinet/in.h>
-#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__ */
+++ /dev/null
-/* 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 <netinet/tcp.h>
-#include <string.h>
-
-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;
-
-}
+++ /dev/null
-/* 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 <arpa/inet.h>
-#include <string.h>
-
-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;
- }
-}
+++ /dev/null
-/* 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 <netdb.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <signal.h>
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <strings.h>
-#if HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#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 */
+++ /dev/null
-/*
- * 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 */
+++ /dev/null
-/*
- * 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);
-}
+++ /dev/null
-#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 */
+++ /dev/null
-/*
- * 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 <string.h>
-#include <ctype.h>
-#include <dirent.h>
-#include <string.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-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++;
- }
- }
-}
+++ /dev/null
-/*
- * 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 <string.h>
-
-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;
-}
+++ /dev/null
-/* 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 <netdb.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <signal.h>
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <strings.h>
-
-#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 */
+++ /dev/null
-#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 <unistd.h>
-
-//#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_<protreq>_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__ */
+++ /dev/null
-
-/* 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 <ctype.h>
-#include <signal.h>
-#include <string.h>
-
-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);
-}
+++ /dev/null
-#include "config.h"
-#include "libntlmauth/ntlmauth.h"
-#include "libntlmauth/smblmauth.h"
-#include "libntlmauth/smb.h"
-
-#if HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#if HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#if HAVE_SYSLOG_H
-#include <syslog.h>
-#endif
-#if HAVE_STRING_H
-#include <string.h>
-#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;
-}
+++ /dev/null
-#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 */