summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/.cvsignore12
-rw-r--r--source/arcfour.c91
-rw-r--r--source/arcfour.h39
-rw-r--r--source/cgi.c163
-rw-r--r--source/change-log1878
-rw-r--r--source/client/client.c4910
-rw-r--r--source/client/clientutil.c1040
-rw-r--r--source/client/clitar.c1771
-rw-r--r--source/codepages/codepage_def.43770
-rw-r--r--source/codepages/codepage_def.85054
-rw-r--r--source/codepages/codepage_def.85263
-rw-r--r--source/codepages/codepage_def.93224
-rw-r--r--source/include/byteorder.h200
-rw-r--r--source/include/charset.h75
-rw-r--r--source/include/clitar.h17
-rw-r--r--source/include/includes.h1290
-rw-r--r--source/include/kanji.h133
-rw-r--r--source/include/local.h167
-rw-r--r--source/include/nameserv.h427
-rw-r--r--source/include/nterr.h505
-rw-r--r--source/include/proto.h1057
-rw-r--r--source/include/smb.h1694
-rw-r--r--source/include/trans2.h251
-rw-r--r--source/include/version.h1
-rw-r--r--source/include/vt_mode.h48
-rw-r--r--source/internals.doc212
-rw-r--r--source/lib/access.c289
-rw-r--r--source/lib/charcnv.c164
-rw-r--r--source/lib/charset.c383
-rw-r--r--source/lib/fault.c82
-rw-r--r--source/lib/getsmbpass.c165
-rw-r--r--source/lib/interface.c457
-rw-r--r--source/lib/kanji.c868
-rw-r--r--source/lib/md4.c171
-rw-r--r--source/lib/replace.c325
-rw-r--r--source/lib/system.c413
-rw-r--r--source/lib/time.c495
-rw-r--r--source/lib/ufc.c782
-rw-r--r--source/lib/username.c324
-rw-r--r--source/lib/util.c4392
-rw-r--r--source/libsmb/credentials.c101
-rw-r--r--source/libsmb/namequery.c295
-rw-r--r--source/libsmb/nmblib.c731
-rw-r--r--source/libsmb/smbdes.c320
-rw-r--r--source/libsmb/smbencrypt.c111
-rw-r--r--source/locking/locking.c1535
-rw-r--r--source/locking/shmem.c844
-rw-r--r--source/lsaparse.c468
-rw-r--r--source/nameannounce.c528
-rw-r--r--source/nameannounce.doc265
-rw-r--r--source/namebrowse.c246
-rw-r--r--source/namebrowse.doc149
-rw-r--r--source/nameconf.c350
-rw-r--r--source/namedbname.c601
-rw-r--r--source/namedbname.doc182
-rw-r--r--source/namedbresp.c166
-rw-r--r--source/namedbresp.doc100
-rw-r--r--source/namedbserver.c212
-rw-r--r--source/namedbsubnet.c367
-rw-r--r--source/namedbwork.c245
-rw-r--r--source/nameelect.c855
-rw-r--r--source/nameelect.doc256
-rw-r--r--source/namelogon.c145
-rw-r--r--source/namelogon.doc36
-rw-r--r--source/namepacket.c637
-rw-r--r--source/namepacket.doc133
-rw-r--r--source/namequery.doc83
-rw-r--r--source/nameresp.c324
-rw-r--r--source/nameresp.doc178
-rw-r--r--source/nameserv.c506
-rw-r--r--source/nameserv.doc159
-rw-r--r--source/nameservreply.c667
-rw-r--r--source/nameservreply.doc213
-rw-r--r--source/nameservresp.c848
-rw-r--r--source/nameservresp.doc191
-rw-r--r--source/namework.c723
-rw-r--r--source/namework.doc363
-rw-r--r--source/nmbd/nmbd.c647
-rw-r--r--source/nmbsync.c191
-rw-r--r--source/param/loadparm.c2361
-rw-r--r--source/param/params.c566
-rw-r--r--source/passdb/smbpass.c293
-rw-r--r--source/printing/pcap.c381
-rw-r--r--source/printing/printing.c1102
-rw-r--r--source/script/addtosmbpass74
-rwxr-xr-xsource/script/installbin.sh44
-rwxr-xr-xsource/script/installcp.sh36
-rwxr-xr-xsource/script/installman.sh38
-rwxr-xr-xsource/script/installscripts.sh43
-rw-r--r--source/script/mkproto.awk82
-rwxr-xr-xsource/script/mksmbpasswd.sh6
-rwxr-xr-xsource/script/revert.sh15
-rw-r--r--source/script/smbtar140
-rwxr-xr-xsource/script/uninstallbin.sh43
-rwxr-xr-xsource/script/uninstallcp.sh33
-rwxr-xr-xsource/script/uninstallman.sh31
-rwxr-xr-xsource/script/uninstallscripts.sh37
-rwxr-xr-xsource/script/updatesmbpasswd.sh14
-rwxr-xr-xsource/smbadduser74
-rw-r--r--source/smbd/chgpasswd.c400
-rw-r--r--source/smbd/dir.c996
-rw-r--r--source/smbd/ipc.c3133
-rw-r--r--source/smbd/mangle.c673
-rw-r--r--source/smbd/message.c201
-rw-r--r--source/smbd/password.c1707
-rw-r--r--source/smbd/pipes.c1196
-rw-r--r--source/smbd/predict.c158
-rw-r--r--source/smbd/quotas.c657
-rw-r--r--source/smbd/reply.c3821
-rw-r--r--source/smbd/server.c5024
-rw-r--r--source/smbd/smbrun.c97
-rw-r--r--source/smbd/trans2.c1794
-rw-r--r--source/smbd/uid.c478
-rw-r--r--source/smbd/vt_mode.c490
-rw-r--r--source/smbparse.c551
-rw-r--r--source/utils/make_smbcodepage.c472
-rw-r--r--source/utils/nmblookup.c241
-rw-r--r--source/utils/smbpasswd.c581
-rw-r--r--source/utils/status.c526
-rw-r--r--source/utils/testparm.c112
-rw-r--r--source/utils/testprns.c72
-rw-r--r--source/web/cgi.c163
-rw-r--r--source/wsmbconf.c251
-rw-r--r--source/wsmbstatus.c87
124 files changed, 0 insertions, 69767 deletions
diff --git a/source/.cvsignore b/source/.cvsignore
deleted file mode 100644
index 9b7ea034be9..00000000000
--- a/source/.cvsignore
+++ /dev/null
@@ -1,12 +0,0 @@
-Makefile.RPM
-makefile
-makefile.sunos5
-nmbd
-nmblookup
-smbclient
-smbd
-smbpasswd
-smbrun
-smbstatus
-testparm
-testprns
diff --git a/source/arcfour.c b/source/arcfour.c
deleted file mode 100644
index a28d702a861..00000000000
--- a/source/arcfour.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
-
- a implementation of arcfour designed for use in the
- SMB password change protocol based on the description
- in 'Applied Cryptography', 2nd Edition.
-
- Copyright (C) Jeremy Allison 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.
-*/
-
-#include "arcfour.h"
-
-void set_arc4_key(unsigned char *data, int key_length, arc4_key *arckey)
-{
- unsigned int i;
- unsigned char j;
- unsigned char tc;
- unsigned char *s_box = &arckey->s_box[0];
-
- arckey->index_i = 0;
- arckey->index_j = 0;
- for(i = 0; i < 256; i++)
- s_box[i] = (unsigned char)i;
-
- j = 0;
- for( i = 0; i < 256; i++)
- {
- j += (s_box[i] + data[i%key_length]);
- tc = s_box[i];
- s_box[i] = s_box[j];
- s_box[j] = tc;
- }
-}
-
-void arc4(arc4_key *arckey, unsigned char *data_in, unsigned char *data_out,
- int length)
-{
- unsigned char tc;
- int ind;
- unsigned char i, j;
- unsigned char t;
- unsigned char *s_box = &arckey->s_box[0];
-
- for( ind = 0; ind < length; ind++)
- {
- i = ++arckey->index_i;
- j = arckey->index_j += s_box[i];
- tc = s_box[i];
- s_box[i] = s_box[j];
- s_box[j] = tc;
- t = s_box[i] + s_box[j];
- *data_out++ = *data_in++ ^ s_box[t];
- }
-}
-
-#if 0
-/* Test vector */
-unsigned char key_data[] = { 0x61, 0x8a, 0x63, 0xd2, 0xfb };
-unsigned char plaintext[] = { 0xdc, 0xee, 0x4c, 0xf9, 0x2c };
-unsigned char ciphertext[] = { 0xf1, 0x38, 0x29, 0xc9, 0xde };
-
-int main(int argc, char *argv[])
-{
- unsigned char out[5];
- arc4_key key;
-
- set_arc4_key(key_data, 5, &key);
- arc4(&key, plaintext, out, 5);
-
- if(memcmp(out, ciphertext, 5) ==0)
- printf("Test ok !\n");
- else
- printf("Test fail !\n");
- return 0;
-}
-#endif
diff --git a/source/arcfour.h b/source/arcfour.h
deleted file mode 100644
index 34a4e8f91be..00000000000
--- a/source/arcfour.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef _ARC4_H_
-#define _ARC4_H_
-
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
-
- a implementation of arcfour designed for use in the
- SMB password change protocol based on the description
- in 'Applied Cryptography', 2nd Edition.
-
- Copyright (C) Jeremy Allison 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.
-*/
-
-typedef struct {
- unsigned char s_box[256];
- unsigned char index_i;
- unsigned char index_j;
-} arc4_key;
-
-extern void set_arc4_key(unsigned char *data, int key_length, arc4_key *arckey);
-extern void arc4(arc4_key *arckey, unsigned char *data_in,
- unsigned char *data_out, int length);
-
-#endif /* _ARC4_H_ */
diff --git a/source/cgi.c b/source/cgi.c
deleted file mode 100644
index 56c293985d6..00000000000
--- a/source/cgi.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- some simple CGI helper routines
- 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.
-*/
-
-
-#include "includes.h"
-
-#define MAX_VARIABLES 512
-
-struct var {
- char *name;
- char *value;
-};
-
-static struct var variables[MAX_VARIABLES];
-static int num_variables;
-
-
-static int grab_line(int *cl, char *line, int maxsize)
-{
- int i = 0;
-
- while ((*cl)) {
- int c = fgetc(stdin);
- (*cl)--;
-
- if (c == EOF) {
- (*cl) = 0;
- break;
- }
-
- if (c == '+') {
- c = ' ';
- }
-
- if (c == '\r') continue;
-
- if (strchr("\n&", c)) break;
-
- if (c == '%' && (*cl) >= 2) {
- int c1, c2;
- c1 = fgetc(stdin);
- c2 = fgetc(stdin);
- (*cl) -= 2;
- if (c1 == EOF || c2 == EOF) break;
- if (c1 >= '0' && c1 <= '9')
- c1 = c1 - '0';
- else if (c1 >= 'A' && c1 <= 'F')
- c1 = 10 + c1 - 'A';
- else if (c1 >= 'a' && c1 <= 'f')
- c1 = 10 + c1 - 'a';
- else break;
-
- if (c2 >= '0' && c2 <= '9')
- c2 = c2 - '0';
- else if (c2 >= 'A' && c2 <= 'F')
- c2 = 10 + c2 - 'A';
- else if (c2 >= 'a' && c2 <= 'f')
- c2 = 10 + c2 - 'a';
- else break;
-
- c = (c1<<4) | c2;
- }
-
- line[i++] = c;
-
- if (i == maxsize) break;
- }
-
- /* now unescape the line */
-
-
- line[i] = 0;
- return 1;
-}
-
-
-/***************************************************************************
- load all the variables passed to the CGI program
- ***************************************************************************/
-void cgi_load_variables(void)
-{
- static pstring line;
- char *p;
- int len;
-
- if (!(p=getenv("CONTENT_LENGTH"))) return;
-
- len = atoi(p);
-
- if (len <= 0) return;
-
-
-
- while (len && grab_line(&len, line, sizeof(line)-1)) {
- p = strchr(line,'=');
- if (!p) continue;
-
- *p = 0;
-
- variables[num_variables].name = strdup(line);
- variables[num_variables].value = strdup(p+1);
-
- if (!variables[num_variables].name ||
- !variables[num_variables].value)
- continue;
-
-#if 0
- printf("%s=%s<br>\n",
- variables[num_variables].name,
- variables[num_variables].value);
-#endif
-
- num_variables++;
- if (num_variables == MAX_VARIABLES) break;
- }
-
- fclose(stdin);
-}
-
-
-/***************************************************************************
- find a variable passed via CGI
- ***************************************************************************/
-char *cgi_variable(char *name)
-{
- int i;
-
- for (i=0;i<num_variables;i++)
- if (strcmp(variables[i].name, name) == 0)
- return variables[i].value;
- return NULL;
-}
-
-
-/***************************************************************************
- return the value of a CGI boolean variable.
- ***************************************************************************/
-int cgi_boolean(char *name, int def)
-{
- char *p = cgi_variable(name);
-
- if (!p) return def;
-
- return strcmp(p, "1") == 0;
-}
diff --git a/source/change-log b/source/change-log
deleted file mode 100644
index 42a27fe6f68..00000000000
--- a/source/change-log
+++ /dev/null
@@ -1,1878 +0,0 @@
-SUPERCEDED Change Log for Samba
-^^^^^^^^^^
-
-Unless otherwise attributed, all changes were made by
-Andrew.Tridgell@anu.edu.au. All bugs to samba-bugs@samba.anu.edu.au.
-
-NOTE: THIS LOG IS IN CHRONOLOGICAL ORDER
-
-NOTE: From now on the cvs.log file will be used to give a complete log of
-changes to samba. This change-log is now obsolete.
-
-1.5.00 announced to mailing list
-
-1.5.01 1/12/93
- - configuration through makefile only
- - fixed silly bug that made the client not accept dir's from
- the server
- - tested and updated include files for ultrix, aix and solaris
- - several things fixed thanks to pierson@ketje.enet.dec.com
- who provided invaluable help and advice.
-
-1.5.02 1/12/93
- - added username option to services file so connection
- as non guest from lanmanager is possible
- - made server abort when it can't read/write on a socket
- - added logging to client
-
-1.5.03 2/12/93
- - printing now works
- - fixed a minor bug to do with hidden and system attributes
-
-1.5.04 2/12/93
- - added reduce_name() call to fill in security hole.
- - cleanup up debug stuff a little
-
-1.5.05 2/12/93
- - fixed bug in reduce_name that affects services with base paths
- that have a soft link in them.
-
-1.5.06 3/12/93
- - used the reserved server field in the search status to hold the
- directory pointer. This allows lots of directories to be open
- at once by clients without stuffing things up.
- - preserved all the client reserved bytes in the search status
- in case they actually use them. Hopefully this will fix the annoying
- empty directory dir bug. (it does)
-
-1.5.07 3/12/93
- - fixed silly bug that caused volume ids to appear twice
- - fixed a wrote-too-few bug in smb_send()
-
-1.5.08 3/12/93
- - did the SMBsearch properly. It can now handle recursive searches.
- In order to keep the required dir info I encode the dirptr and
- the current dir offset (from telldir) into 5 bytes by using a table
- on the last 7 bits of the first byte. The first bit is always on
- as this byte must by != 0
- This is all put in the "server reserved" search field.
-
-1.5.09 5/12/93
- - added a prototype nameserver. It's broken but can at least interpret
- incoming packets.
- - minor fixes to the server and client
-
-
-1.5.10 5/12/93
- - fixed silly unsigned/signed char bug that made dosshell noot see all files
- - added nmbd to Makefile
-
-1.5.11 6/12/93
- - made the volume label appear as the service name, rather than "Remote"
- - made the nmbd actually work (a little) for lanman for dos
-
-1.5.12 7/12/93
- - fixed broadcasting in the nameserver
- - the smbd now correctly sets the pid and uid
- - nmbd now seems to work enough to satisfy the MS client.
-
-
-1.5.13 7/12/93
- - fixed a silly bug that truncated filenames
- - added -B option to nameserver to specify bcast address
- - added -R option to nameserver to prevent name registering
- - fixed minor read() bug. Does this fix the "cmp" bug?
-
-1.5.14 8/12/93
- - fixed a bug in send_login() in the client. Thanks to
- tim.hudson@gslmail.mincom.oz.au for pointing this out.
- - changed name_mangle() to pad to minimum of 32 bytes with spaces
- - changed the returned buffer size in reply_connect() to not
- count the 4 byte length field. This fixes the "can execute" bug
- and the "comp" bug
- - once again re-wrote the directory pointer handling code.
- now "tree" works correctly
-
-1.5.15 9/12/93
- - fixed name mangle bug introduced in 1.5.14 which stopped
- nameserver from working
-
-1.5.16 9/12/93
- - arrgh. another silly bug in name_mangle() causes the client to die.
-
-
-1.5.17 13/12/93
- - some cosmetic cleanups to the code
- - changed make_connection not to lower case the password (thanks
- to bryan@alex.com)
- - fixed accept() bug not initialising in_addrlen (thanks to
- bogstad@cs.jhu.edu)
- - fixed cd bug in client.c (thanks to joergs@toppoint.de)
- - lots of fixes to the nameserver to read_socket and
- associated routines. It should now correctly reply to the originating
- address and use the correct broadcast.
- (thanks to troyer@saifr00.ateng.az.honeywell.com)
- - SVR4 patches from mark@scot1.ucsalf.ac.uk
- - changed the default BUFFER_SIZE to 0xFFFF
-
-1.5.18 15/12/93
- - minor fix to reply_printqueue() to zero data buffer array.
- - added print command to client.
- - fixed minor bug in cmd_put() in client where a handle could
- be closed without being previously opened.
- - minor cleanups to the client
- - minor solaris fixes from lonnie@itg.ti.com
- - SYSV, shadow password and dfree() fixes from mark@scot1.ucsalf.ac.uk
- - fixed reply_delete() to not delete read-only files
- - fixed infinite loop in reply_delete on "del ."
- Thanks to mark@scot1.ucsalf.ac.uk for pointing this out.
- - posix mode definitions and changes from mark@scot1.ucsalf.ac.uk
-
-
-1.5.19 18/12/93
- - another very minor fix to dfree().
- - minor change to SVR4 makefile entry from rossw@march.co.uk
- - changed reply_open not to open directories, this fixes the
- "copy .." bug pointed out by mark@scot1.ucsalf.ac.uk
- - changed dos_mode() so it doesn't return hidden and system info
- on directories.
- - changed get_dir_entry() not to descend into proc/self under linux
- control this with the DONT_DESCEND define in includes.h
- - changed smb_setlen() to add in the SMB id. (thanks
- to troyer@saifr00.ateng.az.honeywell.com)
- - fixed minor bug in reply_dir() so it won't return a ACCESS_DENIED
- when searching a directory that is unreadable
- - removed second stat() from get_dir_entry() (speed up)
- - made null searches close the dirptr (fixes big filesystem problem)
- - fixed clean_name for cd .. (from magnus@axiom.se)
-
-
-1.5.20 28/12/93
- - added debug statement in case of SMBcreate with volid set (leefi@microsoft.com)
- - fixed a bug in dptr_close() so it sets the next_key to a better
- value, this fixes a annoying dir bug
- - LOTS of changes from jeremy@netcom.com (Jeremy Allison). This
- makes it possible to at least connect to a NT server with the client
- and also fixes up much of the socket/process code. This also includes
- stuff for compiling on a sun386
- - got the client working with the Syntax server (a commercial
- smb-based server). This required a few minor changes so the xmit
- sizes were negotiated properly.
- - added support for OSF1, tested on a DEC3000/400 alpha.
- - fixed the ifconf support under ultrix
-
-1.5.21 31/12/93
- - minor cosmetic change to reduce_name()
- - changes for HPUX from ppk@atk.tpo.fi (Pasi Kaara)
- - minor fix to nameserver
- - revamped configuration file format. It now takes a Windows-style
- (.INI style) configuration file. See the file services for
- full details of the format. New files: loadparm.c, loadparm.h,
- params.c, params.h, testparm.c. Several changes to smb.h, local.h,
- server.c, Makefile. The services structure is no longer visible
- to the rest of the system. (Karl Auer)
- - added ability to specify a print command on a per service basis
- and globally via the configuration file. Also allows guest account
- to be specified in the configuration file. Made appropriate changes
- to server.c so that these data items are obtained from the config
- module rather than from hardcoded strings (though the hardcoded
- strings are still the source of the defaults). (Karl Auer)
- - renamed old-style configuration file to services.old (Karl Auer)
- - changed README to reflect new configuration details. (Karl Auer)
- - removed an item from the bugs wishlist (now supplied!) (Karl Auer)
- - protected smb.h against multiple compilation. (Karl Auer)
- - protected local.h against multiple compilation. (Karl Auer)
- - made config stuff do dynamic allocation
- - added "homes" capability
- - added create_mask to each service in config
-
-1.5.22 3/1/94
- - added "root dir" option for extra security
- - added -n option to client (useful for OS/2)
- - changed operation of -n to nameserver to be more useful
- - patches from Jeremy Allison (jeremy@netcom.com)
- fixing bug in set_message(), fixing up wait3() for SYSV,
- making cd check the path in the client, allowing fetching to stdin
- in client, and enhancing prompt in client to include directory.
- - made the -D become_daemon() actually detach from the tty. This
- may need tuning for different flavors of unix.
- - added "dont descend" option to each service to prevent infinite
- loops on recursive filesystems.
- - updated README to add "running as a daemon" and a simple
- smb.conf file.
- - HP/UX fixes from ppk@atk.tpo.fi
- - made lock calls only if opened with write enabled, as pointed out
- by gadams@ddrive.demon.co.uk
-
-1.5.23 4/1/94
- - minor fix to logging of data in receive_smb(). It used to
- miss the last 4 bytes of packets.
- - added the pid,uid and mid fields to the negotiation phase of
- the client.
- - made client able to print from stdin
- - added password on command line for client
- - created a sample printcap input filter "smbprint"
- - several fixes to client to work with OS/2
- - added mput, mget, prompt and lcd to client
-
-1.5.24 5/1/94
- - a resend of 1.5.23 as I managed to not include the new
- prompt, mput and mget code.
-
-1.5.25 7/1/94
- - change -B on nameserver so it can override the broadcast address
- - minor changes to printing in client so OS/2 server can handle it.
- - fixed reply_access() where OK was not being initialised
- - added "max xmit" to global parameters.
- - changed create to open with O_RDWR instead of O_WRONLY
- - added printmode command to client
- - made help return extra help on a specified command in client
- - fixed return code in chkpath
- - added "recurse" and "lowercase" options to client
- - fixed some error codes from server
- - added -I option to client
- - fix for become_daemon() for HPUX from ppk@atk.tpo.fi
- - added "hosts allow" and "hosts deny" to server
- - added keepalives to server
- - added "access" feature to testparam
- - NetBSD patches from sreiz@aie.nl
-
-1.5.26 8/1/94
- - changed semantics of hosts access code to do more sensible defaults
- when either of "hosts allow" or "hosts deny" is blank
- - added the SO_KEEPALIVE option to configurations of sockets in the
- server
- - made some of the SVAL fns into macros to keep fussy compilers from
- complaining
- - fixed several null pointer bugs in check_access(). These bugs
- made 1.5.25 unuseable for many people.
- - fixed null pointer reference of lp_dontdescend()
- - reload services file after each new connection.
-
-1.5.27 11/1/94
- - fixed opening mode for reply_open() in server
- - patches from Jeremy Allison (jeremy@netcom.com) to support the
- "core+" protocol. The patches also inclued some other features, such
- as a new read_with_timeout() call (used by SMBreadbraw), and auto
- detection of the need to create a socket.
- - changed the default KEEPALIVE value to 0, as it caused
- problems with Lanmanager.
- - added tar capability to client when getting files
- - altered unix_mode() to return x bits for directories
- - fixed bug in trim_string()
-
-1.5.28 12/1/94
- - cleaned up the debug levels a little so debug level 1 is a practical
- level for general use
- - fixed a bug in add_a_service() where a freed pointer was referenced. Thanks
- to bryan@alex.com for finding the bug.
- - fixed bug in time structure handling in server and client. Thanks to
- bryan@alex.com for pointing out the bug.
-
-
-1.5.29 15/1/94
- - fixed a silly bug in reply_open(). Thanks to
- jeremy@netcom.com for pointing this out.
- - fixed debug levels in client to be more sensible
- - added raw read to client
- - added -B option to client
- - fixed several bugs in the client, mostly to do with the tar option
- - added -E option to client
-
-1.5.30 16/1/94
- - added lots of prototypes so compilers don't complain
- - fixed minor bug in reply_rename() (thanks to ppk@atk.tpo.fi)
- - added more support for LANMAN1.0 protocol.
- - added SESSION SETUP AND X call
- - added READ AND X call
- - added TREE CONNECT AND X call
- - added support for setbuffer for HPUX (thanks to ppk@atk.tpo.fi)
-
-1.5.31 29/1/94
- - added support for user level security in smbclient eg:
- smbclient "\\SERVER\SHARE" -U USERNAME%PASSWORD
- - added error message decode as per SMB File Sharing
- protocol extensions. (thanks to merik@blackadder.dsh.oz.au)
- - added selection masks to smbclient that recurse down directory
- tree. eg: mget *.* with recurse and mask *.c on will retrieve all
- *.c files in the tree.
- - patches for FreeBSD from kuku@acds.physik.rwth-aachen.de
- - changed reduce_name() to trim ./ from front of strings and / from
- back
- - fixed a nasty bug in trim_string().
- - numerous small changes to lots of stuff that I didn't
- document while I was doing them. Sorry :-(
- - slightly updated sockspy
-
- - The following was done by Karl Auer (Karl.Auer@anu.edu.au)
- - added processing in configuration file of a [printers] section. Allows
- connection to any printer specified in /etc/printcap (or the file
- specified in the global parameter 'printcap name').
- - added full processing of 'available' flag to configuration file. A
- service can now be 'turned off' by specifying 'available = no'. Of
- dubious utility.
- - added 'printcap =' parameter to [global] section in the configuration
- file. This allows the normal /etc/printcap to be bypassed when
- checking printer names for dynamic printer connections via [printers].
- - added 'printer name =' parameters to both the [global] section and
- services sections of the configuration file. This allows the printer
- name only to be set, without having to specify an entire print
- command.
- - added some synonyms: 'writable' and 'write ok' have the opposite sense
- to 'read only'. 'public' may be used instead of 'guest ok'. 'printer'
- may be used instead of 'printer name'. 'printable' is the same as
- 'print ok'. 'root' may be used instead of 'root dir' or 'root
- directory'.
- - added lots more detail to the sample configuration file to take
- account of the above.
- - many minor fixes to internal documentation in the configuration
- sources.
- - also - Man pages!
-
-
-1.5.32 3/2/94
- - addition of smbd, smbclient and testparm man pages
- from Karl Auer
- - zombie process fix from lendecke@namu01.gwdg.de
- - added capability to nmbd to serve names available
- via gethostbyname().
-
-1.5.33 3/2/94
- - fixed up getting of netmask so it works on more unix variants
- - added -N option to nmbd
- - changed GMT diff calculation. need to check it's right for
- lots of OSes
- - fixed a bug in read_and_X() and chain_reply() chaining now
- seems to work correctly
-
-1.5.34 4/2/94
- - fixed bug in client that meant it couldn't get/put files from WfWg
- - fixed a bug in the server that caused lpr to return -1 under sunos
- - fixed a few errors in the hosts allow section of the
- smb.conf.5 manual page and added examples
-
-1.5.35 6/2/1994
- - minor bugfix in reduce_name().
- - changed width of "size" in client during a dir
- - patches for NEXT (among other things) from lendecke@namu01.gwdg.de
- - added -a switch to server, and made default action to append
- to log file
- - added deadtime options to [global] section for timing out
- dead connections to the smbd.
- - HPUX changes from Pasi.Kaara@atk.tpo.fi
- - made use of unsigned char more consistent
- - changed the way of getting the default username and host in the
- client
- - made LANMAN1 default to on in the client, off in server.
- Use -DLANMAN1=1 to make it on in both.
- - lots of casts and cleanups for various operating systems
- - changes to the Makefile from Karl to auto-instal the man pages
- - added a short history of the project to the distribution
-
-1.5.36 15/2/94
- - fixed minor bug in Debug() (thanks to Pasi.Kaara@atk.tpo.fi)
- - fixed bug in server.c so -a wasn't accepted.
- - minor fixes to the client
- - added hosts file to name server (-H option)
- - added -G option for groups to nameserver
- - cleanups and additions from Jeremy Allison, taking us
- closer to LANMAN1.0. In particular the locking code was cleaned up
- considerably.
-
-1.5.37 16/2/94
- - fixed bug introduced in 1.5.36 which disabled SMBcreate
-
-1.5.38 18/2/94
- - fixed get_broadcast() for ultrix (fix from iversen@dsfys1.fi.uib.no)
- - added automatic group registration
- - fixed bug in registration code
- - made nmbd work better with WfWg, and probably others
- - updated the man pages to include the new nmbd options.
- - minor updates to the README
- - fixed double log_out() in send_packet().
- - fixed bug in smbclient so that "dir" didn't work correctly
- with pathworks
- - possibly fixed bug in server that led to "abort retry ignore" from
- pathworks client when doing a "dir".
- - changed behaviour of smbclient login slightly, to try a
- blank password in SMBtcon if the right password fails, and a
- session setup has succeeded. Some clients seem to use a blank
- one if a session setup has succeeded.
- - ISC patches from imb@asstdc.scgt.oz.au
- - the client now tries to do name registration using a unicast.
- Let me know if this helps anyone.
- - tried to add a "contributed" line to each OS in the Makefile.
-
-1.5.39 18/2/94
- - fixed silly C code that only worked with some compilers
- - fixed another silly bug in nameserv.c that caused it to seg fault
-
-1.5.40 21/2/94
- - removed the from (IP) message so people don't worry about 0.0.0.0,
- it's redundant anyway.
- - changed the client so the crypt key isn't printed
- - changed the structure of switch_message() to use a list of functions.
- This improves the debug info.
- - made SMBopen ignore supplied attribute as per X/Open spec
- - made SMBopen fail if file doesn't exist in all cases. Let me know
- if this breaks something. It is implied in the X/Open spec. This
- fixes the pkzip bug.
- - added dptr_demote() to replace dptr_close() to try and fix
- pathworks dir bug. This has the potential disadvantage of
- leaving lots of open file descriptors.
- - changed mask_match to disallow two .s in a name
-
-1.5.41 2/3/94
- - added "dfree command" global option to smbd to support an
- external "disk free" executable (typically a script). This gets
- around the problem of getting disk free info reliably on lots
- of systems.
- - added ffirst and fclose to client
- - simple SYSVR4 patch from mark@scot1.ucsalf.ac.uk
- - added better uid/gid reporting for debugging purposes
- - several changes to the logon procedure for the client, so hopefully
- it will connect correctly to a wider range of servers.
- - server should no longer crash if it can't open the debug
- file (thanks to MGK@newton.npl.co.uk)
- - added the THANKS file.
-
-1.5.42 6/3/94
- - lots of changes from Jeremy Allison, implementing more of
- the LANMAN1.0 protocol, and fixing a few bugs.
- - fixed delete bug, so hopefully wildcards are correct now
- - pcap changes from Martin Kiff so non-aliased printers in
- /etc/printcap are recognised
- - wrote announce file ready for 1.6
- - re-wrote browse code in client (still doesn't work)
- - updates to man-pages from Karl Auer
- - made raw packet dumps mode 0600 and only if -dA is given
- - changed socket code to use utility functions in util.c
-
-1.6.00 17/3/94
- - made server always return to original directory (rather than /)
- - fixed bug in params.c that caused a seg fault if no parms in a
- section
- - minor clean ups for clean compile under solaris
- - solaris fix for running from inetd from Karl Auer
- - fixes for dfree() under solaris
- - minor changes that might help BSDI
- - changes to the Makefile, manual-pages and sample config file from
- Karl Auer
- - fixed dfree for Ultrix
-
-1.6.01 19/3/94
- - fixed setatr bug that allowed directories to be unusable
-
-1.6.02 27/3/94
- - added timestamps to connection message in log
- - added idle timeout of 10 minutes to name server
- - made HAVE_SYSCONF==0 the default in includes.h
- - made the client not register by default
- - ISC patches from imb@asstdc.scgt.oz.au
- - GetWd() cache code from Martin Kiff
- - rewrote the locking code in terms of fcntl() calls.
- - fixed "can't delete directory" bug
- - added code to close old dirptrs for duplicate searches
- - removed exchange_uids() and the access() call and replaced them.
-
-1.6.03 28/3/94
- - tried to clean up the time handling a little (local vs gmt time)
- - added debug level global to server config
- - added protocol level global to server config
- - added SMBecho command to server
- - included Karl Auers SMBGuide in the distribution.
-
-1.6.04 31/3/94
- - fixed time zeroing bug in smb_close and smb_setatr
- - re-wrote the username/password handling to be more flexible
- - added "guest only" service setting to smb.conf
- - updated man pages for new username/password handling
- - fixed parse bug in reply_tconX
- - improved error return code from tcon
- - several changes to fix printing from WfWg
-
-1.6.05 2/4/94
- - changed the name of the whole package to Samba
- - removed SMBexit call from client to stop exiting error message
- - added interpret_addr() call to replace inet_addr() so
- a hostname can be used whenever a IP is required
-
-1.6.06 8/4/94
- - added random tid choice to reduce problem of clients not
- detecting a server disconnection.
- - made client not report spurious time from CORE or COREPLUS server.
- - minor HPUX fix from gunjkoa@dep.sa.gov.au
- - turned off GETWD_CACHE until we track down a minor bug in it
-
-1.6.07: 10/4/94
- - added helpful error messages to connection failure in client.
- - fixed problem with mput in client
- - changed server to allow guest-only sesssetup messages with any
- password. Control this with GUEST_SESSION_SETUP in local.h.
- - minor change to session setup handling in make_connection()
- - added check for right number of \s in the client.
- - made the server not exit on last close if the deadtime is != 0
- - added malloc and realloc wrappers. enable them with -DWRAP_MALLOC=1
- - if smbd is started with a debug level of 10 or greater it creates
- a log file ending in the process number
-
-1.6.08: 18/4/94
- - updated the THANKS file
- - changes from marcel@fanout.et.tudelft.nl (Marcel Mol) for AMPM
- times and error report on connect().
- - made the get_myname() routine discard any part after the first '.'
- - added a wrapper for free from Martin Kiff
- - added simpleminded code to handle trapdoor uid systems (untested)
- - added Martin Kiffs "paranoid" getwd code.
- - added default MAXPATHLEN if undefined of 1024
- - made get_broadcast() continue to get netmask if it can't get
- broadcast (suggestion from Hannu Martikk)
- - replaced fchmod() calls with chmod() to satisfy some unixes
-
-
-
-1.6.09: 4/5/94
- - changed perror() calls to strerror() in server.c
- - fix for dfree on OSF1 from
- Maximilian Errath (errath@balu.kfunigraz.ac.at)
- - fixed server time reporting for protocol >= LANMAN1
- - fixed TimeDiff() for machines without TIMEZONE or TIMELOCAL
- (thanks to Vesa S{rkel{ <vesku@rankki.kcl.fi>)
- - added SYSV defs to AIX and HPUX to fix "memory" problem
- (actually a signal problem).
- - added version to client banner in log file
- - Ultrix patches from Vesa S{rkel{ <vesku@rankki.kcl.fi>
- - added ! command to client for executing shell commands
- - fixed ERRnofids bug in server
- - fixed name_equal bug
- (thanks to cjkiick@flinx.b11.ingr.com (Chris Kiick))
- - wrapped gethostbyname() with Get_Hostbyname() to prevent
- case sensitive problems on name lookups
- - limit printer tmp filename to 14 chars
- (from Paul Thomas Mahoney <ptm@xact1.xact.com>)
- - added ability to understand 64 bit file times
- (thanks to davidb@ndl.co.uk (David Boreham))
- - added Gwt_Pwnam() wrapper to cover server case-sensitivity
- problems (suggestion from J.M.OConnor@massey.ac.nz (John O'Connor))
- - changed the setuid() calls to try and work for more systems
- without breaking the ones it currently works for
- - added version number to usage()
- (suggestion from peter@prospect.anprod.csiro.au)
- - added "security=" option for share or user level security
- - allowed multiple usernames in "user=" field
- - changed display method for recursive dorectory listings
- - switched client to use long filenames where supported
- - added speed reporting to client transfers
- - several NT fixes to server from jra@vantive.com (Jeremy Allison)
- - ISC fixes from ptm@xact.demon.co.uk (Paul Mahoney)
- - fix to README from grif@cs.ucr.edu (Michael A. Griffith)
- - default netmask and broadcast from Ian A Young <iay@threel.co.uk>
- - changed default of is_locked() on fcntl() error.
- - fixed bug in read_with_timeout() that could cause a runaway
- smbd process.
- - fixed findnext bug for long filenames in client
- - changed default protocol level to LANMAN1
- - change default reported security level to SHARE.
- - changed password_ok() so that if pwdauth() fails it tries
- with standard crypt.
- - added "translate" command to the client to do CR/LF translation
- for printing, and add a form feed at the end.
- (thanks to mh2620@sarek.sbc.com (Mark A. Horstman ) )
- - added "locking=yes/no" toggle for each service
- - SCO unix patches from Heinz Mauelshagen (mauelsha@ez.da.telekom.de)
-
-1.6.10: 7/5/94
- - fixed important bug in readbraw/writebraw
- - added -A option to client
- - fixed delete bug on long filenames (untested). Thanks to
- Stefan Wessels <SWESSELS@dos-lan.cs.up.ac.za>
- - neatened up the byte swapping code
-
-1.6.11: 3/6/94
- - fixed bug in client in receive_trans2_response() that caused
- some strange behaviour with LANMAN2.
- - fixed some offset/alignment problems with lockingX (thanks to
- Jeremy Allison)
- - allow locking on O_RDONLY files. Thanks to Martin N Dey <mnd@netmgrs.co.uk>
- - fixed del bug in client thanks to paulzn@olivetti.nl (Paul van der Zwan)
- - fixed multiple user= bug thanks to MDGrosen@spectron.COM (Mark Grosen)
- - added translate ability for all files. Thanks to mh2620@sarek.sbc.com (Mark A. Horstman )
- - mask out negative lock offsets. Thanks to bgm@atml.co.uk (Barry G Merrick)
- - more attempts to get the structure alignment better for some machines
- - cleaned up the machine dependencies a little
- - ISC fixes from Paul Thomas Mahoney <ptm@xact1.xact.com>
- - enabled printing with a SMBclose and SMBwrite for NT
- thanks to jkf@frisky.Franz.COM (Sean Foderaro)
- - SGI changes from Michael Chua <lpc@solomon.technet.sg>
- - CLIX patches from cjkiick@ingr.com
- - NEXT2 and NEXT3_0 patches from Brad Greer (brad@cac.washington.edu)
- - BSDI changes from tomh@metrics.com (Tom Haapanen)
- - SCO patches from John Owens (john@micros.com)
- - fix psz bug in pcap.c (thanks to Karl Auer)
- - added widelinks option (global and per service). Suggestion from
- Karl Auer. Defaults to True.
- - made locking able to be global or local (default is give by global)
- - added check_name() to dir listings
- - added "packet size" option to globals. default to 32767. This
- "fixes" a WfWg bug (thanks to Karl Auer)
- - fixes for getattrE and setattrE and minor fix in util.c from Jeremy Allison.
- - Karl updated the man pages o be current
- - disabled writebraw and readbraw until a possible bug can be investigated further
-
-1.7.00: 14/7/94
- - added session_users list, to overcome problem of missing usernames in SMBTconX.
- - added term support to the client
- - added "default service"
- - fork for print so user is not root
- - added name mangling to 8.3 (rudimentary)
- - fixed bug in in_group()
- - changed to use gid in place of egid
- - fixed client connection to OS/2 (1.3 + lanman2.2) and long filenames
- - added patches from mcochran@wellfeet.com (Marc Cochran)
- these implement scope ids and fix some udp bugs. It means
- the -L option to nmbd now works.
- - made nmbd respond to incoming port rather than only 137
- - made wide links refuse .. components
- - fixed "dir foo." bug to stop it showing "foo.???"
- - improved name mangling (added stack)
- - added valid FNUM check to most calls
- - fixed important do_put bug in the client
- - added magic scripts to the server
- - re-enabled getwd_cache code
- - added optional agressive password checking
- - removed dptr_closepath from SMBsearch to try and stop "dos for loop"
- bug
- - DGUX patches from ross@augie.insci.com (ross andrus)
- - updated the README and THANKS file.
- - added node status request to -L option of nmbd
- - stripped trailing spaces in mask_match() (thanks to mike hench hench@cae.uwm.edu)
- - added COREPLUS style print queue reporting and "lpq command"
- in globals.
- - cleaned up date handling and fixed byte order dependancy on dates
- in SMBgetattrE.
- - cleaned up the password handling and added "password level" with
- the possability of checking all case combinations up to N upper
- case chars.
- - changed to use recvfrom only on udp ports (fixed read raw!)
- - added TCB password support for SCO (thanks to lance@fox.com)
- - updated README, THANKS and announce files.
- - fixed timezone reporting to be signed (thanks to noses@oink.rhein.de)
- - disabled max packet as it could cause problems with WfWg (no longer
- needed now readraw is "fixed")
- - changed from creat() to open() in mktemp and mknew.
- - changed umask handling
- - sped up nmbd by making it cache names
- - changed idle timeout on nmbd to 2 mins
- - Netbsd changes from noses@oink.rhein.de
- - released alpha2
- - added name timeout to nmbd
- - changed bind port retry in nmbd
- - added Limitations sections to README
- - fixed two . in is_83()
- - fixed compilations warnings in util.c (thanks to njw@cpsg.com.au)
- - made [homes] honour multiple user list
- - fixed mask match bug introduced in alpha1
- - added "mangled stack" option for stack size
- - added mangled stack promotion
- - released alpha3
- - netbsd-1.0 fix for statfs().
- - added null_string to util.c to reduce memory usage
- - changed the way directory structures are put together
- - added smbrun for system() requests
- - changed maxmux to 0 in hope of avoiding mpx commands problem
- - fixed zero response length for session keepalives
- - removed called name from session users list
- - added F_RDLCK support to try and handle locks on readonly files
- - made directory creation honour the lowercase flag in client (thanks
- to charlie@edina.demon.co.uk)
- - made checksum for mangling independant of extension if extension is
- lowercase
- - added ability to rename files with different extension, preserving
- root name
- - released alpha4
- - better command line error checking in client
- - changed all debug statements to new format
- - fixed delete error code reporting
- - released alpha5
- - added mangled name support to wildcard delete in server
- - fixed mask bug in SMBsearch
- - cleaned up prototypes
- - released alpha6
- - fixed important bug in session_setup which made WfWg freeze
- (maxmux was 0 - this bug was introduced in alpha4)
- - released alpha7
- - two printing bug fixes thanks to bgm@atml.co.uk (Barry G Merrick)
- - uid fix to smbrun (thanks to larry@witch.mitra.com)
- - man page updates from Karl Auer
- - FAQ file from Karl Auer
- - released alpha8
- - fixed read-only flag in dos_mode() for non writeable services
- - fixed error code reporting in open() and openX().
- - minor secureware fix from (thanks to lance@fox.com)
- - released alpha9
- - casting cleanups for memcpy().
- - cleaned up error code names to be more consistant
-
-1.7.01: 17/7/94
- - minor man page fix from baeder@cadence.com (Scott Baeder)
- - changed usage() error message in client
- - made nmbd not exit if can't register own name
- - made nmbd only register if running as a daemon
- - fixed stdout problem in smbrun by closing stdin/stdout/stderr
- - minor fix to lmhosts parsing
-
-
-1.7.02: 20/7/94
- - made nmbd not call get_broadcast if both -B and -N are used (thanks
- to Chris Woodrow <Chris.Woodrow@actrix.gen.nz>)
- - disabled GETWD_CACHE again
- - fixed INCLUDES list in Makefile to add version.h (thanks to
- jimw@PE-Nelson.COM (Jim Watt))
- - made checkname do a become user if it hasn't already done so.
- - added consistancy check to become_user().
- - removed mask extension expansion from SMBsearch
- - small change to chkpth
- - fix to snum select for lpq status (thanks to Rafi Sadowsky
- rafi@tavor.openu.ac.il)
- - changed daemon to is_daemon for NetBSD (thanks to noses@oink.rhein.de)
- - removed STAFS3 stuff for NETBSD_1_0
-
-
-1.7.03: 29/7/94
- - updated docs for new distribution structure
- - made getatr return 0 size for directories (thanks to Bernd Esser
- esser@pib1.physik.uni-bonn.de)
- - added valid dos filename checks from Stefan Wessels
- (swessels@cs.up.ac.za)
- - added trimming of . in hostnames to -S mode of nmbd
- - removed become_user() and OPEN_CNUM calls. Now make them
- in switch_message instead which simplifies a lot of code.
- - added GETFNUM macro to make chain_fnum more consistant and
- reliable.
- - added flags to protocol structures to simplify CAN_WRITE and AS_USER
- checking
- - added getwd cache boolean option to globals
- - added fclose() to lpq status routine thanks to
- dgb900@durras.anu.edu.au (David Baldwin)
- - added "only user" option, to limit connection usernames to those
- in the user= line
- - changed to badpath from badfile in chkpath despite specs (following
- what WfWg does). This fixes "file not found" error in copy command.
- Thanks to rwa@aber.ac.uk for pointing out the bug
- - changes for apollo from Stephen C. Steel <steve@qv3donald.LeidenUniv.nl>
- - more changes for Apollo from jmi@csd.cri.dk (John Mills)
- - released alpha release
- - added FTRUNCATE_CAN_EXTEND=0 as default to fix problem with word6.
- Possibly not needed on many OSes? Thanks to Charlie Hussey
- charlie@edina.demon.co.uk
- - started adding max connections code
- - much improved group handling contributed by
- Ian Heath (ih@ecs.soton.ac.uk)
-
-1.7.04: 29/7/94
- - fixed one line bug in SMBopenX that got error code wrong.
-
-1.7.05: 2/8/94
- - added UNIXERROR() macro to get error code from unix errno.
- - fixed lpq status for MSTCPB3
- - added @ option for user= line to lookup groups in group file
- - added become_user optimisation and process timeout (thanks to
- Jeanette Pauline Middelink (middelin@calvin.iaf.nl)
- - added malloc optimisation in readbraw
- - released alpha
- - patches for OSF1 enhanced security from Udo Linauer <ul@eacpc4.tuwien.ac.at>
- - made level 2 a more useful debug level (less guff)
- - added "max connections" and "lock dir" options to allow
- limiting of the number of connections to a service at one time.
- - released alpha2
- - updated man pages
- - released alpha3
- - added read prediction code for better read performance
- - released alpha4
- - minor tuning to receive_smb()
- - changed the order of mangled stack checking
- - bug fix in read_predict().
- - released alpha5
- - minor search optimisation
- - fixed keep alive bug in writebraw and in readbraw in the client
- - released alpha6
- - disabled writeraw by default pending a bug fix
- - added profiling code (off by default)
- - minor delete tuning
-
-
-1.7.06: 4/8/94
- - OSF1 crypt fix thanks to Udo Linauer <ul@eacpc4.tuwien.ac.at>
- - ifdef'd EDQUOT in case you don't have it (thanks to Paul Blackman <ictinus@Lake.canberra.edu.au>)
- - tidied up UNIXERROR stuff to work on more systems.
- - made Makefile more sophisticated and added "make revert"
-
-1.7.07: 4/8/94
- - fixed one line fatal bug in receive_smb. Thanks to bruce@pixar.com
-
-1.7.08: 2/9/94
- - initgroups call for SCO from lance@fox.com
- - code cleanups from cap@isac.hces.com (Simon Casady)
- - use full pathname in print command construction
- - ISC includes fix from Martin Tomes <mt00@ecl.etherm.co.uk>
- - added GID_TYPE define to cope with ultrix. Thanks to
- brad@cac.washington.edu
- - added umask call to main in server
- - fixed several minor problems with the max connections
- code. Thanks to lehmann@klizix.mpi-stuttgart.mpg.de (Arno Lehmann).
- - fixed filetime in writeclose. Thanks to Andreas Bahrdt
- <100321.2431@compuserve.com>
- - df fix for large disks from Andreas Bahrdt
- - getpwanam support from horn@mickey.jsc.nasa.gov
- - clean name change from Bernd Esser
- <be@syli30.physik.uni-bonn.de>
- - released alpha1
- - more locking changes to fix Excel problem
- - released alpha3
- - another minor locking change
- - smarter masking in the locking code. Excel now apparently works.
- - minor FAQ updates
- - changed max connections refusal error to access denied.
- - added queue command to client to show the print queue
- - changed some print queue reporting stuff
-
-1.8.0: 14/10/94
- - added international chars to valid_dos_char(). Thanks
- to Daniel.Grandjean@dgr.epfl.ch
- - volume label fix
- - released alpha1
- - important off by 4 fix in the server
- - readbraw size adaption in the client
- - released alpha2
- - wait3 cast for NeXt fixed. Thanks to dbrandon@politics.tamu.edu.
- - man page fix for max xmit. Thanks to mmoore@wexford (Mike Moore)
- - is_8_3() fixes from Jochen Roderburg <Roderburg@rrz.Uni-Koeln.DE>
- - list_match() fix from jkf@soton.ac.uk
- - statfs3 fix for BSDI from dan@supra.com
- - changed file open/close/read in server in preparation for mmap()
- based IO.
- - added mmap() support for reading files in the server. Optional
- at compile time. Thanks to suggestion from Roger Binns <rogerb@x.co.uk>
- - mmap bug fixes
- - added __SAMBA__ name in nmbd
- - major changes for support of lanman2 and long filenames from
- Jeremy Allison (jeremy@netcom.com)
- - lseek optimisation. Thanks to Linus Torvalds.
- - released alpha4
- - date patches for lanman2 from Jeremy Allison
- - added protocol aliases to handle WfWg (untested)
- - allow for zero params or data in reply_trans2
- - small lanman2 patches from jeremy
- - more prototype additions for clean compilation
- - postscript patches from tim@fsg.com
- - more lanman2 patches from Jeremy
- - added null ioctl support
- - kanji patches from fujita@ainix.isac.co.jp
- - released alpha6
- - disallowed null password access (thanks to Birger Kraegelin krg@iitb.fhg.de)
- - Makefile fix for ultrix from andrew@d2bsys.demon.co.uk (Andrew Stirling)
- - added per-service mangled names
- - totally re-vamped loadparm.c
- - added "mangling char" parameter
- - released alpha7
- - added "default case = lower|upper" service option
- - change mangling char to a service parameter
- - ultrix enhanced security patch from steven@gopher.dosli.govt.nz
- - more changes to loadparm.c
- - printer name always set in [printers]
- - string_free() fix thanks to jef_iwaniw@pts.mot.com
- - changed group handling to be faster and work for large numbers
- of groups
- - added dynamic gid_t type determination
- - released alpha8
- - fixed become_user() problem for services with invalid
- directories
- - added "invalid users" list on per service basis
- - fixed pointer problems in alpha8 (thanks to murnaghant@a1uproar.yuppy.rdgmts.MTS.dec.com)
- - fixed some date setting problems
- - trans2 fixes from jeremy to stop infinite directory listings of
- long filenames
- - "standard input" lpq patch from root@tlspu.demon.co.uk (Adrian Hungate)
- - changed password checking to check session list and validated ids
- before user list
- - split off password functions into password.c
- - added hosts equiv and rhosts code (thanks to Tim Murnaghan <murnaghant@a1uproar.yuppy.hhl.MTS.dec.com>)
- - released alpha11
- - added "newer" command to the client
- - attempt at aix trapdoor uid workaround
- - released alpha12
- - minor trans2 bugfix
- - added ufc crypt (fast crypt) support. Thanks to suggestion from
- forrest d whitcher <fw@world.std.com>
- - socket() fix for getting bcast and netmask thanks to
- Brian.Onn@Canada.Sun.COM
- - added beginnings of IPC and named pipe support in the server
- - changed file structure a bit, creating reply.c
- - finished print queue support for lanman1
- - changed default protocol to LANMAN2
- - released alpha13
- - logged IPC connects at a higher debug level
- - added netgroup support to hosts equiv search
- - disallowed root access though hosts.equiv (thanks to Colin.Dean@Smallworld.co.uk)
- - kanji and password handling fixes from fujita@ainix.isac.co.jp
- - several bug fixes for lanman and other things from
- esser@pib1.physik.uni-bonn.de (Bernd Esser)
- - updated man pages, README and announce files.
- - released 1.8.00alpha1
- - reply_close() time change fix from Andreas Bahrdt <100321.2431@compuserve.com>
- - added valid users list to compliment invalid users list.
- - aix fixes from tomc@osi.curtin.edu.au (Tom Crawley)
- - changed testparm output format
- - support for getting time from the server (nearly untested)
- - fixed device type error for wild device ????
- - fixed groups problem when in 0 groups
- - more IPC fixups
- - added support for "net view \\server" command to list
- available services (like browsing)
- - released 1.8.00alpha2
- - changed port choice for nmbd -L
- - added -L option to client to view share list on a host
- - bug fixes for NetShareEnum code
- - added "server string" option
- - changed default print file name to include remote machine name.
- - added hooks for browsing in nmbd
- - added browsing to nmbd
- - freebsd fixed from Steve Sims SimsS@Infi.Net
- - got rid of tell()
- - added subnet browsing with the S option in lmhosts
- - made smbd prime nmbd with a 1 byte dgram
- - added REUSADDR to open_socket_in() thanks to peter@ifm.liu.se
-
-
-1.8.01: 18/10/94
-
- - auto add group "LANGROUP" if no group specified in nmbd
- - made nmbd more responsive at startup
- - lots of cleanups and consistancy checks
- - added -C option to nmbd to set "machine comment".
- - fixed postscript option
- - force print_file in print_open()
- - restructured the browsing a little
- - casesignames fix for lanman-dos
- - auto-load home directory from session setup
- - changed to StrnCpy() for safety
- - fixed "out of file descriptors" bug in the client (a WfWg bug?)
-
-
-1.8.02: 22/10/94
- - fixed uppercase username problem
- - added "hide dot files" option
- - changed auto debug log in nmbd
- - added LMHOSTS to Makefile
- - added M flag in lmhosts to specify own netbios name
- - added "load printers" option to auto-load all printers
- - substitution of %p in lpq command
- - substitution of %h and %v in server string and -C option of
- nmbd
- - string substitions substitute all occurances of a pattern
- - added casesignames global option
- - fix for man pages thanks to David Gardiner <dgardine@cssip.edu.au>
- - changed debug options a bit
- - added default for lpq command and lpr command
- - changed default shell path to /bin/sh
- - forced lpq under api to run as root - should speed things up
- - added "group" option to force group of a connection
- - added "read list" and "write list" options
- - added max mux option - seems to fix NT browsing?
- - added "mangled map" option thanks to
- Martin.Tomes@uk.co.eurotherm.controls
- - separated mangling functions into mangle.c
- - allowed all dos chars in mangled names
- - apollo changes from Helmut Buchsbaum <buc@eze22.siemens.co.at>
- - password changing code from Bob Nance <Bob.Nance@niehs.nih.gov>
- it doesn't quite work yet, but it's a start (disabled by default)
-
-
-1.8.03: 25/10/94
- - made auto loaded services browsable as per default service
- so you can hide homes but keep home directories.
- - changed check_name() to handle "direct to network" printing
- - auto 3 minute deadtime if all connections are closed. This
- prevents restart when polling the print queue.
- - fix for newer command in client from Rich-Hoesly@uai.com
- - changed connection recording method
- - added the program smbstatus
- - changed timeout mechanism
- - "null passwords" option from Pim Zandbergen <pim@cti-software.nl>
- - made new files with casesignames=False set their case to the default
- case.
- - fixed problem of uppercasing first letter of printers in printcap
- - debug level fixes in trans2 from jimw@PE-Nelson.COM (Jim Watt)
- - made null printer default to lp
-
-1.8.04: 27/10/94
- - added OS2.txt from riiber@oslonett.no
- - another "auto services" fix. A silly strtok() bug :-(
- - fixed the status locking and max connections (broken in 1.8.03)
- - released alpha1
- - added gets_slash so lines can be continued in smb.conf and
- lmhosts
- - browse list bugfix
- - default to "load printers=yes"
- - rewrote pcap.c
- - intergraph bugfix from tarjeij@ulrik.uio.no
- - changed properties flags in nmbd (to fix NT print browsing)
- - allowed very long lines in printcap parsing.
-
-1.8.05: 28/10/94
- - lanman2 fix from Jeremy
-
-1.9.00: 22/1/95
- - only add home if not already there.
- - added ulogoffX support
- - PTR_DIFF() cleanups
- - fixed a bug that caused STATUS..LCK to grow very large
- - changed mangling to handle names ending in . a little better
- - added "strip dot" option
- - SGI and setgroups() fix from bill@sg25.npt.nuwc.navy.mil
- - fixed password preservation in password_ok() (again?)
- - unink fix from emer@vssad.enet.dec.com (Joel S. Emer)
- - changed username part of spool filename to max 10 chars (from 6)
- - magic script fix from beverly@datacube.com (Beverly Brown)
- - reply_special() fix from Peter Brouwer <pb@apd.dec.com>
- - stopped nmbd from listening on 138. It didn't seem to help much.
- - clix fixes from ttj@sknsws61.sjo.statkart.no
- - fixed select behaviour under Linux
- - man page fix from Robin Cutshaw <robin@intercore.com>
- - ISC block size fix from ralf@rbsoft.sdata.de (Ralf Beck)
- - ISC fixes from Martin.Tomes@controls.eurotherm.co.uk
- - attrib bit fix in smbclient (pointed out by Rich-Hoesly@uai.com)
- - japanese extensions from fujita@ainix.isac.co.jp (Takashi
- Fujita) and ouki@gssm.otuska.tsukuba.ac.jp.
- - SCO patches from Stephen.Rothwell@pd.necisa.oz.au
- - changed the system commands to redirect stderr
- - changed default printername to service name for all print ops
- - added ability to delete print queue entries
- - added warning if you try to print without -P in smbclient
- - INTERACTIVE patches from cardinal@settimo.italtel.it
- - patch to handle spaces in group names from GJC@vax1.village.com
- (GEORGE J. CARRETTE)
- - lockingX fix from stefank@esi.COM.AU (Stefan Kjellberg)
- - some fairly radical changes to filename handling. We can now
- handle mixed case filenames properly
- - released alpha2
- - added sysv printing support and improved bsd support
- - changed the user that does print queues and lprm jobs
- - return code support in the client from doylen@nbslib.isc-br.com (Doyle Nickless)
- - added "strict locking" option. Defaults to no.
-
- - added -I switch to nmbd
- - fixed DEV bug thanks to Dirk.DeWachter@rug.ac.be
- - use pw_encrypt() for shadow passords in Linux (from begemot@begemot.iko.kharkov.ua (Dmitry Gorodchanin))
- - disabled read prediction by default
- - added varient handling code to ipc.c for printQ and printDel.
- - released alpha5
- - AUX patches from root@dolphin.csudh.edu
- - struct timeval fix from gkb1@york.ac.uk
- - patches to merge ISC and INTERACTIVE from pim@cti-software.nl
- - changed to "printing ="
- - fixed problem with long print queues.
- - fixed node status request in nmbd to go to non bcast
- - made default path in services /tmp if not specified
- - added %u in passwd program
- - fixed up the password changing code for Linux
- - no guest sess setup when user level security
- - changed timeouts to kill dirptrs so cdroms can be unmounted
- - added auto-reload of smb.conf if changed
- - added SIGHUP to reload the config files
- - added -M option to nmbd to search for a master browser
- - added support for continue bit in trans2findnext
- - changed to dynamic strings in some more structures
- - changed default deadtime to 30 minutes
- - cleaned up the memory swapping code a bit
- - updated the man pages somewhat
- - added %m and %u in the "path=" of services
- - released alpha6
- - simple testing and fixups for solaris, sunos, aix, ultrix and
- osf/1 (this is all I have access to).
- - fixed chdir bug
- - added hashing to cnum selection
- - released alpha7
- - fixed printing bug
- - reduced chance of "hung" smbd with dead client
- - fixed do_match() bug (recently introduced)
- - released alpha8
- - nameserver fix from W.J.M.vGeest@et.tudelft.nl (W.J.M. van Geest)
- - rewrote readbraw to try and overlap reads with writes
- - client optimisations
- - rewrote getwd cache and enabled it by default
- - added partial smb packet reads (hopefully faster writes)
- - added log file and log level options (with subs)
- - added "read size" option
- - tried setting some more socket options
- - can use subs in "config file=" and will auto-reload
- - added "include" options, with some subs
- - finally got print manager working with NT
- - auto-respond in nmbd to non-broadcast (auto WINS server, no -A
- needed)
- - released alpha10
- - auto-delet unused services when reloading
- - fixed auto-deletion
- - fixed long names in printing
- - fixed double loading of services file
- - added printer file name support
- - reformatted man pages for better www conversion
- - renamed to 1.9.00.
- - added support for RNetServerGetInfo and NetWkstaGetInfo API's
- - updated the docs a bit
- - released alpha1
- - added -M -
- - changed nmbd announce interval to 10 mins in outgoing packets
- - hopefully fixed idle timeout reconnects
- - strupper all command lines in nmbd
- - added %a substitution for "remote architecture"
- - added "Samba" protocol (same as lanman2)
- - added "security = SERVER"
- - released alpha2
- - lowercase password fix
- - fixed connect path length bug (thanks to JOHN YTSENG
- <jtseng@cory.EECS.Berkeley.EDU>)
- - added subs on "password server".
- - fixed printing filename bug from smbclient
- - disk quotas and hpux printing support from Dirk.DeWachter@rug.ac.be
- - Makefile patches from pappinm@ayr_srv2.nth.dpi.qld.gov.au
- - AFS patches from Mike Allard (mgrmja@nextwork.rose-hulman.edu)
- - fixed grp name = server name problem
- - man page updates from Charlie Brady (charlieb@budge.apana.org.au)
- - fixed file search bug by adding "finished" flag
- - added "max log size". Suggestion from Mark Hastings <mark.hastings@gain.com>
- - released alpha3
- - changed the read/write routines to handle partial read/writes
- - released alpha4
- - changed "guest account" to per-service
- - changed so "guest ok" allows access to the guest account,
- not the "user=" line
- - changed default readsize to 2048
- - try bind to 137 in nmbd if possible
- - added server lookup to -L option in smbclient (gets list of servers)
- - added -M switch to smbclient for sending winpopup messages
- - released alpha5
- - FAQ updates from Paul Blackman ictinus@lake.canberra.edu.au
-
-1.9.01: 23/1/95
- - changed comment in print Q info to service rather than server comment
- - fixed smbclient -L to NT when in user level security mode
- - hopefully finally fixed NT print manager problems
- - added informative messages during smbclient -M
- - added node status replies to nmbd
- - changed the lock offset fixup calculation to be more friendly
- to dumb lockd daemons.
- - added sigbus and sigsegv handlers to catch any silly errors and
- print a message
- - added message receipt to smbd and "message command =" option
-
-1.9.02: 25/1/95
- - added argv/argc mangling for people who start the server the
- wrong way.
- - some man page updates
- - added "revalidate" option
- - added hosts allow/deny access check to messaging access
- - added timeouts in the client
- - added check for existance of smbrun binary
- - man page updates from Colin.Dean@Smallworld.co.uk
- - freebsd patches from dfr@render.com
- - added mask sanity check in SMBsearch
- - added more useful substitutions (%S, %P, %I and %T)
- - added "exec =" option to execute commands on each connection
-
-1.9.03: 13/3/95
- - added "socket options" option
- - close base fd's (0,1 and 2)
- - use dup(0) for inetd operation
- - better detection of is_daemon
- - hopefully finally fixed silly put bug that gave the wrong
- date on files.
- - fixed segv in readbraw bug
- - added improved checing for invalid (or null) print file name
- - several patches from ad@papyrus.hamburg.com (Andreas Degert)
- - fixed slow logout bug in smbclient
- - fixed automounter problems
- - added subs on lock dir
- - BSDI patch from John.Terpstra@Aquasoft.com.au
- - added separate nmb and smb logfile entries in the Makefile
- - fixed return code error in open calls
- - added simple status display of printer in lpq parsing
- - rewrote the directory handling to avoid seekdir (added dir.c)
- - added uid=65535 check (thanks to grant@gear.torque.net)
- - enhanced transfer_file() to add header (used in readbraw)
- - reply_special bugfix from ferret@pc8871.seqeb.gov.au
- - added HAVE_PATHCONF
- - RiscIX patches from Jim Barry <jim@ilp.com> and
- Charles Gay-Jones <charlie@ilp.com>
- - CLIX patches from ttj@sknsws61.sjo.statkart.no
- - fixed aix lpq parser from kvintus@acd.com
- - added substitutions to "include="
- - M88K_S3 patches from tonyb@plaza.ds.adp.com (Tony D. Birnseth)
- - fixed mangled stack problem
- - added code to handle broken readdir() setups on solaris
- - initgroups() fix from jarit@to.icl.fi
- - dgux dfree fix from listwork@cloud9.net
- - dnix support from Peter Olsson <pol@leissner.se>
- - getgrgid() patch from tpg@bailey.com (Tom Gall)
- - Makefile patch from obrien@Sea.Legent.com (David O'Brien)
- - password changing fixes from Dirk.DeWachter@rug.ac.be
- - minor man page updates
- - tried to enhance the read prediction code a little bit
-
-1.9.04: 16/3/95
- - a bit better handling of global include lists
- - fixed GSTRING bug in loadparm.c (affected "socket options =")
- - fixed broken lpq parsing code (recent bug).
- Thanks to Dirk.DeWachter@rug.ac.be
-
-1.9.05: 20/3/95
- - improved mget in client to take multiple arguments and default
- to *.*
- - socket option fixes for both nmbd and smbd
- - changed the byteorder handling scheme to be more portable (and
- faster)
- - lint cleanups from kast@kcs.planet.net (Robert Kast)
- - added crude segv, sigbus and sighup recovery to nmbd
- - rewrote lanman2_match to be closer to NT and WfWg behaviour
- - Cray support from velo@sesun3.epfl.ch (Martin Ouwehand)
- - "admin users" patch from Tim Leamy <tcleamy@ucdavis.edu>
- - released alpha1
- - added samba.7 man page
- - no chdir when doing non AS_USER protocols
- - become_guest() returns true in trapdoor uid system
- - added more sophisticated segv/sigbus reporting (Linux only)
- - released alpha2
- - minor code cleanups (output of -Wall)
- - smbprint fix from James Dryfoos <dryfoos@ll.mit.edu>
- - improved testparm a little
- - updated INSTALL.txt a little
-
-
-1.9.06: 21/3/95
- - added %S substitution to users, valid users and invalid
- users. This is useful for [homes].
- - split off printing routines into printing.c and more dir
- commands into dir.c
- - postexec patch from jpm@gin.Mens.DE (Jan-Piet Mens)
- - smbstatus updates from jpm@gin.Mens.DE (Jan-Piet Mens)
- - reload sighup after use
- - fixed name ptr offset bug
- - added %f in print commands
- - fixed byte ordering in nmbd which caused browsing to fail in
- 1.9.05
-
-1.9.07: 22/3/95
- - important directory listing fix
- - allowed path= in [homes] section
- - printer status patches from Dirk.DeWachter@rug.ac.be
-
-1.9.08: 24/3/95
- - fixed . and .. in root dir for lanman2
- - better default comment in [homes]
- - added time stamping to directory entries
- - check directory access at connection time
- - rlimit code from loebach@homer.atria.com (Thomas M. Loebach)
- - fixed home dir default comment
- - totally rewrote dptr handling to overcome a persistant bug
- - added [globals] as well as [global]
-
-1.9.09: 30/3/95
- - fixed static string bug in nmbd
- - better null password handling
- - split CFLAGS in Makefile
- - fixed typo in smbclient messaging
- - made home dir not inherit path from [global]
- - standard input printing patch from xiao@ic.ac.uk
- - added O_CREAT to all print opens (bug in Win95)
- - use /proc for process_exists under Linux and solaris
- - fixed another segv problem in readbraw
- - fixed volume label problem
- - lots of changes to try and support the NT1 protocol
- - released alpha1
- - fixed session setup bug with NT in NT1 protocol
- - released alpha2
- - fixed "get" bug in smbclient that affected NT3.5
- - added SO_KEEPALIVE as a default socket option in smbd
- - changed some error codes to match those that NT 3.5 produces
- - updated trans2 with some new calls for Win95 and WinNT (better
- long file support)
- - released alpha3
- - fixed "nmbd -D -b" timeouts
- - added IS_LONG_NAME flag to getattr in NT1
- - added the NT qfileinfo trans2 commands
- - merged qpathinfo with qfileinfo
- - changed idling technique to try and be more friendly to
- clients
- - merged setfileinfo with setpathinfo and updated them with the NT fns
- - improved read prediction a lot
- - added read prediction to readbraw
- - improved fault reporting (last packet dump)
-
-1.9.10: 30/3/95
- - fixed read prediction+readbraw bug for read/write files
-
-1.9.11: 9/4/95
- - fixed trans2 qpathinfo bug
- - fixed bug with % in service name when doing print queue requests
- - default readsize now 16K
- - minor read prediction changes
- - fixed status initialisation in print queue reporting
- - fixed const compile problem for hpux
- - minor SMBread fix from Volker Lendecke <lendecke@namu01.gwdg.de>
- - removed space after -P in print commands (for fussy systems)
- - disabled level2 of setfilepathinfo
- - changed to a single read dir model, saving all dir names in
- the Dir structure
- - disabled NT protocols in the client due to reported problems
- - fixed QUERY_FS_VOLUME_INFO which caused Win95 to hang on drive
- properties
- - minor lseek bug fix
- - fixed up keepalives
- - new timezone handling code (hopefully better!)
- from steve@qv3pluto.LeidenUniv.nl
- - BSDI interface patch from jrb@csi.compuserve.com
- - gettimeofday changes from Roger Binns <rogerb@x.co.uk>
- - added smbrun option
- - added "root preexec" and "root postexec" options
-
-1.9.12: 12/4/95
- - hopefully fixed some recently introduced NT problems
- - fixed a unlink error code problem
- - minor testparm fix
- - fixed silly error messages about comments in config files
- - added "valid chars" option for other languages
-
-1.9.13: 28/4/95
- - patches from David O'Brien (obrien@Sea.Legent.com) improving the
- netgroup suport, and adding the "map archive" option, as well as
- other minor cleanups.
- - tried to add info level 3 and 4 support for OS/2
- - default deadtime set to 0 as in docs
- - cleaned up the trans2 code a little
- - cleaned up the Makefile a little
- - added charset.c and charset.h
- - expanded "valid chars" option to handle case mapping
- - lots of changes to try and get timezones right
- - released alpha1
- - win95 fixups
- - released alpha2
- - added %H substitution (gives home directory)
- - nameserv.c cleanups and minor bug fixes
- - redid the browse hook logic
- - fixed daylight saving time offset for logfile messages
- - added name cacheing to nmbd
- - added send counts to node status in nmbd
- - added STRICT_TIMEZONES compile time option (very computationally
- expensive)
- - removed the partial read code
- - cleaned up the permission checking a lot
- - added share modes (DENY_READ, DENY_WRITE, DENY_ALL, DENY_NONE,
- DENY_FCB and DENY_DOS)
- - added "share modes" option
- - cleaned up the file open calls
- - released alpha4
- - fixed important one line bug in open_file()
- - trans2 client fix from lendecke@namu01.gwdg.de
- - netgroup patche from David O'Brien (obrien@Sea.Legent.com)
- - case sensitive fix from lenneis@statrix2.wu-wien.ac.at (Joerg Lenneis)
- - got long filenames working from Win95 dos prompt
- - added "workgroup=" option
- - added "username map" option including multiple maps, group maps etc
- - fixed password server for NT1 protocol and made it more robust
- - changed unix_mode() to add IWUSR to read-only directories. This
- is much closer to what clients expect.
- - added preservation of unused permission bits when a chmod() is
- called from a client.
- - made static those fns that could be
- - fixed typo in access.c (thanks to Andrew J Cole
- <A.J.Cole@cbl.leeds.ac.uk>)
- - added %d substitution for process id
- (thanks to lenneis@statrix2.wu-wien.ac.at (Joerg Lenneis))
- - changed share error code to ERRbadshare
- - added locked files list to smbstatus if share modes is enabled
- - changed DENY_DOS to allow read by other tasks
- - added shared_pending checks to server
- - preserverd all possible permission bits during a chmod, and
- fixed a trans2 chmod bug
- - open /dev/null to use up first 3 fds, in an attempt to stop rogue
- library routines from causing havoc
- - fixed NT username problem when in server security
- - added "force user" and "force group" options
- - cleaned up some of the IPC calls a bit
- - added writeraw to the client and cleaned up write raw in the server
- - osf1 big-crypt bugfix from Udo Linauer <ul@eacpc4.tuwien.ac.at>
- - hopefully better disk-full checking
- - next uid bugfix from patrick@graphics.cornell.edu
- - changed share modes so lock directory doesn't need to be world
- writeable
- - enabled write-raw by default
- - added server_info() in client
- - added level checks in some ipc calls
- - added defines for the important timeouts in local.h
- - added print queue deletion to smbclient (untested)
- - removed the sysconf() calls
- - optimised writebraw a bit
- - fixed some file deletion problems
- - added total_data check for extended attribs in trans2 (for OS/2)
- - fixed broadcast reply bug in nmbd
- - added careful core dumping code
- - added faster password level searches (suggestion
- by lydick@cvpsun104.csc.ti.com (Dan Lydick))
-
-
-1.9.14: 22/9/95
- - fixed up level 3 and 4 trans2 requests for OS/2
- - minor optimisations in a few places
- - cleaned up the closing of low fds a bit
- - added SO_REUSEADDR to socket as a daemon
- - override aDIR bit for directories in dos_chmod()
- - SGI5 fixes from ymd@biosym.com (Yuri Diomin)
- - bsize sanity check and removed sunos force to 1k
- - force the create mode to be at least 0700
- - SCO and freebsd include changes from Peter Olsson
- <pol@leissner.se>
- - check with FQDN in access.c (thanks to Arne Ansper <arne@ioc.ee>)
- - default broadcast for dnix from Peter Olsson <pol@leissner.se>
- - solaris patches from Ronald Guilmette <rfg@segfault.us.com>
- - added EXDEV handling
- - small AFS Makefile patch from mgrlhc@nextwork.rose-hulman.edu
- - hopefully fixed the Win95 dates to work in other than my
- timezone
- - attempted alignment fixups (to speed up memcpy)
- - added some DCE/DFS support (thanks to Jim Doyle <doyle@oec.com>)
- - added fix so that root doesn't have special privilages to open
- readonly files for writing (but admin users do). This fixes the MS
- office install problem.
- - fixed trans2 response bug in client
- - got dual names working for NT
- - enabled lock_and_read in NT protocol
- - added %L macro for "local machine"
- - changed dfree reporting to use "sectors per unit"
- - fixed "not enough memory" bug in MS print manger by limiting
- share name length in share enum.
- - "short preserve case" option from Rabin Ezra (rabin@acm.org)
- - added archive option to client
- - changed openX in client to be able to open hidden and system files
- - added "sync always" option
- - rewrote writebmpx and readbmpx
- - added auto string_sub_basic to all loadparm strings
- - lots of nmbd fixups (add registration, refresh etc)
- - released alpha1
- - added smbtar patches from Ricky Poulten (poultenr@logica.co.uk)
- - added a lpq cache and the "lpq cache time" option
- - released alpha 2
- - sun includes fix from Kimmo Suominen <kim@deshaw.com>
- - change nmbd -L lookup type to workstation from server
- - added min print space option
- - added user and group names to smbstatus (thanks to
- davide.migliavacca@inferentia.it)
- - fixed %f in print command bug (thanks to huver@amgraf.com)
- - added wildcard support to SMBmv
- - misc patches from David Elm (delm@hookup.net)
- - changed default of "share modes" to yes
- - changed default of "status" to yes
- - aix qconfig parsing from Jean-Pierre.Boulard@univ-rennes1.fr
- - more long_date fixups
- - added wildcards to nmbd
- - extensive changes to ipc.c and miscellaneous other changes
- from ad@papyrus.hamburg.com (Andreas Degert). Should especially
- help OS/2 users
- - added name release to nmbd
- - relesed alpha4
- - fixed "SOLARIS" to SUNOS5 in Makefile
- - several minor fixups to get it to compile on aix, osf1, ultrix,
- solaris and sunos
- - released alpha5
- - minor bug fixes and cleanups in ipc.c
- - fixed "only user" bug
- - changed lpq to report guest queue entries as sesssetup_user to
- allow for deletion by windows
- - released alpha6
- - added __SAMBA__ as type 0 in nmbd (was type 20)
- - fixed null print job bug
- - added 8 char warnings to testparm and smbclient
- - changed to 8 char limit for names in pcap.c
- - added linked list of config files to detect all date changes
- that require a reload
- - simplified pcap guessing heuristics
- - added space trimming to the name mapping
- - updated Get_Pwnam to add allow_change field for username mapping
- - fixed MemMove bug (thanks to mass@tanner.com (Massimo
- Sivilotti))
- - released alpha7
- - rewrote MemMove to be a little more efficient
- - ipc va_arg bug fix from djg@tas.com (Dave Gesswein)
- - added check for illegal chars in long filenames
- - fixed name cache init bug in nmbd
- - Convex patches from Victor Balashov <balashov@cv.jinr.dubna.su>
- - timestring() bugfix from staale@spacetec.no
- - changed %H to give path of forced user if one is set
- - added quoting to smbclient to allow spaces in filenames
- - convex and other patches from Ulrich Hahn
- <ulrich.hahn@zdv.uni-tuebingen.de>
- - released alpha8
- - fixed rename directory bug
- - nmbd wins fix from Maximilian Errath <errath@balu.kfunigraz.ac.at>
- - client and AFS changes + password.c reorganisation + "more" and
- "pwd" commands in client from Todd j. Derr (tjd@smi.med.pitt.edu)
- - fixed several nmbd bugs
- - released alpha9
- - fixed another "cd" bug in smbclient
- - password encryption from Jeremy Allison
- - added "passwd chat" option and chat interpretation code
- - added "smb passwd file" option
- - released alpha10
- - cleaned up chgpasswd.c a little
- - portability changes to the encryption handling code
- - added password encryption to smbclient
- - fixed a share level security encryption bug
- - added "ENCRYPTION.txt" document
- - released alpha11
- - added code to detect a password server loop
- - fixed typo in chkpath in client.c that broken cd (again)
- - LINUX_BIGCRYPT from marsj@ida.liu.se
- - AFS password fixup from jbushey@primenet.com (Jeffrey G. Bushey)
- - iso/8859-1 charcnv patches from Dan.Oscarsson@malmo.trab.se
- - strtok/user_in_list fix from roderich@nodebonn.muc.bmw.de
- - NETGROUP patches from J.W.Schilperoort@research.ptt.nl
- - trim_string patch from J.W.Schilperoort@research.ptt.nl
- - fixed problem with files with no extension getting mixed up
- - ipc bugfix for print job deletion from Rainer Leberle <rleberle@auspex.de>
- - released alpha12
- - pwlen fix in NETGROUP from Andrew J Cole <A.J.Cole@cbl.leeds.ac.uk>
- - lots of uid and encryption changes from Jeremy Allison. WinDD
- should now work.
- - released alpha13
- - fixed max_xmit bug in client
- - select fix in server (fixed critical drive errors under ISC)
- - released alpha14
- - wildcard fix from Jeremy
- - changes to make IPC code more robust
- - small select loop change to reduce cleaning of share files
- - vtp, altos and mktime patches from Christian A. Lademann
- <cal@zls.com>
- - EEXIST bugfix in server.c
- - changed mangled map to apply in all cases
- - released alpha15
- - fixed fcb open permissions (should mean apps know when a file is
- read only)
- - released alpha16
- - client help formatting fix and docs fix from Peter Jones
- <thanatos@drealm.org>
- - added a directory cache
- - use /proc whenever possible for pid detection
- - TCSANOW fix in getsmbpasswd from roderich@nodebonn.muc.bmw.de
- - fixed default printing mode for sysv systems
- - make client always expand mask
- - more minor IPC fixups
- - pyramid makefile entry from jeffrey@itm.org
- - client fixups for passlen, maxvcs and session redirect from
- Charles Hoch <hoch@hplcgh.hpl.hp.com>
- - finally fixed important IPC bug (varargs bug with int16)
- - quota patches from Dirk.DeWachter@rug.ac.be
- - print queue cache changes (per service) and print queue priority
- additions from Dirk.DeWachter@rug.ac.be
- - new japanese patches (incomplete) from
- fujita@ainix.isac.co.jp (Takashi Fujita)
- - moved a lot more functions into system.c via wrappers
- - changed a lot of the connection refused error codes to be more
- informative (or at least different)
- - released alpha17
- - changed error return code from cannor chdir() in make_connection
- - fixed realloc() bug in printing.c
- - fixed invalid username bug in sesssetupX
- - released alpha18
- - made default service change name to asked for service (idea
- from Ian McEwan <ijm@doc.ic.ac.uk>)
- - fixed "guest only" bug
- - sambatar patches from Ricky
- - printing.c patches from Dirk.DeWachter@rug.ac.be
- - rewrote become_user()
- - sunos5 patch from Niels.Baggesen@uni-c.dk
- - more japanese extensions patches from fujita@ainix.isac.co.jp
- - released alpha20
- - added force_user to conn struct
-
-
-1.9.15: 14/11/95
- - removed bcast override from workgroup announce in nmbd
- - aix patch, added NO_SYSMOUNTH, from
- lionel leston <102624.346@compuserve.com>
- - quick fix in lp_string() to try and stop some core dumps
- - added uid cache in connections structure
- to make user level security faster
- - changed dos_mode() to show read-only on read-only shares only if
- user w bit not set
- - added check to stop exit_server() looping
- - core dump fix in string_sub()
- - fix client bug for long dirs in NT1 mode.
- Thanks to Erwin Authried (erwin@ws1.atv.tuwien.ac.at)
- - switched to a safer (but probably slower) readbraw implementation
- - released p1
- - readbraw fix from Stefaan.Eeckels@eunet.lu
- - fixed groups bug when user is in 1 group
- - fixed NT1 dir bug
- - changed default protocol in client to NT1
- - changed trans2 to not return both names in long listing if long
- name is 8.3
- - made stat of "" return RONLY if not writeable drive
- - wrapped strcpy() to stop nulls propogating (hack)
- - made rename and unlink look at share locks on file
- - clitar memory leak fix from jjm@jjm.com
- - added -p option to smbstatus to list smbd processes
- - added rename to the client
- - released p2
- - fixed SMBmv for case where the destination exists
- - man page patch from michal@ellpspace.math.ualberta.ca (Michal Jaegermann)
- - once again redid the time handling, but finally explained what
- is going on, this is written up in TIME.txt. The "kludge-GMT" used
- by NT is a bastard and led to a lot of the confusion
- - kanji patch from fujita@ainix.isac.co.jp (Takashi Fujita)
- - is08859-1 patches from eauth@mail.cso.co.at
- - starting rewriting nmbd, new nmbd is nmbd2, old one still around
- for time being
- - released p3
- - rewrote more of nmbd2 to use new structures
- - CLIX patches from Jason.J.Faultless@bechtel.btx400.co.uk
- - DirCacheFlush() bugfix from Michael Joosten
- <joost@ori.cadlab.de>. This bug explains a lot of the crashes.
- - fixed a bug in ChDir() that caused reversion to / in some
- situations
- - ipc fix from Magnus Hyllander <mhy@os.se>
- - released p4
- - smbpasswd fix from Jeremy
- - compilation fixes from Magnus Hyllander <mhy@os.se>
- - added NetServerEnum to ipc.c (needed for master browser stuff)
- - Makefile fix from Gunther Mayer <gmayer@physik.uni-kl.de>
- - cleanups for clean compile on several OSes
- - added browse mastering code
- - started integration with smb.conf for nmbd2
- - released p5
- - fixed death_time (should be t+ttl*3)
- - fixed non-removal of dead servers
- - added smbstatus -u patch from oskarh@spornet.is (Oskar Hannesson)
- - NETGROUP fix from J.W.Schilperoort@research.kpn.com
- - select and NO_SETGROUPS patches from lennylim@netcom.com (Lenny
- Lim)
- - added LINKS_READ_ONLY define in dos_mode() for LM/X
- compatability
- - "dir a.c" bug fixed thanks to roderich@nodebonn.muc.bmw.de
- (Roderich Schupp)
- - job cancel fix in client from peo@mtek.chalmers.se
- - changed nmbd2 to nmbd
- - fixed "dir a*" under trans2 lookups
- - added StrnCaseCmp()
- - updated docs a bit for new browsing stuff
- - updated INSTALL.txt
- - hopefully fixed server level security with WfWg
-
-1.9.15 (patches):
- - major/minor fix for solaris from Jeroen Schipper
- <Jeroen.Schipper@let.ruu.nl>
- - fixed critical bug in directory listings
- - released p1
- - fixed one of the causes of "out of memory" while browsing
- - fixed manpage install script (Paul Blackman)
- - added DNS failures to name cache
- - fixed writebmpx bug (affects OS/2)
- - misc OS/2 fixes, mostly for EA handling
- - added SMBcopy
- - added "max ttl" option
- - arch detection patch from Bas Laarhoven <bas@vimec.nl>
- - released p2
- - another OS/2 fix - the level 4 getpathinfo for EAs
- - added "alternate permissions" option
- - changed client to parse destination names into name + domain
- - fixed problem with PrimaryGroup and lmhosts loading
- - added domain master ability to nmbd
- - added "domain master" option
- - added "domain controller" option and code
- - pwd fix to client from Erik Devriendt (de@te6.siemens.be)
- - fixed problem in smbmv that led to ar not working in mks
- - added transs2
- - released p3
- - updated email addresses
- - fix for innetgr from Olaf Seibert (rhialto@polder.ubc.kun.nl)
- - client translate fix from bandc@dircon.co.uk
- - netbsd bcast fix from from Olaf Seibert (rhialto@polder.ubc.kun.nl)
- - syslog code from Alex Nash <alex@fa.tca.com>
- - strip dot fix from Arne Ansper <arne@ioc.ee>
- - added addtosmbpass + man page from
- michal@ellpspace.math.ualberta.ca (Michal Jaegermann)
- - pcap fix for AIX from Jon Christiansen <jchristi@sctcorp.com>
- - fixed servertype bug in remote announcements
- - fixed up illegal name checks (should also be faster)
- - kanji patches from fujita@ainix.isac.co.jp (Takashi Fujita)
- - fixed bug handling non-encrypted passwords
- - released p4
- - fixed makefile for addtosmbpass
- - DCE/DFS fixes from John Brezak (brezak@ch.hp.com)
- - client patch for partial command matching from Andrew Wiseman
- <bandc@dircon.co.uk>
- - made is_8_3() handle full paths
- - rewrote open_file_shared() with help from Charles Hoch
- <hoch@hplcgh.hpl.hp.com>
- - changed syslog to handle interactive programs
- - fixed syslog problem with full path in argv[0]
- - illegal name fixup for kanji from fujita@ainix.isac.co.jp
- - fixed server level security to allow fallback to encryption
- - changed reply_read() and reply_lockread() to ignore clients
- smb_bufsize in order to handle broken lanman clients
- - fixed NT wildcard problem with old style programs
- - man page patches from "John M. Sellens"
- <jmsellen@watdragon.uwaterloo.ca>
- - partially documented the "character set" option
- - changed default for MAXDIR to 64
- - changed default DPTR idle time to 120
- - released p5
- - QNX patches from eldo@invisa.satlink.net (Eldo Loguzzo)
- - made nmbd use the "max log size" option and changed log handling
- code a bit
- - sunos patches, remote protocol (%R) addition and arch detection
- changes to stop compiler warning from Timothy Hunt <tim@fsg.com>
- - fixed become_user() bug that led to incorrect permissions in
- some situations.
- - released p6
- - is_8_3() fix from Charles Hoch <hoch@hplcgh.hpl.hp.com>
- - nmblib bugfix from gmk@mhcnet.att.com (George Kull)
- - aix pcap fix from Jon Christiansen <jchristi@sctcorp.com>
- - added explicit sig_pipe() in server.c
- - added domain logins option (not fully implemented)
- - added HAVE_GMTOFF code
- - got rid of PM_MAXLINE
- - minor client fix from goggi@eflir (Garðar Georg Nielsen)
- - added SIGCLD_IGNORE for HPUX (from Tor Lillqvist
- <tml@hemuli.tte.vtt.fi>)
- - OSF/1 lpq patch from scooter@GENE.COM (Scooter Morris)
- - NeXT patches from pmarcos@next.com (Paul Marcos)
- - dstdiff patch to stop infinite loop from Erwin Authried (eauth@cso.co.at)
- - password server option can now take a list of password servers
- - patches to let samba run on OS/2 from Jason Rumney <jasonr@pec.co.nz>
- - added domain logon and logon script suport
- - SCO openserver 5 patches from Scott Michel <scottm@intime.intime.com>
- - Makefile changes from Marty Leisner <leisner@sdsp.mc.xerox.com>
- - chgpasswd changes from Roman Dumych <roman@nyxis.unibase.com>
- for SVR4
- - GUEST_SESSSETUP change from David.Chappell@mail.cc.trincoll.edu
- - released p7
- - moved SO_REUSEADDR before bind() (thanks to Thomas Bellman
- <tbe@ivab.se>)
- - added more flexible GUEST_SESSSETUP to local.h and restored
- pre-p7 behaviour as default
- - released p8
-
-1.9.16:
- - Makefile fix from Marty Leisner <leisner@sdsp.mc.xerox.com>
- - added %g and %G substitutions
- - changed IDLE_CLOSED_TIMEOUT to 60
- - fixed the "admin user" status in domain logons
- - hpux 10 "trusted security" patches from David-Michael Lincke
- (dlincke@sgcl1.unisg.ch)
- - added nmb lookups to client from Adrian Hill <Adrian.Hill@softimage.co.uk>
- - svr4 pause/resume printing patch from Brendan O'Dea (bod@tyndall.com.au)
- - fixed master announcement thanks to Luke Leighton <rah14@dial.pipex.com>
- - changed srcdir usage in Makefile to be friendly to more systems
- - NT4 alignment patches from Jeremy Allison (jra@vantive.com)
- - updated share mode code for new spec
- - minor client bugfix (for smbclient '\\\')
- - fix for level 260 when magling disabled. From Martin Tomes
- <Martin.Tomes@ecl.etherm.co.uk>
- - SMBtranss2 fix for OS/2 from Jeremy Allison
- - profiles fixup from Timm Wetzel <twetzel@cage.mpibpc.gwdg.de>
- - man page updates from Dirk.DeWachter@rug.ac.be
- - nmbsync fix from Andy Whitcroft <andy@soi.city.ac.uk>
- - Lynx patches from Manfred Woelfel <woelfel@hpesco1.fzk.de>
- - new smbtar stuff from Ricky
- - changed to share mode DENY_NONE for tar
- - fixed -D option of smbclient when in tar mode
- - added aARCH to open modes
- - added code to cope with select/read errors
- - fixed blank browse entries after smb.conf reread
- - integrated new browse stuff from Luke into ipc.c
- - added workgroup list to smbclient -L
- - improved archive attribute handling in close_file() and
- write_file()
- - smbtar fixes from Martin.Kraemer@mch.sni.de
- - Linux quota patch from xeno@mix.hsv.no
- - try to work around NT passlen2 problem in session setup
- - released alpha1
-
-NOTE: From now on the cvs.log file will be used to give a complete log of
-changes to samba. This change-log is now obsolete.
-
-
-==========
-todo:
-
-
-64 bit longs and IP addresses may give problems with unsigned longs?
-
-set archive bit whenever file is modified??
-
-fix man page dates
-
-reply only to own workgroup in server enum
-
-patch to compile with g++ and possibly solaris c++
-
-nmbd needs to keep browse list uptodate by talking to the master if it loses
-an election as others may still think its a valid backup and use it to get
-lists.
-
-leftover lock files can end up belonging to non-smbd processes after a reboot.
-
-hosts allow in nmbd
-
-hosts allow cache
-
-add password command in smbclient
-
-drag long filename to samba under os/2 gives short name
-
-document max ttl option
-
-dup/close 0 for getopt?
-
-implement SMBmove ??
-
-add option to print more info about locked files (full path, share name
-etc)
-
-very slow listing CD, perhaps because of order of stat and readdir or add
-masking to opendir?
-
-protocol drop back in client to avoid openX etc.
-
-handle exported fat drives to a long filename capable client
-
-add check for existance of lpq commands etc (use stat?)
-
-get rid of the silly +4 and -4 by removing NBT stuff
-
-write-only shares
-
-document cnvchar stuff
-
-allow smbd to serve user and group lists to win95
-
-document homes behaviour with WinDD
-
-add "hide file = *.o" "hide dir = .Foo*" "show file = xx*" type options.
-
-ALLOW_PASSWORD_CHANGE only compiles/works on some systems
-
-weird foooooooo/open.exe bug on NT
-
-%a detection can't detect Win95 versus WinNT
-
-reverse mangled maps, so (*.html *.htm) works for new files.
-
-install problems with w95. could be some sort of race?
-
-more efficient Files[] structure to handle thousands of open files
-
-lpd stuff:
- Tony Aiuto (tony@ics.com)
-
-make max disk size local
-
diff --git a/source/client/client.c b/source/client/client.c
deleted file mode 100644
index 6d85bd8807f..00000000000
--- a/source/client/client.c
+++ /dev/null
@@ -1,4910 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- SMB client
- Copyright (C) Andrew Tridgell 1994-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.
-*/
-
-#ifdef SYSLOG
-#undef SYSLOG
-#endif
-
-#include "includes.h"
-
-#ifndef REGISTER
-#define REGISTER 0
-#endif
-
-pstring cur_dir = "\\";
-pstring cd_path = "";
-pstring service="";
-pstring desthost="";
-extern pstring myname;
-extern pstring myhostname;
-pstring password = "";
-pstring username="";
-pstring workgroup="";
-char *cmdstr="";
-BOOL got_pass = False;
-BOOL connect_as_printer = False;
-BOOL connect_as_ipc = False;
-extern struct in_addr ipzero;
-
-char cryptkey[8];
-BOOL doencrypt=False;
-
-extern pstring user_socket_options;
-
-/* 30 second timeout on most commands */
-#define CLIENT_TIMEOUT (30*1000)
-#define SHORT_TIMEOUT (5*1000)
-
-/* value for unused fid field in trans2 secondary request */
-#define FID_UNUSED (0xFFFF)
-
-int name_type = 0x20;
-
-int max_protocol = PROTOCOL_NT1;
-
-
-time_t newer_than = 0;
-int archive_level = 0;
-
-extern pstring debugf;
-extern int DEBUGLEVEL;
-
-BOOL translation = False;
-
-
-static BOOL send_trans_request(char *outbuf,int trans,
- char *name,int fid,int flags,
- char *data,char *param,uint16 *setup,
- int ldata,int lparam,int lsetup,
- int mdata,int mparam,int msetup);
-static BOOL receive_trans_response(char *inbuf,int trans,
- int *data_len,int *param_len,
- char **data,char **param);
-static int interpret_long_filename(int level,char *p,file_info *finfo);
-static void dir_action(char *inbuf,char *outbuf,int attribute,file_info *finfo,BOOL recurse_dir,void (*fn)(),BOOL longdir);
-static int interpret_short_filename(char *p,file_info *finfo);
-static BOOL call_api(int prcnt,int drcnt,
- int mprcnt,int mdrcnt,
- int *rprcnt,int *rdrcnt,
- char *param,char *data,
- char **rparam,char **rdata);
-static BOOL do_this_one(file_info *finfo);
-
-/* clitar bits insert */
-extern int blocksize;
-extern BOOL tar_inc;
-extern BOOL tar_reset;
-/* clitar bits end */
-
-
-int cnum = 0;
-int pid = 0;
-int gid = 0;
-int uid = 0;
-int mid = 0;
-int myumask = 0755;
-
-int max_xmit = BUFFER_SIZE;
-
-extern pstring scope;
-
-BOOL prompt = True;
-
-int printmode = 1;
-
-BOOL recurse = False;
-BOOL lowercase = False;
-
-BOOL have_ip = False;
-
-struct in_addr dest_ip;
-
-#define SEPARATORS " \t\n\r"
-
-BOOL abort_mget = True;
-
-extern int Protocol;
-
-BOOL readbraw_supported = False;
-BOOL writebraw_supported = False;
-
-pstring fileselection = "";
-
-extern file_info def_finfo;
-
-/* timing globals */
-int get_total_size = 0;
-int get_total_time_ms = 0;
-int put_total_size = 0;
-int put_total_time_ms = 0;
-
-/* totals globals */
-int dir_total = 0;
-
-extern int Client;
-
-#define USENMB
-
-extern int coding_system;
-static BOOL setup_term_code (char *code)
-{
- int new;
- new = interpret_coding_system (code, UNKNOWN_CODE);
- if (new != UNKNOWN_CODE) {
- coding_system = new;
- return True;
- }
- return False;
-}
-#define CNV_LANG(s) dos2unix_format(s,False)
-#define CNV_INPUT(s) unix2dos_format(s,True)
-
-/****************************************************************************
-setup basics in a outgoing packet
-****************************************************************************/
-void setup_pkt(char *outbuf)
-{
- SSVAL(outbuf,smb_pid,pid);
- SSVAL(outbuf,smb_uid,uid);
- SSVAL(outbuf,smb_mid,mid);
- if (Protocol > PROTOCOL_COREPLUS)
- {
- SCVAL(outbuf,smb_flg,0x8);
- SSVAL(outbuf,smb_flg2,0x1);
- }
-}
-
-/****************************************************************************
-write to a local file with CR/LF->LF translation if appropriate. return the
-number taken from the buffer. This may not equal the number written.
-****************************************************************************/
-static int writefile(int f, char *b, int n)
-{
- int i;
-
- if (!translation)
- return(write(f,b,n));
-
- i = 0;
- while (i < n)
- {
- if (*b == '\r' && (i<(n-1)) && *(b+1) == '\n')
- {
- b++;i++;
- }
- if (write(f, b, 1) != 1)
- {
- break;
- }
- b++;
- i++;
- }
-
- return(i);
-}
-
-/****************************************************************************
- read from a file with LF->CR/LF translation if appropriate. return the
- number read. read approx n bytes.
-****************************************************************************/
-static int readfile(char *b, int size, int n, FILE *f)
-{
- int i;
- int c;
-
- if (!translation || (size != 1))
- return(fread(b,size,n,f));
-
- i = 0;
- while (i < n)
- {
- if ((c = getc(f)) == EOF)
- {
- break;
- }
-
- if (c == '\n') /* change all LFs to CR/LF */
- {
- b[i++] = '\r';
- n++;
- }
-
- if(i < n)
- b[i++] = c;
- }
-
- return(i);
-}
-
-
-/****************************************************************************
-read from a file with print translation. return the number read. read approx n
-bytes.
-****************************************************************************/
-static int printread(FILE *f,char *b,int n)
-{
- int i;
-
- i = readfile(b,1, n-1,f);
-#if FORMFEED
- if (feof(f) && i>0)
- b[i++] = '\014';
-#endif
-
- return(i);
-}
-
-/****************************************************************************
-check for existance of a dir
-****************************************************************************/
-static BOOL chkpath(char *path,BOOL report)
-{
- fstring path2;
- pstring inbuf,outbuf;
- char *p;
-
- strcpy(path2,path);
- trim_string(path2,NULL,"\\");
- if (!*path2) *path2 = '\\';
-
- bzero(outbuf,smb_size);
- set_message(outbuf,0,4 + strlen(path2),True);
- SCVAL(outbuf,smb_com,SMBchkpth);
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- p = smb_buf(outbuf);
- *p++ = 4;
- strcpy(p,path2);
-
-#if 0
- {
- /* this little bit of code can be used to extract NT error codes.
- Just feed a bunch of "cd foo" commands to smbclient then watch
- in netmon (tridge) */
- static int code=0;
- SIVAL(outbuf, smb_rcls, code | 0xC0000000);
- SSVAL(outbuf, smb_flg2, SVAL(outbuf, smb_flg2) | (1<<14));
- code++;
- }
-#endif
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (report && CVAL(inbuf,smb_rcls) != 0)
- DEBUG(2,("chkpath: %s\n",smb_errstr(inbuf)));
-
- return(CVAL(inbuf,smb_rcls) == 0);
-}
-
-
-/****************************************************************************
-send a message
-****************************************************************************/
-static void send_message(char *inbuf,char *outbuf)
-{
- int total_len = 0;
-
- char *p;
- int grp_id;
-
- /* send a SMBsendstrt command */
- bzero(outbuf,smb_size);
- set_message(outbuf,0,0,True);
- CVAL(outbuf,smb_com) = SMBsendstrt;
- SSVAL(outbuf,smb_tid,cnum);
-
- p = smb_buf(outbuf);
- *p++ = 4;
- strcpy(p,username);
- p = skip_string(p,1);
- *p++ = 4;
- strcpy(p,desthost);
- p = skip_string(p,1);
-
- set_message(outbuf,0,PTR_DIFF(p,smb_buf(outbuf)),False);
-
- send_smb(Client,outbuf);
-
-
- if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
- {
- printf("SMBsendstrt failed. (%s)\n",smb_errstr(inbuf));
- return;
- }
-
- grp_id = SVAL(inbuf,smb_vwv0);
-
- printf("Connected. Type your message, ending it with a Control-D\n");
-
- while (!feof(stdin) && total_len < 1600)
- {
- int maxlen = MIN(1600 - total_len,127);
- pstring msg;
- int l=0;
- int c;
-
- bzero(msg,smb_size);
-
- for (l=0;l<maxlen && (c=fgetc(stdin))!=EOF;l++)
- {
- if (c == '\n')
- msg[l++] = '\r';
- msg[l] = c;
- }
-
- CVAL(outbuf,smb_com) = SMBsendtxt;
-
- set_message(outbuf,1,l+3,True);
-
- SSVAL(outbuf,smb_vwv0,grp_id);
-
- p = smb_buf(outbuf);
- *p = 1;
- SSVAL(p,1,l);
- memcpy(p+3,msg,l);
-
- send_smb(Client,outbuf);
-
-
- if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
- {
- printf("SMBsendtxt failed (%s)\n",smb_errstr(inbuf));
- return;
- }
-
- total_len += l;
- }
-
- if (total_len >= 1600)
- printf("the message was truncated to 1600 bytes ");
- else
- printf("sent %d bytes ",total_len);
-
- printf("(status was %d-%d)\n",CVAL(inbuf,smb_rcls),SVAL(inbuf,smb_err));
-
- CVAL(outbuf,smb_com) = SMBsendend;
- set_message(outbuf,1,0,False);
- SSVAL(outbuf,smb_vwv0,grp_id);
-
- send_smb(Client,outbuf);
-
-
- if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
- {
- printf("SMBsendend failed (%s)\n",smb_errstr(inbuf));
- return;
- }
-}
-
-
-
-/****************************************************************************
-check the space on a device
-****************************************************************************/
-static void do_dskattr(void)
-{
- pstring inbuf,outbuf;
-
- bzero(outbuf,smb_size);
- set_message(outbuf,0,0,True);
- CVAL(outbuf,smb_com) = SMBdskattr;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- DEBUG(0,("Error in dskattr: %s\n",smb_errstr(inbuf)));
-
- DEBUG(0,("\n\t\t%d blocks of size %d. %d blocks available\n",
- SVAL(inbuf,smb_vwv0),
- SVAL(inbuf,smb_vwv1)*SVAL(inbuf,smb_vwv2),
- SVAL(inbuf,smb_vwv3)));
-}
-
-/****************************************************************************
-show cd/pwd
-****************************************************************************/
-static void cmd_pwd(void)
-{
- DEBUG(0,("Current directory is %s",CNV_LANG(service)));
- DEBUG(0,("%s\n",CNV_LANG(cur_dir)));
-}
-
-
-/****************************************************************************
-change directory - inner section
-****************************************************************************/
-static void do_cd(char *newdir)
-{
- char *p = newdir;
- pstring saved_dir;
- pstring dname;
-
- /* Save the current directory in case the
- new directory is invalid */
- strcpy(saved_dir, cur_dir);
- if (*p == '\\')
- strcpy(cur_dir,p);
- else
- strcat(cur_dir,p);
- if (*(cur_dir+strlen(cur_dir)-1) != '\\') {
- strcat(cur_dir, "\\");
- }
- dos_clean_name(cur_dir);
- strcpy(dname,cur_dir);
- strcat(cur_dir,"\\");
- dos_clean_name(cur_dir);
-
- if (!strequal(cur_dir,"\\"))
- if (!chkpath(dname,True))
- strcpy(cur_dir,saved_dir);
-
- strcpy(cd_path,cur_dir);
-}
-
-/****************************************************************************
-change directory
-****************************************************************************/
-static void cmd_cd(char *inbuf,char *outbuf)
-{
- fstring buf;
-
- if (next_token(NULL,buf,NULL))
- do_cd(buf);
- else
- DEBUG(0,("Current directory is %s\n",CNV_LANG(cur_dir)));
-}
-
-
-/****************************************************************************
- display info about a file
- ****************************************************************************/
-static void display_finfo(file_info *finfo)
-{
- if (do_this_one(finfo)) {
- time_t t = finfo->mtime; /* the time is assumed to be passed as GMT */
- DEBUG(0,(" %-30s%7.7s%10d %s",
- CNV_LANG(finfo->name),
- attrib_string(finfo->mode),
- finfo->size,
- asctime(LocalTime(&t))));
- dir_total += finfo->size;
- }
-}
-
-
-/****************************************************************************
- do a directory listing, calling fn on each file found. Use the TRANSACT2
- call for long filenames
- ****************************************************************************/
-static int do_long_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
-{
- int max_matches = 512;
- int info_level = Protocol<PROTOCOL_NT1?1:260; /* NT uses 260, OS/2 uses 2. Both accept 1. */
- char *p;
- pstring mask;
- file_info finfo;
- int i;
- char *dirlist = NULL;
- int dirlist_len = 0;
- int total_received = 0;
- BOOL First = True;
- char *resp_data=NULL;
- char *resp_param=NULL;
- int resp_data_len = 0;
- int resp_param_len=0;
-
- int ff_resume_key = 0;
- int ff_searchcount=0;
- int ff_eos=0;
- int ff_lastname=0;
- int ff_dir_handle=0;
- int loop_count = 0;
-
- uint16 setup;
- pstring param;
-
- strcpy(mask,Mask);
-
- while (ff_eos == 0)
- {
- loop_count++;
- if (loop_count > 200)
- {
- DEBUG(0,("Error: Looping in FIND_NEXT??\n"));
- break;
- }
-
- if (First)
- {
- setup = TRANSACT2_FINDFIRST;
- SSVAL(param,0,attribute); /* attribute */
- SSVAL(param,2,max_matches); /* max count */
- SSVAL(param,4,8+4+2); /* resume required + close on end + continue */
- SSVAL(param,6,info_level);
- SIVAL(param,8,0);
- strcpy(param+12,mask);
- }
- else
- {
- setup = TRANSACT2_FINDNEXT;
- SSVAL(param,0,ff_dir_handle);
- SSVAL(param,2,max_matches); /* max count */
- SSVAL(param,4,info_level);
- SIVAL(param,6,ff_resume_key); /* ff_resume_key */
- SSVAL(param,10,8+4+2); /* resume required + close on end + continue */
- strcpy(param+12,mask);
-
- DEBUG(5,("hand=0x%X resume=%d ff_lastname=%d mask=%s\n",
- ff_dir_handle,ff_resume_key,ff_lastname,mask));
- }
- /* ??? original code added 1 pad byte after param */
-
- send_trans_request(outbuf,SMBtrans2,NULL,FID_UNUSED,0,
- NULL,param,&setup,
- 0,12+strlen(mask)+1,1,
- BUFFER_SIZE,10,0);
-
- if (!receive_trans_response(inbuf,SMBtrans2,
- &resp_data_len,&resp_param_len,
- &resp_data,&resp_param))
- {
- DEBUG(3,("FIND%s gave %s\n",First?"FIRST":"NEXT",smb_errstr(inbuf)));
- break;
- }
-
- /* parse out some important return info */
- p = resp_param;
- if (First)
- {
- ff_dir_handle = SVAL(p,0);
- ff_searchcount = SVAL(p,2);
- ff_eos = SVAL(p,4);
- ff_lastname = SVAL(p,8);
- }
- else
- {
- ff_searchcount = SVAL(p,0);
- ff_eos = SVAL(p,2);
- ff_lastname = SVAL(p,6);
- }
-
- if (ff_searchcount == 0)
- break;
-
- /* point to the data bytes */
- p = resp_data;
-
- /* we might need the lastname for continuations */
- if (ff_lastname > 0)
- {
- switch(info_level)
- {
- case 260:
- ff_resume_key =0;
- StrnCpy(mask,p+ff_lastname,resp_data_len-ff_lastname);
- /* strcpy(mask,p+ff_lastname+94); */
- break;
- case 1:
- strcpy(mask,p + ff_lastname + 1);
- ff_resume_key = 0;
- break;
- }
- }
- else
- strcpy(mask,"");
-
- /* and add them to the dirlist pool */
- dirlist = Realloc(dirlist,dirlist_len + resp_data_len);
-
- if (!dirlist)
- {
- DEBUG(0,("Failed to expand dirlist\n"));
- break;
- }
-
- /* put in a length for the last entry, to ensure we can chain entries
- into the next packet */
- {
- char *p2;
- for (p2=p,i=0;i<(ff_searchcount-1);i++)
- p2 += interpret_long_filename(info_level,p2,NULL);
- SSVAL(p2,0,resp_data_len - PTR_DIFF(p2,p));
- }
-
- /* grab the data for later use */
- memcpy(dirlist+dirlist_len,p,resp_data_len);
- dirlist_len += resp_data_len;
-
- total_received += ff_searchcount;
-
- if (resp_data) free(resp_data); resp_data = NULL;
- if (resp_param) free(resp_param); resp_param = NULL;
-
- DEBUG(3,("received %d entries (eos=%d resume=%d)\n",
- ff_searchcount,ff_eos,ff_resume_key));
-
- First = False;
- }
-
- if (!fn)
- for (p=dirlist,i=0;i<total_received;i++)
- {
- p += interpret_long_filename(info_level,p,&finfo);
- display_finfo(&finfo);
- }
-
- for (p=dirlist,i=0;i<total_received;i++)
- {
- p += interpret_long_filename(info_level,p,&finfo);
- dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,True);
- }
-
- /* free up the dirlist buffer */
- if (dirlist) free(dirlist);
- return(total_received);
-}
-
-
-/****************************************************************************
- do a directory listing, calling fn on each file found
- ****************************************************************************/
-static int do_short_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
-{
- char *p;
- int received = 0;
- BOOL first = True;
- char status[21];
- int num_asked = (max_xmit - 100)/DIR_STRUCT_SIZE;
- int num_received = 0;
- int i;
- char *dirlist = NULL;
- pstring mask;
- file_info finfo;
-
- finfo = def_finfo;
-
- bzero(status,21);
-
- strcpy(mask,Mask);
-
- while (1)
- {
- bzero(outbuf,smb_size);
- if (first)
- set_message(outbuf,2,5 + strlen(mask),True);
- else
- set_message(outbuf,2,5 + 21,True);
-
-#if FFIRST
- if (Protocol >= PROTOCOL_LANMAN1)
- CVAL(outbuf,smb_com) = SMBffirst;
- else
-#endif
- CVAL(outbuf,smb_com) = SMBsearch;
-
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,num_asked);
- SSVAL(outbuf,smb_vwv1,attribute);
-
- p = smb_buf(outbuf);
- *p++ = 4;
-
- if (first)
- strcpy(p,mask);
- else
- strcpy(p,"");
- p += strlen(p) + 1;
-
- *p++ = 5;
- if (first)
- SSVAL(p,0,0);
- else
- {
- SSVAL(p,0,21);
- p += 2;
- memcpy(p,status,21);
- }
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- received = SVAL(inbuf,smb_vwv0);
-
- DEBUG(5,("dir received %d\n",received));
-
- DEBUG(6,("errstr=%s\n",smb_errstr(inbuf)));
-
- if (received <= 0) break;
-
- first = False;
-
- dirlist = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE);
-
- if (!dirlist)
- return 0;
-
- p = smb_buf(inbuf) + 3;
-
- memcpy(dirlist+num_received*DIR_STRUCT_SIZE,
- p,received*DIR_STRUCT_SIZE);
-
- memcpy(status,p + ((received-1)*DIR_STRUCT_SIZE),21);
-
- num_received += received;
-
- if (CVAL(inbuf,smb_rcls) != 0) break;
- }
-
-#if FFIRST
- if (!first && Protocol >= PROTOCOL_LANMAN1)
- {
- bzero(outbuf,smb_size);
- CVAL(outbuf,smb_com) = SMBfclose;
-
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- p = smb_buf(outbuf);
- *p++ = 4;
-
- strcpy(p,"");
- p += strlen(p) + 1;
-
- *p++ = 5;
- SSVAL(p,0,21);
- p += 2;
- memcpy(p,status,21);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- DEBUG(0,("Error closing search: %s\n",smb_errstr(inbuf)));
- }
-#endif
-
- if (!fn)
- for (p=dirlist,i=0;i<num_received;i++)
- {
- p += interpret_short_filename(p,&finfo);
- display_finfo(&finfo);
- }
-
- for (p=dirlist,i=0;i<num_received;i++)
- {
- p += interpret_short_filename(p,&finfo);
- dir_action(inbuf,outbuf,attribute,&finfo,recurse_dir,fn,False);
- }
-
- if (dirlist) free(dirlist);
- return(num_received);
-}
-
-
-
-/****************************************************************************
- do a directory listing, calling fn on each file found
- ****************************************************************************/
-void do_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir)
-{
- DEBUG(5,("do_dir(%s,%x,%s)\n",Mask,attribute,BOOLSTR(recurse_dir)));
- if (Protocol >= PROTOCOL_LANMAN2)
- {
- if (do_long_dir(inbuf,outbuf,Mask,attribute,fn,recurse_dir) > 0)
- return;
- }
-
- expand_mask(Mask,False);
- do_short_dir(inbuf,outbuf,Mask,attribute,fn,recurse_dir);
- return;
-}
-
-/*******************************************************************
- decide if a file should be operated on
- ********************************************************************/
-static BOOL do_this_one(file_info *finfo)
-{
- if (finfo->mode & aDIR) return(True);
-
- if (newer_than && finfo->mtime < newer_than)
- return(False);
-
- if ((archive_level==1 || archive_level==2) && !(finfo->mode & aARCH))
- return(False);
-
- return(True);
-}
-
-
-/*****************************************************************************
- Convert a character pointer in a call_api() response to a form we can use.
- This function contains code to prevent core dumps if the server returns
- invalid data.
-*****************************************************************************/
-static char *fix_char_ptr(unsigned int datap, unsigned int converter, char *rdata, int rdrcnt)
-{
-if( datap == 0 ) /* turn NULL pointers */
- { /* into zero length strings */
- return "";
- }
-else
- {
- unsigned int offset = datap - converter;
-
- if( offset >= rdrcnt )
- {
- DEBUG(1,("bad char ptr: datap=%u, converter=%u, rdata=%lu, rdrcnt=%d>", datap, converter, (unsigned long)rdata, rdrcnt));
- return "<ERROR>";
- }
- else
- {
- return &rdata[offset];
- }
- }
-}
-
-/****************************************************************************
-interpret a short filename structure
-The length of the structure is returned
-****************************************************************************/
-static int interpret_short_filename(char *p,file_info *finfo)
-{
- finfo->mode = CVAL(p,21);
-
- /* this date is converted to GMT by make_unix_date */
- finfo->ctime = make_unix_date(p+22);
- finfo->mtime = finfo->atime = finfo->ctime;
- finfo->size = IVAL(p,26);
- strcpy(finfo->name,p+30);
-
- return(DIR_STRUCT_SIZE);
-}
-
-/****************************************************************************
-interpret a long filename structure - this is mostly guesses at the moment
-The length of the structure is returned
-The structure of a long filename depends on the info level. 260 is used
-by NT and 2 is used by OS/2
-****************************************************************************/
-static int interpret_long_filename(int level,char *p,file_info *finfo)
-{
- if (finfo)
- memcpy(finfo,&def_finfo,sizeof(*finfo));
-
- switch (level)
- {
- case 1: /* OS/2 understands this */
- if (finfo)
- {
- /* these dates are converted to GMT by make_unix_date */
- finfo->ctime = make_unix_date2(p+4);
- finfo->atime = make_unix_date2(p+8);
- finfo->mtime = make_unix_date2(p+12);
- finfo->size = IVAL(p,16);
- finfo->mode = CVAL(p,24);
- strcpy(finfo->name,p+27);
- }
- return(28 + CVAL(p,26));
-
- case 2: /* this is what OS/2 uses mostly */
- if (finfo)
- {
- /* these dates are converted to GMT by make_unix_date */
- finfo->ctime = make_unix_date2(p+4);
- finfo->atime = make_unix_date2(p+8);
- finfo->mtime = make_unix_date2(p+12);
- finfo->size = IVAL(p,16);
- finfo->mode = CVAL(p,24);
- strcpy(finfo->name,p+31);
- }
- return(32 + CVAL(p,30));
-
- /* levels 3 and 4 are untested */
- case 3:
- if (finfo)
- {
- /* these dates are probably like the other ones */
- finfo->ctime = make_unix_date2(p+8);
- finfo->atime = make_unix_date2(p+12);
- finfo->mtime = make_unix_date2(p+16);
- finfo->size = IVAL(p,20);
- finfo->mode = CVAL(p,28);
- strcpy(finfo->name,p+33);
- }
- return(SVAL(p,4)+4);
-
- case 4:
- if (finfo)
- {
- /* these dates are probably like the other ones */
- finfo->ctime = make_unix_date2(p+8);
- finfo->atime = make_unix_date2(p+12);
- finfo->mtime = make_unix_date2(p+16);
- finfo->size = IVAL(p,20);
- finfo->mode = CVAL(p,28);
- strcpy(finfo->name,p+37);
- }
- return(SVAL(p,4)+4);
-
- case 260: /* NT uses this, but also accepts 2 */
- if (finfo)
- {
- int ret = SVAL(p,0);
- int namelen;
- p += 4; /* next entry offset */
- p += 4; /* fileindex */
-
- /* these dates appear to arrive in a weird way. It seems to
- be localtime plus the serverzone given in the initial
- connect. This is GMT when DST is not in effect and one
- hour from GMT otherwise. Can this really be right??
-
- I suppose this could be called kludge-GMT. Is is the GMT
- you get by using the current DST setting on a different
- localtime. It will be cheap to calculate, I suppose, as
- no DST tables will be needed */
-
- finfo->ctime = interpret_long_date(p); p += 8;
- finfo->atime = interpret_long_date(p); p += 8;
- finfo->mtime = interpret_long_date(p); p += 8; p += 8;
- finfo->size = IVAL(p,0); p += 8;
- p += 8; /* alloc size */
- finfo->mode = CVAL(p,0); p += 4;
- namelen = IVAL(p,0); p += 4;
- p += 4; /* EA size */
- p += 2; /* short name len? */
- p += 24; /* short name? */
- StrnCpy(finfo->name,p,namelen);
- return(ret);
- }
- return(SVAL(p,0));
- }
-
- DEBUG(1,("Unknown long filename format %d\n",level));
- return(SVAL(p,0));
-}
-
-
-
-
-/****************************************************************************
- act on the files in a dir listing
- ****************************************************************************/
-static void dir_action(char *inbuf,char *outbuf,int attribute,file_info *finfo,BOOL recurse_dir,void (*fn)(),BOOL longdir)
-{
-
- if (!((finfo->mode & aDIR) == 0 && *fileselection &&
- !mask_match(finfo->name,fileselection,False,False)) &&
- !(recurse_dir && (strequal(finfo->name,".") ||
- strequal(finfo->name,".."))))
- {
- if (recurse_dir && (finfo->mode & aDIR))
- {
- pstring mask2;
- pstring sav_dir;
- strcpy(sav_dir,cur_dir);
- strcat(cur_dir,finfo->name);
- strcat(cur_dir,"\\");
- strcpy(mask2,cur_dir);
-
- if (!fn)
- DEBUG(0,("\n%s\n",CNV_LANG(cur_dir)));
-
- strcat(mask2,"*");
-
- if (longdir)
- do_long_dir(inbuf,outbuf,mask2,attribute,fn,True);
- else
- do_dir(inbuf,outbuf,mask2,attribute,fn,True);
-
- strcpy(cur_dir,sav_dir);
- }
- else
- {
- if (fn && do_this_one(finfo))
- fn(finfo);
- }
- }
-}
-
-
-/****************************************************************************
- receive a SMB trans or trans2 response allocating the necessary memory
- ****************************************************************************/
-static BOOL receive_trans_response(char *inbuf,int trans,
- int *data_len,int *param_len,
- char **data,char **param)
-{
- int total_data=0;
- int total_param=0;
- int this_data,this_param;
-
- *data_len = *param_len = 0;
-
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
- show_msg(inbuf);
-
- /* sanity check */
- if (CVAL(inbuf,smb_com) != trans)
- {
- DEBUG(0,("Expected %s response, got command 0x%02x\n",
- trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(inbuf,smb_com)));
- return(False);
- }
- if (CVAL(inbuf,smb_rcls) != 0)
- return(False);
-
- /* parse out the lengths */
- total_data = SVAL(inbuf,smb_tdrcnt);
- total_param = SVAL(inbuf,smb_tprcnt);
-
- /* allocate it */
- *data = Realloc(*data,total_data);
- *param = Realloc(*param,total_param);
-
- while (1)
- {
- this_data = SVAL(inbuf,smb_drcnt);
- this_param = SVAL(inbuf,smb_prcnt);
- if (this_data)
- memcpy(*data + SVAL(inbuf,smb_drdisp),
- smb_base(inbuf) + SVAL(inbuf,smb_droff),
- this_data);
- if (this_param)
- memcpy(*param + SVAL(inbuf,smb_prdisp),
- smb_base(inbuf) + SVAL(inbuf,smb_proff),
- this_param);
- *data_len += this_data;
- *param_len += this_param;
-
- /* parse out the total lengths again - they can shrink! */
- total_data = SVAL(inbuf,smb_tdrcnt);
- total_param = SVAL(inbuf,smb_tprcnt);
-
- if (total_data <= *data_len && total_param <= *param_len)
- break;
-
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
- show_msg(inbuf);
-
- /* sanity check */
- if (CVAL(inbuf,smb_com) != trans)
- {
- DEBUG(0,("Expected %s response, got command 0x%02x\n",
- trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(inbuf,smb_com)));
- return(False);
- }
- if (CVAL(inbuf,smb_rcls) != 0)
- return(False);
- }
-
- return(True);
-}
-
-
-/****************************************************************************
- get a directory listing
- ****************************************************************************/
-static void cmd_dir(char *inbuf,char *outbuf)
-{
- int attribute = aDIR | aSYSTEM | aHIDDEN;
- pstring mask;
- fstring buf;
- char *p=buf;
-
- dir_total = 0;
- strcpy(mask,cur_dir);
- if(mask[strlen(mask)-1]!='\\')
- strcat(mask,"\\");
-
- if (next_token(NULL,buf,NULL))
- {
- if (*p == '\\')
- strcpy(mask,p);
- else
- strcat(mask,p);
- }
- else {
- strcat(mask,"*");
- }
-
- do_dir(inbuf,outbuf,mask,attribute,NULL,recurse);
-
- do_dskattr();
-
- DEBUG(3, ("Total bytes listed: %d\n", dir_total));
-}
-
-
-
-/****************************************************************************
- get a file from rname to lname
- ****************************************************************************/
-static void do_get(char *rname,char *lname,file_info *finfo1)
-{
- int handle=0,fnum;
- uint32 nread=0;
- char *p;
- BOOL newhandle = False;
- char *inbuf,*outbuf;
- file_info finfo;
- BOOL close_done = False;
- BOOL ignore_close_error = False;
- char *dataptr=NULL;
- int datalen=0;
-
- struct timeval tp_start;
- GetTimeOfDay(&tp_start);
-
- if (finfo1)
- finfo = *finfo1;
- else
- finfo = def_finfo;
-
- if (lowercase)
- strlower(lname);
-
-
- inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
- if (!inbuf || !outbuf)
- {
- DEBUG(0,("out of memory\n"));
- return;
- }
-
- bzero(outbuf,smb_size);
- set_message(outbuf,15,1 + strlen(rname),True);
-
- CVAL(outbuf,smb_com) = SMBopenX;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,0xFF);
- SSVAL(outbuf,smb_vwv2,1);
- SSVAL(outbuf,smb_vwv3,(DENY_NONE<<4));
- SSVAL(outbuf,smb_vwv4,aSYSTEM | aHIDDEN);
- SSVAL(outbuf,smb_vwv5,aSYSTEM | aHIDDEN);
- SSVAL(outbuf,smb_vwv8,1);
-
- p = smb_buf(outbuf);
- strcpy(p,rname);
- p = skip_string(p,1);
-
- /* do a chained openX with a readX? */
-#if 1
- if (finfo.size > 0)
- {
- DEBUG(3,("Chaining readX wth openX\n"));
- SSVAL(outbuf,smb_vwv0,SMBreadX);
- SSVAL(outbuf,smb_vwv1,smb_offset(p,outbuf));
- bzero(p,200);
- p -= smb_wct;
- SSVAL(p,smb_wct,10);
- SSVAL(p,smb_vwv0,0xFF);
- SSVAL(p,smb_vwv5,MIN(max_xmit-500,finfo.size));
- SSVAL(p,smb_vwv9,MIN(BUFFER_SIZE,finfo.size));
- smb_setlen(outbuf,smb_len(outbuf)+11*2+1);
- }
-#endif
-
- if(!strcmp(lname,"-"))
- handle = fileno(stdout);
- else
- {
- handle = creat(lname,0644);
- newhandle = True;
- }
- if (handle < 0)
- {
- DEBUG(0,("Error opening local file %s\n",lname));
- free(inbuf);free(outbuf);
- return;
- }
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- if (CVAL(inbuf,smb_rcls) == ERRSRV &&
- SVAL(inbuf,smb_err) == ERRnoresource &&
- reopen_connection(inbuf,outbuf))
- {
- do_get(rname,lname,finfo1);
- return;
- }
- DEBUG(0,("%s opening remote file %s\n",smb_errstr(inbuf),CNV_LANG(rname)));
- if(newhandle)
- close(handle);
- free(inbuf);free(outbuf);
- return;
- }
-
- strcpy(finfo.name,rname);
-
- if (!finfo1)
- {
- finfo.mode = SVAL(inbuf,smb_vwv3);
- /* these times arrive as LOCAL time, using the DST offset
- corresponding to that time, we convert them to GMT */
- finfo.mtime = make_unix_date3(inbuf+smb_vwv4);
- finfo.atime = finfo.ctime = finfo.mtime;
- finfo.size = IVAL(inbuf,smb_vwv6);
- }
-
- DEBUG(3,("file %s attrib 0x%X\n",CNV_LANG(finfo.name),finfo.mode));
-
- fnum = SVAL(inbuf,smb_vwv2);
-
- /* we might have got some data from a chained readX */
- if (SVAL(inbuf,smb_vwv0) == SMBreadX)
- {
- p = (smb_base(inbuf)+SVAL(inbuf,smb_vwv1)) - smb_wct;
- datalen = SVAL(p,smb_vwv5);
- dataptr = smb_base(inbuf) + SVAL(p,smb_vwv6);
- }
- else
- {
- dataptr = NULL;
- datalen = 0;
- }
-
-
- DEBUG(2,("getting file %s of size %d bytes as %s ",
- CNV_LANG(finfo.name),
- finfo.size,
- lname));
-
- while (nread < finfo.size && !close_done)
- {
- int method = -1;
- static BOOL can_chain_close = True;
-
- p=NULL;
-
- DEBUG(3,("nread=%d max_xmit=%d fsize=%d\n",nread,max_xmit,finfo.size));
-
- /* 3 possible read types. readbraw if a large block is required.
- readX + close if not much left and read if neither is supported */
-
- /* we might have already read some data from a chained readX */
- if (dataptr && datalen>0)
- method=3;
-
- /* if we can finish now then readX+close */
- if (method<0 && can_chain_close && (Protocol >= PROTOCOL_LANMAN1) &&
- ((finfo.size - nread) <
- (max_xmit - (2*smb_size + 13*SIZEOFWORD + 300))))
- method = 0;
-
- /* if we support readraw then use that */
- if (method<0 && readbraw_supported)
- method = 1;
-
- /* if we can then use readX */
- if (method<0 && (Protocol >= PROTOCOL_LANMAN1))
- method = 2;
-
- switch (method)
- {
- /* use readX */
- case 0:
- case 2:
- if (method == 0)
- close_done = True;
-
- /* use readX + close */
- bzero(outbuf,smb_size);
- set_message(outbuf,10,0,True);
- CVAL(outbuf,smb_com) = SMBreadX;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- if (close_done)
- {
- CVAL(outbuf,smb_vwv0) = SMBclose;
- SSVAL(outbuf,smb_vwv1,smb_offset(smb_buf(outbuf),outbuf));
- }
- else
- CVAL(outbuf,smb_vwv0) = 0xFF;
-
- SSVAL(outbuf,smb_vwv2,fnum);
- SIVAL(outbuf,smb_vwv3,nread);
- SSVAL(outbuf,smb_vwv5,MIN(max_xmit-200,finfo.size - nread));
- SSVAL(outbuf,smb_vwv6,0);
- SIVAL(outbuf,smb_vwv7,0);
- SSVAL(outbuf,smb_vwv9,MIN(BUFFER_SIZE,finfo.size-nread));
-
- if (close_done)
- {
- p = smb_buf(outbuf);
- bzero(p,9);
-
- CVAL(p,0) = 3;
- SSVAL(p,1,fnum);
- SIVALS(p,3,-1);
-
- /* now set the total packet length */
- smb_setlen(outbuf,smb_len(outbuf)+9);
- }
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("Error %s reading remote file\n",smb_errstr(inbuf)));
- break;
- }
-
- if (close_done &&
- SVAL(inbuf,smb_vwv0) != SMBclose)
- {
- /* NOTE: WfWg sometimes just ignores the chained
- command! This seems to break the spec? */
- DEBUG(3,("Rejected chained close?\n"));
- close_done = False;
- can_chain_close = False;
- ignore_close_error = True;
- }
-
- datalen = SVAL(inbuf,smb_vwv5);
- dataptr = smb_base(inbuf) + SVAL(inbuf,smb_vwv6);
- break;
-
- /* use readbraw */
- case 1:
- {
- static int readbraw_size = BUFFER_SIZE;
-
- extern int Client;
- bzero(outbuf,smb_size);
- set_message(outbuf,8,0,True);
- CVAL(outbuf,smb_com) = SMBreadbraw;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
- SSVAL(outbuf,smb_vwv0,fnum);
- SIVAL(outbuf,smb_vwv1,nread);
- SSVAL(outbuf,smb_vwv3,MIN(finfo.size-nread,readbraw_size));
- SSVAL(outbuf,smb_vwv4,0);
- SIVALS(outbuf,smb_vwv5,-1);
- send_smb(Client,outbuf);
-
- /* Now read the raw data into the buffer and write it */
- if(read_smb_length(Client,inbuf,0) == -1) {
- DEBUG(0,("Failed to read length in readbraw\n"));
- exit(1);
- }
-
- /* Even though this is not an smb message, smb_len
- returns the generic length of an smb message */
- datalen = smb_len(inbuf);
-
- if (datalen == 0)
- {
- /* we got a readbraw error */
- DEBUG(4,("readbraw error - reducing size\n"));
- readbraw_size = (readbraw_size * 9) / 10;
-
- if (readbraw_size < max_xmit)
- {
- DEBUG(0,("disabling readbraw\n"));
- readbraw_supported = False;
- }
-
- dataptr=NULL;
- continue;
- }
-
- if(read_data(Client,inbuf,datalen) != datalen) {
- DEBUG(0,("Failed to read data in readbraw\n"));
- exit(1);
- }
- dataptr = inbuf;
- }
- break;
-
- case 3:
- /* we've already read some data with a chained readX */
- break;
-
- default:
- /* use plain read */
- bzero(outbuf,smb_size);
- set_message(outbuf,5,0,True);
- CVAL(outbuf,smb_com) = SMBread;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,fnum);
- SSVAL(outbuf,smb_vwv1,MIN(max_xmit-200,finfo.size - nread));
- SIVAL(outbuf,smb_vwv2,nread);
- SSVAL(outbuf,smb_vwv4,finfo.size - nread);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("Error %s reading remote file\n",smb_errstr(inbuf)));
- break;
- }
-
- datalen = SVAL(inbuf,smb_vwv0);
- dataptr = smb_buf(inbuf) + 3;
- break;
- }
-
- if (writefile(handle,dataptr,datalen) != datalen)
- {
- DEBUG(0,("Error writing local file\n"));
- break;
- }
-
- nread += datalen;
- if (datalen == 0)
- {
- DEBUG(0,("Error reading file %s. Got %d bytes\n",CNV_LANG(rname),nread));
- break;
- }
-
- dataptr=NULL;
- datalen=0;
- }
-
-
-
- if (!close_done)
- {
- bzero(outbuf,smb_size);
- set_message(outbuf,3,0,True);
- CVAL(outbuf,smb_com) = SMBclose;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,fnum);
- SIVALS(outbuf,smb_vwv1,-1);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (!ignore_close_error && CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("Error %s closing remote file\n",smb_errstr(inbuf)));
- if(newhandle)
- close(handle);
- free(inbuf);free(outbuf);
- return;
- }
- }
-
- if(newhandle)
- close(handle);
-
- if (archive_level >= 2 && (finfo.mode & aARCH)) {
- bzero(outbuf,smb_size);
- set_message(outbuf,8,strlen(rname)+4,True);
- CVAL(outbuf,smb_com) = SMBsetatr;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
- SSVAL(outbuf,smb_vwv0,finfo.mode & ~(aARCH));
- SIVALS(outbuf,smb_vwv1,0);
- p = smb_buf(outbuf);
- *p++ = 4;
- strcpy(p,rname);
- p += strlen(p)+1;
- *p++ = 4;
- *p = 0;
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
- }
-
- {
- struct timeval tp_end;
- int this_time;
-
- GetTimeOfDay(&tp_end);
- this_time =
- (tp_end.tv_sec - tp_start.tv_sec)*1000 +
- (tp_end.tv_usec - tp_start.tv_usec)/1000;
- get_total_time_ms += this_time;
- get_total_size += finfo.size;
-
- DEBUG(1,("(%g kb/s) (average %g kb/s)\n",
- finfo.size / (1.024*this_time + 1.0e-4),
- get_total_size / (1.024*get_total_time_ms)));
- }
-
- free(inbuf);free(outbuf);
-}
-
-
-/****************************************************************************
- get a file
- ****************************************************************************/
-static void cmd_get(void)
-{
- pstring lname;
- pstring rname;
- char *p;
-
- strcpy(rname,cur_dir);
- strcat(rname,"\\");
-
- p = rname + strlen(rname);
-
- if (!next_token(NULL,p,NULL)) {
- DEBUG(0,("get <filename>\n"));
- return;
- }
- strcpy(lname,p);
- dos_clean_name(rname);
-
- next_token(NULL,lname,NULL);
-
- do_get(rname,lname,NULL);
-}
-
-
-/****************************************************************************
- do a mget operation on one file
- ****************************************************************************/
-static void do_mget(file_info *finfo)
-{
- pstring rname;
- pstring quest;
-
- if (strequal(finfo->name,".") || strequal(finfo->name,".."))
- return;
-
- if (abort_mget)
- {
- DEBUG(0,("mget aborted\n"));
- return;
- }
-
- if (finfo->mode & aDIR)
- sprintf(quest,"Get directory %s? ",CNV_LANG(finfo->name));
- else
- sprintf(quest,"Get file %s? ",CNV_LANG(finfo->name));
-
- if (prompt && !yesno(quest)) return;
-
- if (finfo->mode & aDIR)
- {
- pstring saved_curdir;
- pstring mget_mask;
- char *inbuf,*outbuf;
-
- inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
- if (!inbuf || !outbuf)
- {
- DEBUG(0,("out of memory\n"));
- return;
- }
-
- strcpy(saved_curdir,cur_dir);
-
- strcat(cur_dir,finfo->name);
- strcat(cur_dir,"\\");
-
- unix_format(finfo->name);
- {
- if (lowercase)
- strlower(finfo->name);
-
- if (!directory_exist(finfo->name,NULL) &&
- sys_mkdir(finfo->name,0777) != 0)
- {
- DEBUG(0,("failed to create directory %s\n",CNV_LANG(finfo->name)));
- strcpy(cur_dir,saved_curdir);
- free(inbuf);free(outbuf);
- return;
- }
-
- if (sys_chdir(finfo->name) != 0)
- {
- DEBUG(0,("failed to chdir to directory %s\n",CNV_LANG(finfo->name)));
- strcpy(cur_dir,saved_curdir);
- free(inbuf);free(outbuf);
- return;
- }
- }
-
- strcpy(mget_mask,cur_dir);
- strcat(mget_mask,"*");
-
- do_dir((char *)inbuf,(char *)outbuf,
- mget_mask,aSYSTEM | aHIDDEN | aDIR,do_mget,False);
- chdir("..");
- strcpy(cur_dir,saved_curdir);
- free(inbuf);free(outbuf);
- }
- else
- {
- strcpy(rname,cur_dir);
- strcat(rname,finfo->name);
- do_get(rname,finfo->name,finfo);
- }
-}
-
-/****************************************************************************
-view the file using the pager
-****************************************************************************/
-static void cmd_more(void)
-{
- fstring rname,lname,tmpname,pager_cmd;
- char *pager;
-
- strcpy(rname,cur_dir);
- strcat(rname,"\\");
- sprintf(tmpname,"%s/smbmore.%d",tmpdir(),(int)getpid());
- strcpy(lname,tmpname);
-
- if (!next_token(NULL,rname+strlen(rname),NULL)) {
- DEBUG(0,("more <filename>\n"));
- return;
- }
- dos_clean_name(rname);
-
- do_get(rname,lname,NULL);
-
- pager=getenv("PAGER");
- sprintf(pager_cmd,"%s %s",(pager? pager:PAGER), tmpname);
- system(pager_cmd);
- unlink(tmpname);
-}
-
-
-
-/****************************************************************************
-do a mget command
-****************************************************************************/
-static void cmd_mget(char *inbuf,char *outbuf)
-{
- int attribute = aSYSTEM | aHIDDEN;
- pstring mget_mask;
- fstring buf;
- char *p=buf;
-
- *mget_mask = 0;
-
- if (recurse)
- attribute |= aDIR;
-
- abort_mget = False;
-
- while (next_token(NULL,p,NULL))
- {
- strcpy(mget_mask,cur_dir);
- if(mget_mask[strlen(mget_mask)-1]!='\\')
- strcat(mget_mask,"\\");
-
- if (*p == '\\')
- strcpy(mget_mask,p);
- else
- strcat(mget_mask,p);
- do_dir((char *)inbuf,(char *)outbuf,mget_mask,attribute,do_mget,False);
- }
-
- if (! *mget_mask)
- {
- strcpy(mget_mask,cur_dir);
- if(mget_mask[strlen(mget_mask)-1]!='\\')
- strcat(mget_mask,"\\");
- strcat(mget_mask,"*");
- do_dir((char *)inbuf,(char *)outbuf,mget_mask,attribute,do_mget,False);
- }
-}
-
-/****************************************************************************
-make a directory of name "name"
-****************************************************************************/
-static BOOL do_mkdir(char *name)
-{
- char *p;
- char *inbuf,*outbuf;
-
- inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
- if (!inbuf || !outbuf)
- {
- DEBUG(0,("out of memory\n"));
- return False;
- }
-
- bzero(outbuf,smb_size);
- set_message(outbuf,0,2 + strlen(name),True);
-
- CVAL(outbuf,smb_com) = SMBmkdir;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
-
- p = smb_buf(outbuf);
- *p++ = 4;
- strcpy(p,name);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("%s making remote directory %s\n",
- smb_errstr(inbuf),CNV_LANG(name)));
-
- free(inbuf);free(outbuf);
- return(False);
- }
-
- free(inbuf);free(outbuf);
- return(True);
-}
-
-
-/****************************************************************************
- make a directory
- ****************************************************************************/
-static void cmd_mkdir(char *inbuf,char *outbuf)
-{
- pstring mask;
- fstring buf;
- char *p=buf;
-
- strcpy(mask,cur_dir);
-
- if (!next_token(NULL,p,NULL))
- {
- if (!recurse)
- DEBUG(0,("mkdir <dirname>\n"));
- return;
- }
- strcat(mask,p);
-
- if (recurse)
- {
- pstring ddir;
- pstring ddir2;
- *ddir2 = 0;
-
- strcpy(ddir,mask);
- trim_string(ddir,".",NULL);
- p = strtok(ddir,"/\\");
- while (p)
- {
- strcat(ddir2,p);
- if (!chkpath(ddir2,False))
- {
- do_mkdir(ddir2);
- }
- strcat(ddir2,"\\");
- p = strtok(NULL,"/\\");
- }
- }
- else
- do_mkdir(mask);
-}
-
-
-/*******************************************************************
- write to a file using writebraw
- ********************************************************************/
-static int smb_writeraw(char *outbuf,int fnum,int pos,char *buf,int n)
-{
- extern int Client;
- pstring inbuf;
-
- bzero(outbuf,smb_size);
- bzero(inbuf,smb_size);
- set_message(outbuf,Protocol>PROTOCOL_COREPLUS?12:10,0,True);
-
- CVAL(outbuf,smb_com) = SMBwritebraw;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,fnum);
- SSVAL(outbuf,smb_vwv1,n);
- SIVAL(outbuf,smb_vwv3,pos);
- SSVAL(outbuf,smb_vwv7,1);
-
- send_smb(Client,outbuf);
-
- if (!receive_smb(Client,inbuf,CLIENT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
- return(0);
-
- _smb_setlen(buf-4,n); /* HACK! XXXX */
-
- if (write_socket(Client,buf-4,n+4) != n+4)
- return(0);
-
- if (!receive_smb(Client,inbuf,CLIENT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0) {
- DEBUG(0,("Error writing remote file (2)\n"));
- return(0);
- }
- return(SVAL(inbuf,smb_vwv0));
-}
-
-
-
-/*******************************************************************
- write to a file
- ********************************************************************/
-static int smb_writefile(char *outbuf,int fnum,int pos,char *buf,int n)
-{
- pstring inbuf;
-
- if (writebraw_supported && n > (max_xmit-200))
- return(smb_writeraw(outbuf,fnum,pos,buf,n));
-
- bzero(outbuf,smb_size);
- bzero(inbuf,smb_size);
- set_message(outbuf,5,n + 3,True);
-
- CVAL(outbuf,smb_com) = SMBwrite;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,fnum);
- SSVAL(outbuf,smb_vwv1,n);
- SIVAL(outbuf,smb_vwv2,pos);
- SSVAL(outbuf,smb_vwv4,0);
- CVAL(smb_buf(outbuf),0) = 1;
- SSVAL(smb_buf(outbuf),1,n);
-
- memcpy(smb_buf(outbuf)+3,buf,n);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0) {
- DEBUG(0,("%s writing remote file\n",smb_errstr(inbuf)));
- return(0);
- }
- return(SVAL(inbuf,smb_vwv0));
-}
-
-
-
-/****************************************************************************
- put a single file
- ****************************************************************************/
-static void do_put(char *rname,char *lname,file_info *finfo)
-{
- int fnum;
- FILE *f;
- int nread=0;
- char *p;
- char *inbuf,*outbuf;
- time_t close_time = finfo->mtime;
- char *buf=NULL;
- static int maxwrite=0;
-
- struct timeval tp_start;
- GetTimeOfDay(&tp_start);
-
- inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
- if (!inbuf || !outbuf)
- {
- DEBUG(0,("out of memory\n"));
- return;
- }
-
- bzero(outbuf,smb_size);
- set_message(outbuf,3,2 + strlen(rname),True);
-
- if (finfo->mtime == 0 || finfo->mtime == -1)
- finfo->mtime = finfo->atime = finfo->ctime = time(NULL);
-
- CVAL(outbuf,smb_com) = SMBcreate;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,finfo->mode);
- put_dos_date3(outbuf,smb_vwv1,finfo->mtime);
-
- p = smb_buf(outbuf);
- *p++ = 4;
- strcpy(p,rname);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("%s opening remote file %s\n",smb_errstr(inbuf),CNV_LANG(rname)));
-
- free(inbuf);free(outbuf);if (buf) free(buf);
- return;
- }
-
- f = fopen(lname,"r");
-
- if (!f)
- {
- DEBUG(0,("Error opening local file %s\n",lname));
- free(inbuf);free(outbuf);
- return;
- }
-
-
- fnum = SVAL(inbuf,smb_vwv0);
- if (finfo->size < 0)
- finfo->size = file_size(lname);
-
- DEBUG(1,("putting file %s of size %d bytes as %s ",lname,finfo->size,CNV_LANG(rname)));
-
- if (!maxwrite)
- maxwrite = writebraw_supported?MAX(max_xmit,BUFFER_SIZE):(max_xmit-200);
-
- while (nread < finfo->size)
- {
- int n = maxwrite;
- int ret;
-
- n = MIN(n,finfo->size - nread);
-
- buf = (char *)Realloc(buf,n+4);
-
- fseek(f,nread,SEEK_SET);
- if ((n = readfile(buf+4,1,n,f)) < 1)
- {
- DEBUG(0,("Error reading local file\n"));
- break;
- }
-
- ret = smb_writefile(outbuf,fnum,nread,buf+4,n);
-
- if (n != ret) {
- if (!maxwrite) {
- DEBUG(0,("Error writing file\n"));
- break;
- } else {
- maxwrite /= 2;
- continue;
- }
- }
-
- nread += n;
- }
-
-
-
- bzero(outbuf,smb_size);
- set_message(outbuf,3,0,True);
- CVAL(outbuf,smb_com) = SMBclose;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,fnum);
- put_dos_date3(outbuf,smb_vwv1,close_time);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("%s closing remote file %s\n",smb_errstr(inbuf),CNV_LANG(rname)));
- fclose(f);
- free(inbuf);free(outbuf);
- if (buf) free(buf);
- return;
- }
-
-
- fclose(f);
- free(inbuf);free(outbuf);
- if (buf) free(buf);
-
- {
- struct timeval tp_end;
- int this_time;
-
- GetTimeOfDay(&tp_end);
- this_time =
- (tp_end.tv_sec - tp_start.tv_sec)*1000 +
- (tp_end.tv_usec - tp_start.tv_usec)/1000;
- put_total_time_ms += this_time;
- put_total_size += finfo->size;
-
- DEBUG(1,("(%g kb/s) (average %g kb/s)\n",
- finfo->size / (1.024*this_time + 1.0e-4),
- put_total_size / (1.024*put_total_time_ms)));
- }
-}
-
-
-
-/****************************************************************************
- put a file
- ****************************************************************************/
-static void cmd_put(void)
-{
- pstring lname;
- pstring rname;
- fstring buf;
- char *p=buf;
- file_info finfo;
- finfo = def_finfo;
-
- strcpy(rname,cur_dir);
- strcat(rname,"\\");
-
-
- if (!next_token(NULL,p,NULL))
- {
- DEBUG(0,("put <filename>\n"));
- return;
- }
- strcpy(lname,p);
-
- if (next_token(NULL,p,NULL))
- strcat(rname,p);
- else
- strcat(rname,lname);
-
- dos_clean_name(rname);
-
- {
- struct stat st;
- if (!file_exist(lname,&st)) {
- DEBUG(0,("%s does not exist\n",lname));
- return;
- }
- finfo.mtime = st.st_mtime;
- }
-
- do_put(rname,lname,&finfo);
-}
-
-/****************************************************************************
- seek in a directory/file list until you get something that doesn't start with
- the specified name
- ****************************************************************************/
-static BOOL seek_list(FILE *f,char *name)
-{
- pstring s;
- while (!feof(f))
- {
- if (fscanf(f,"%s",s) != 1) return(False);
- trim_string(s,"./",NULL);
- if (strncmp(s,name,strlen(name)) != 0)
- {
- strcpy(name,s);
- return(True);
- }
- }
-
- return(False);
-}
-
-
-/****************************************************************************
- set the file selection mask
- ****************************************************************************/
-static void cmd_select(void)
-{
- strcpy(fileselection,"");
- next_token(NULL,fileselection,NULL);
-}
-
-
-/****************************************************************************
- mput some files
- ****************************************************************************/
-static void cmd_mput(void)
-{
- pstring lname;
- pstring rname;
- file_info finfo;
- fstring buf;
- char *p=buf;
-
- finfo = def_finfo;
-
-
- while (next_token(NULL,p,NULL))
- {
- struct stat st;
- pstring cmd;
- pstring tmpname;
- FILE *f;
-
- sprintf(tmpname,"%s/ls.smb.%d",tmpdir(),(int)getpid());
- if (recurse)
- sprintf(cmd,"find . -name \"%s\" -print > %s",p,tmpname);
- else
- sprintf(cmd,"/bin/ls %s > %s",p,tmpname);
- system(cmd);
-
- f = fopen(tmpname,"r");
- if (!f) continue;
-
- while (!feof(f))
- {
- pstring quest;
-
- if (fscanf(f,"%s",lname) != 1) break;
- trim_string(lname,"./",NULL);
-
- again1:
-
- /* check if it's a directory */
- if (directory_exist(lname,&st))
- {
- if (!recurse) continue;
- sprintf(quest,"Put directory %s? ",lname);
- if (prompt && !yesno(quest))
- {
- strcat(lname,"/");
- if (!seek_list(f,lname))
- break;
- goto again1;
- }
-
- strcpy(rname,cur_dir);
- strcat(rname,lname);
- if (!chkpath(rname,False) && !do_mkdir(rname)) {
- strcat(lname,"/");
- if (!seek_list(f,lname))
- break;
- goto again1;
- }
-
- continue;
- }
- else
- {
- sprintf(quest,"Put file %s? ",lname);
- if (prompt && !yesno(quest)) continue;
-
- strcpy(rname,cur_dir);
- strcat(rname,lname);
- }
- dos_format(rname);
-
- /* null size so do_put knows to ignore it */
- finfo.size = -1;
-
- /* set the date on the file */
- finfo.mtime = st.st_mtime;
-
- do_put(rname,lname,&finfo);
- }
- fclose(f);
- unlink(tmpname);
- }
-}
-
-/****************************************************************************
- cancel a print job
- ****************************************************************************/
-static void do_cancel(int job)
-{
- char *rparam = NULL;
- char *rdata = NULL;
- char *p;
- int rdrcnt,rprcnt;
- pstring param;
-
- bzero(param,sizeof(param));
-
- p = param;
- SSVAL(p,0,81); /* DosPrintJobDel() */
- p += 2;
- strcpy(p,"W");
- p = skip_string(p,1);
- strcpy(p,"");
- p = skip_string(p,1);
- SSVAL(p,0,job);
- p += 2;
-
- if (call_api(PTR_DIFF(p,param),0,
- 6,1000,
- &rprcnt,&rdrcnt,
- param,NULL,
- &rparam,&rdata))
- {
- int res = SVAL(rparam,0);
-
- if (!res)
- printf("Job %d cancelled\n",job);
- else
- printf("Error %d calcelling job %d\n",res,job);
- return;
- }
- else
- printf("Server refused cancel request\n");
-
- if (rparam) free(rparam);
- if (rdata) free(rdata);
-
- return;
-}
-
-
-/****************************************************************************
- cancel a print job
- ****************************************************************************/
-static void cmd_cancel(char *inbuf,char *outbuf )
-{
- fstring buf;
- int job;
-
- if (!connect_as_printer)
- {
- DEBUG(0,("WARNING: You didn't use the -P option to smbclient.\n"));
- DEBUG(0,("Trying to cancel print jobs without -P may fail\n"));
- }
-
- if (!next_token(NULL,buf,NULL)) {
- printf("cancel <jobid> ...\n");
- return;
- }
- do {
- job = atoi(buf);
- do_cancel(job);
- } while (next_token(NULL,buf,NULL));
-}
-
-
-/****************************************************************************
- get info on a file
- ****************************************************************************/
-static void cmd_stat(char *inbuf,char *outbuf)
-{
- fstring buf;
- pstring param;
- char *resp_data=NULL;
- char *resp_param=NULL;
- int resp_data_len = 0;
- int resp_param_len=0;
- char *p;
- uint16 setup = TRANSACT2_QPATHINFO;
-
- if (!next_token(NULL,buf,NULL)) {
- printf("stat <file>\n");
- return;
- }
-
- bzero(param,6);
- SSVAL(param,0,4); /* level */
- p = param+6;
- strcpy(p,cur_dir);
- strcat(p,buf);
-
- send_trans_request(outbuf,SMBtrans2,NULL,FID_UNUSED,0,
- NULL,param,&setup,
- 0,6 + strlen(p)+1,1,
- BUFFER_SIZE,2,0);
-
- receive_trans_response(inbuf,SMBtrans2,
- &resp_data_len,&resp_param_len,
- &resp_data,&resp_param);
-
- if (resp_data) free(resp_data); resp_data = NULL;
- if (resp_param) free(resp_param); resp_param = NULL;
-}
-
-
-/****************************************************************************
- print a file
- ****************************************************************************/
-static void cmd_print(char *inbuf,char *outbuf )
-{
- int fnum;
- FILE *f = NULL;
- uint32 nread=0;
- pstring lname;
- pstring rname;
- char *p;
-
- if (!connect_as_printer)
- {
- DEBUG(0,("WARNING: You didn't use the -P option to smbclient.\n"));
- DEBUG(0,("Trying to print without -P may fail\n"));
- }
-
- if (!next_token(NULL,lname,NULL))
- {
- DEBUG(0,("print <filename>\n"));
- return;
- }
-
- strcpy(rname,lname);
- p = strrchr(rname,'/');
- if (p)
- {
- pstring tname;
- strcpy(tname,p+1);
- strcpy(rname,tname);
- }
-
- if ((int)strlen(rname) > 14)
- rname[14] = 0;
-
- if (strequal(lname,"-"))
- {
- f = stdin;
- strcpy(rname,"stdin");
- }
-
- dos_clean_name(rname);
-
- bzero(outbuf,smb_size);
- set_message(outbuf,2,2 + strlen(rname),True);
-
- CVAL(outbuf,smb_com) = SMBsplopen;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,0);
- SSVAL(outbuf,smb_vwv1,printmode);
-
- p = smb_buf(outbuf);
- *p++ = 4;
- strcpy(p,rname);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("%s opening printer for %s\n",smb_errstr(inbuf),CNV_LANG(rname)));
- return;
- }
-
- if (!f)
- f = fopen(lname,"r");
- if (!f)
- {
- DEBUG(0,("Error opening local file %s\n",lname));
- return;
- }
-
-
- fnum = SVAL(inbuf,smb_vwv0);
-
- DEBUG(1,("printing file %s as %s\n",lname,CNV_LANG(rname)));
-
- while (!feof(f))
- {
- int n;
-
- bzero(outbuf,smb_size);
- set_message(outbuf,1,3,True);
-
- /* for some strange reason the OS/2 print server can't handle large
- packets when printing. weird */
- n = MIN(1024,max_xmit-(smb_len(outbuf)+4));
-
- if (translation)
- n = printread(f,smb_buf(outbuf)+3,(int)(0.95*n));
- else
- n = readfile(smb_buf(outbuf)+3,1,n,f);
- if (n <= 0)
- {
- DEBUG(0,("read gave %d\n",n));
- break;
- }
-
- smb_setlen(outbuf,smb_len(outbuf) + n);
-
- CVAL(outbuf,smb_com) = SMBsplwr;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,fnum);
- SSVAL(outbuf,smb_vwv1,n+3);
- CVAL(smb_buf(outbuf),0) = 1;
- SSVAL(smb_buf(outbuf),1,n);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("%s printing remote file\n",smb_errstr(inbuf)));
- break;
- }
-
- nread += n;
- }
-
- DEBUG(2,("%d bytes printed\n",nread));
-
- bzero(outbuf,smb_size);
- set_message(outbuf,1,0,True);
- CVAL(outbuf,smb_com) = SMBsplclose;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,fnum);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("%s closing print file\n",smb_errstr(inbuf)));
- if (f != stdin)
- fclose(f);
- return;
- }
-
- if (f != stdin)
- fclose(f);
-}
-
-/****************************************************************************
-show a print queue - this is deprecated as it uses the old smb that
-has limited support - the correct call is the cmd_p_queue_4() after this.
-****************************************************************************/
-static void cmd_queue(char *inbuf,char *outbuf )
-{
- int count;
- char *p;
-
- bzero(outbuf,smb_size);
- set_message(outbuf,2,0,True);
-
- CVAL(outbuf,smb_com) = SMBsplretq;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,32); /* a max of 20 entries is to be shown */
- SSVAL(outbuf,smb_vwv1,0); /* the index into the queue */
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("%s obtaining print queue\n",smb_errstr(inbuf)));
- return;
- }
-
- count = SVAL(inbuf,smb_vwv0);
- p = smb_buf(inbuf) + 3;
- if (count <= 0)
- {
- DEBUG(0,("No entries in the print queue\n"));
- return;
- }
-
- {
- char status[20];
-
- DEBUG(0,("Job Name Size Status\n"));
-
- while (count--)
- {
- switch (CVAL(p,4))
- {
- case 0x01: sprintf(status,"held or stopped"); break;
- case 0x02: sprintf(status,"printing"); break;
- case 0x03: sprintf(status,"awaiting print"); break;
- case 0x04: sprintf(status,"in intercept"); break;
- case 0x05: sprintf(status,"file had error"); break;
- case 0x06: sprintf(status,"printer error"); break;
- default: sprintf(status,"unknown"); break;
- }
-
- DEBUG(0,("%-6d %-16.16s %-9d %s\n",
- SVAL(p,5),p+12,IVAL(p,7),status));
- p += 28;
- }
- }
-
-}
-
-
-/****************************************************************************
-show information about a print queue
-****************************************************************************/
-static void cmd_p_queue_4(char *inbuf,char *outbuf )
-{
- char *rparam = NULL;
- char *rdata = NULL;
- char *p;
- int rdrcnt, rprcnt;
- pstring param;
- int result_code=0;
-
- if (!connect_as_printer)
- {
- DEBUG(0,("WARNING: You didn't use the -P option to smbclient.\n"));
- DEBUG(0,("Trying to print without -P may fail\n"));
- }
-
- bzero(param,sizeof(param));
-
- p = param;
- SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */
- p += 2;
- strcpy(p,"zWrLeh"); /* parameter description? */
- p = skip_string(p,1);
- strcpy(p,"WWzWWDDzz"); /* returned data format */
- p = skip_string(p,1);
- strcpy(p,strrchr(service,'\\')+1); /* name of queue */
- p = skip_string(p,1);
- SSVAL(p,0,2); /* API function level 2, PRJINFO_2 data structure */
- SSVAL(p,2,1000); /* size of bytes of returned data buffer */
- p += 4;
- strcpy(p,""); /* subformat */
- p = skip_string(p,1);
-
- DEBUG(1,("Calling DosPrintJobEnum()...\n"));
- if( call_api(PTR_DIFF(p,param), 0,
- 10, 4096,
- &rprcnt, &rdrcnt,
- param, NULL,
- &rparam, &rdata) )
- {
- int converter;
- result_code = SVAL(rparam,0);
- converter = SVAL(rparam,2); /* conversion factor */
-
- DEBUG(2,("returned %d bytes of parameters, %d bytes of data, %d records\n", rprcnt, rdrcnt, SVAL(rparam,4) ));
-
- if (result_code == 0) /* if no error, */
- {
- int i;
- uint16 JobId;
- uint16 Priority;
- uint32 Size;
- char *UserName;
- char *JobName;
- char *JobTimeStr;
- time_t JobTime;
- char PrinterName[20];
-
- strcpy(PrinterName,strrchr(service,'\\')+1); /* name of queue */
- strlower(PrinterName); /* in lower case */
-
- p = rdata; /* received data */
- for( i = 0; i < SVAL(rparam,4); ++i)
- {
- JobId = SVAL(p,0);
- Priority = SVAL(p,2);
- UserName = fix_char_ptr(SVAL(p,4), converter, rdata, rdrcnt);
- strlower(UserName);
- Priority = SVAL(p,2);
- JobTime = make_unix_date3( p + 12);
- JobTimeStr = asctime(LocalTime( &JobTime));
- Size = IVAL(p,16);
- JobName = fix_char_ptr(SVAL(p,24), converter, rdata, rdrcnt);
-
-
- printf("%s-%u %s priority %u %s %s %u bytes\n",
- PrinterName, JobId, UserName,
- Priority, JobTimeStr, JobName, Size);
-
-#if 0 /* DEBUG code */
- printf("Job Id: \"%u\"\n", SVAL(p,0));
- printf("Priority: \"%u\"\n", SVAL(p,2));
-
- printf("User Name: \"%s\"\n", fix_char_ptr(SVAL(p,4), converter, rdata, rdrcnt) );
- printf("Position: \"%u\"\n", SVAL(p,8));
- printf("Status: \"%u\"\n", SVAL(p,10));
-
- JobTime = make_unix_date3( p + 12);
- printf("Submitted: \"%s\"\n", asctime(LocalTime(&JobTime)));
- printf("date: \"%u\"\n", SVAL(p,12));
-
- printf("Size: \"%u\"\n", SVAL(p,16));
- printf("Comment: \"%s\"\n", fix_char_ptr(SVAL(p,20), converter, rdata, rdrcnt) );
- printf("Document: \"%s\"\n", fix_char_ptr(SVAL(p,24), converter, rdata, rdrcnt) );
-#endif /* DEBUG CODE */
- p += 28;
- }
- }
- }
- else /* call_api() failed */
- {
- printf("Failed, error = %d\n", result_code);
- }
-
- /* If any parameters or data were returned, free the storage. */
- if(rparam) free(rparam);
- if(rdata) free(rdata);
-
- return;
-}
-
-/****************************************************************************
-show information about a print queue
-****************************************************************************/
-static void cmd_qinfo(char *inbuf,char *outbuf )
-{
- char *rparam = NULL;
- char *rdata = NULL;
- char *p;
- int rdrcnt, rprcnt;
- pstring param;
- int result_code=0;
-
- bzero(param,sizeof(param));
-
- p = param;
- SSVAL(p,0,70); /* API function number 70 (DosPrintQGetInfo) */
- p += 2;
- strcpy(p,"zWrLh"); /* parameter description? */
- p = skip_string(p,1);
- strcpy(p,"zWWWWzzzzWWzzl"); /* returned data format */
- p = skip_string(p,1);
- strcpy(p,strrchr(service,'\\')+1); /* name of queue */
- p = skip_string(p,1);
- SSVAL(p,0,3); /* API function level 3, just queue info, no job info */
- SSVAL(p,2,1000); /* size of bytes of returned data buffer */
- p += 4;
- strcpy(p,""); /* subformat */
- p = skip_string(p,1);
-
- DEBUG(1,("Calling DosPrintQueueGetInfo()...\n"));
- if( call_api(PTR_DIFF(p,param), 0,
- 10, 4096,
- &rprcnt, &rdrcnt,
- param, NULL,
- &rparam, &rdata) )
- {
- int converter;
- result_code = SVAL(rparam,0);
- converter = SVAL(rparam,2); /* conversion factor */
-
- DEBUG(2,("returned %d bytes of parameters, %d bytes of data, %d records\n", rprcnt, rdrcnt, SVAL(rparam,4) ));
-
- if (result_code == 0) /* if no error, */
- {
- p = rdata; /* received data */
-
- printf("Name: \"%s\"\n", fix_char_ptr(SVAL(p,0), converter, rdata, rdrcnt) );
- printf("Priority: %u\n", SVAL(p,4) );
- printf("Start time: %u\n", SVAL(p,6) );
- printf("Until time: %u\n", SVAL(p,8) );
- printf("Seperator file: \"%s\"\n", fix_char_ptr(SVAL(p,12), converter, rdata, rdrcnt) );
- printf("Print processor: \"%s\"\n", fix_char_ptr(SVAL(p,16), converter, rdata, rdrcnt) );
- printf("Parameters: \"%s\"\n", fix_char_ptr(SVAL(p,20), converter, rdata, rdrcnt) );
- printf("Comment: \"%s\"\n", fix_char_ptr(SVAL(p,24), converter, rdata, rdrcnt) );
- printf("Status: %u\n", SVAL(p,28) );
- printf("Jobs: %u\n", SVAL(p,30) );
- printf("Printers: \"%s\"\n", fix_char_ptr(SVAL(p,32), converter, rdata, rdrcnt) );
- printf("Drivername: \"%s\"\n", fix_char_ptr(SVAL(p,36), converter, rdata, rdrcnt) );
-
- /* Dump the driver data */
- {
- int count, x, y, c;
- char *ddptr;
-
- ddptr = rdata + SVAL(p,40) - converter;
- if( SVAL(p,40) == 0 ) {count = 0;} else {count = IVAL(ddptr,0);}
- printf("Driverdata: size=%d, version=%u\n", count, IVAL(ddptr,4) );
-
- for(x=8; x < count; x+=16)
- {
- for(y=0; y < 16; y++)
- {
- if( (x+y) < count )
- printf("%2.2X ", CVAL(ddptr,(x+y)) );
- else
- fputs(" ", stdout);
- }
- for(y=0; y < 16 && (x+y) < count; y++)
- {
- c = CVAL(ddptr,(x+y));
- if(isprint(c))
- fputc(c, stdout);
- else
- fputc('.', stdout);
- }
- fputc('\n', stdout);
- }
- }
-
- }
- }
- else /* call_api() failed */
- {
- printf("Failed, error = %d\n", result_code);
- }
-
- /* If any parameters or data were returned, free the storage. */
- if(rparam) free(rparam);
- if(rdata) free(rdata);
-
- return;
-}
-
-/****************************************************************************
-delete some files
-****************************************************************************/
-static void do_del(file_info *finfo)
-{
- char *p;
- char *inbuf,*outbuf;
- pstring mask;
-
- strcpy(mask,cur_dir);
- strcat(mask,finfo->name);
-
- if (finfo->mode & aDIR)
- return;
-
- inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
- if (!inbuf || !outbuf)
- {
- DEBUG(0,("out of memory\n"));
- return;
- }
-
- bzero(outbuf,smb_size);
- set_message(outbuf,1,2 + strlen(mask),True);
-
- CVAL(outbuf,smb_com) = SMBunlink;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,0);
-
- p = smb_buf(outbuf);
- *p++ = 4;
- strcpy(p,mask);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- DEBUG(0,("%s deleting remote file %s\n",smb_errstr(inbuf),CNV_LANG(mask)));
-
- free(inbuf);free(outbuf);
-
-}
-
-/****************************************************************************
-delete some files
-****************************************************************************/
-static void cmd_del(char *inbuf,char *outbuf )
-{
- pstring mask;
- fstring buf;
- int attribute = aSYSTEM | aHIDDEN;
-
- if (recurse)
- attribute |= aDIR;
-
- strcpy(mask,cur_dir);
-
- if (!next_token(NULL,buf,NULL))
- {
- DEBUG(0,("del <filename>\n"));
- return;
- }
- strcat(mask,buf);
-
- do_dir((char *)inbuf,(char *)outbuf,mask,attribute,do_del,False);
-}
-
-
-/****************************************************************************
-remove a directory
-****************************************************************************/
-static void cmd_rmdir(char *inbuf,char *outbuf )
-{
- pstring mask;
- fstring buf;
- char *p;
-
- strcpy(mask,cur_dir);
-
- if (!next_token(NULL,buf,NULL))
- {
- DEBUG(0,("rmdir <dirname>\n"));
- return;
- }
- strcat(mask,buf);
-
- bzero(outbuf,smb_size);
- set_message(outbuf,0,2 + strlen(mask),True);
-
- CVAL(outbuf,smb_com) = SMBrmdir;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
-
- p = smb_buf(outbuf);
- *p++ = 4;
- strcpy(p,mask);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("%s removing remote directory file %s\n",smb_errstr(inbuf),CNV_LANG(mask)));
- return;
- }
-
-}
-
-/****************************************************************************
-rename some files
-****************************************************************************/
-static void cmd_rename(char *inbuf,char *outbuf )
-{
- pstring src,dest;
- fstring buf,buf2;
- char *p;
-
- strcpy(src,cur_dir);
- strcpy(dest,cur_dir);
-
- if (!next_token(NULL,buf,NULL) || !next_token(NULL,buf2,NULL))
- {
- DEBUG(0,("rename <src> <dest>\n"));
- return;
- }
- strcat(src,buf);
- strcat(dest,buf2);
-
- bzero(outbuf,smb_size);
- set_message(outbuf,1,4 + strlen(src) + strlen(dest),True);
-
- CVAL(outbuf,smb_com) = SMBmv;
- SSVAL(outbuf,smb_tid,cnum);
- SSVAL(outbuf,smb_vwv0,aHIDDEN | aDIR | aSYSTEM);
- setup_pkt(outbuf);
-
- p = smb_buf(outbuf);
- *p++ = 4;
- strcpy(p,src);
- p = skip_string(p,1);
- *p++ = 4;
- strcpy(p,dest);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("%s renaming files\n",smb_errstr(inbuf)));
- return;
- }
-
-}
-
-
-/****************************************************************************
-toggle the prompt flag
-****************************************************************************/
-static void cmd_prompt(void)
-{
- prompt = !prompt;
- DEBUG(2,("prompting is now %s\n",prompt?"on":"off"));
-}
-
-
-/****************************************************************************
-set the newer than time
-****************************************************************************/
-static void cmd_newer(void)
-{
- fstring buf;
- BOOL ok;
- struct stat sbuf;
-
- ok = next_token(NULL,buf,NULL);
- if (ok && (sys_stat(buf,&sbuf) == 0))
- {
- newer_than = sbuf.st_mtime;
- DEBUG(1,("Getting files newer than %s",
- asctime(LocalTime(&newer_than))));
- }
- else
- newer_than = 0;
-
- if (ok && newer_than == 0)
- DEBUG(0,("Error setting newer-than time\n"));
-}
-
-/****************************************************************************
-set the archive level
-****************************************************************************/
-static void cmd_archive(void)
-{
- fstring buf;
-
- if (next_token(NULL,buf,NULL)) {
- archive_level = atoi(buf);
- } else
- DEBUG(0,("Archive level is %d\n",archive_level));
-}
-
-/****************************************************************************
-toggle the lowercaseflag
-****************************************************************************/
-static void cmd_lowercase(void)
-{
- lowercase = !lowercase;
- DEBUG(2,("filename lowercasing is now %s\n",lowercase?"on":"off"));
-}
-
-
-
-
-/****************************************************************************
-toggle the recurse flag
-****************************************************************************/
-static void cmd_recurse(void)
-{
- recurse = !recurse;
- DEBUG(2,("directory recursion is now %s\n",recurse?"on":"off"));
-}
-
-/****************************************************************************
-toggle the translate flag
-****************************************************************************/
-static void cmd_translate(void)
-{
- translation = !translation;
- DEBUG(2,("CR/LF<->LF and print text translation now %s\n",
- translation?"on":"off"));
-}
-
-
-/****************************************************************************
-do a printmode command
-****************************************************************************/
-static void cmd_printmode(void)
-{
- fstring buf;
- fstring mode;
-
- if (next_token(NULL,buf,NULL))
- {
- if (strequal(buf,"text"))
- printmode = 0;
- else
- {
- if (strequal(buf,"graphics"))
- printmode = 1;
- else
- printmode = atoi(buf);
- }
- }
-
- switch(printmode)
- {
- case 0:
- strcpy(mode,"text");
- break;
- case 1:
- strcpy(mode,"graphics");
- break;
- default:
- sprintf(mode,"%d",printmode);
- break;
- }
-
- DEBUG(2,("the printmode is now %s\n",mode));
-}
-
-/****************************************************************************
-do the lcd command
-****************************************************************************/
-static void cmd_lcd(void)
-{
- fstring buf;
- pstring d;
-
- if (next_token(NULL,buf,NULL))
- sys_chdir(buf);
- DEBUG(2,("the local directory is now %s\n",GetWd(d)));
-}
-
-
-/****************************************************************************
-send a session request
-****************************************************************************/
-static BOOL send_session_request(char *inbuf,char *outbuf)
-{
- fstring dest;
- char *p;
- int len = 4;
- /* send a session request (RFC 8002) */
-
- strcpy(dest,desthost);
- p = strchr(dest,'.');
- if (p) *p = 0;
-
- /* put in the destination name */
- p = outbuf+len;
- name_mangle(dest,p,name_type); /* 0x20 is the SMB server NetBIOS type. */
- len += name_len(p);
-
- /* and my name */
- p = outbuf+len;
- name_mangle(myname,p,0);
- len += name_len(p);
-
- /* setup the packet length */
- _smb_setlen(outbuf,len);
- CVAL(outbuf,0) = 0x81;
-
- send_smb(Client,outbuf);
- DEBUG(5,("Sent session request\n"));
-
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,0) == 0x84) /* C. Hoch 9/14/95 Start */
- {
- /* For information, here is the response structure.
- * We do the byte-twiddling to for portability.
- struct RetargetResponse{
- unsigned char type;
- unsigned char flags;
- int16 length;
- int32 ip_addr;
- int16 port;
- };
- */
- extern int Client;
- int port = (CVAL(inbuf,8)<<8)+CVAL(inbuf,9);
- /* SESSION RETARGET */
- putip((char *)&dest_ip,inbuf+4);
-
- close_sockets();
- Client = open_socket_out(SOCK_STREAM, &dest_ip, port, LONG_CONNECT_TIMEOUT);
- if (Client == -1)
- return False;
-
- DEBUG(3,("Retargeted\n"));
-
- set_socket_options(Client,user_socket_options);
-
- /* Try again */
- return send_session_request(inbuf,outbuf);
- } /* C. Hoch 9/14/95 End */
-
-
- if (CVAL(inbuf,0) != 0x82)
- {
- int ecode = CVAL(inbuf,4);
- DEBUG(0,("Session request failed (%d,%d) with myname=%s destname=%s\n",
- CVAL(inbuf,0),ecode,myname,desthost));
- switch (ecode)
- {
- case 0x80:
- DEBUG(0,("Not listening on called name\n"));
- DEBUG(0,("Try to connect to another name (instead of %s)\n",desthost));
- DEBUG(0,("You may find the -I option useful for this\n"));
- break;
- case 0x81:
- DEBUG(0,("Not listening for calling name\n"));
- DEBUG(0,("Try to connect as another name (instead of %s)\n",myname));
- DEBUG(0,("You may find the -n option useful for this\n"));
- break;
- case 0x82:
- DEBUG(0,("Called name not present\n"));
- DEBUG(0,("Try to connect to another name (instead of %s)\n",desthost));
- DEBUG(0,("You may find the -I option useful for this\n"));
- break;
- case 0x83:
- DEBUG(0,("Called name present, but insufficient resources\n"));
- DEBUG(0,("Perhaps you should try again later?\n"));
- break;
- default:
- DEBUG(0,("Unspecified error 0x%X\n",ecode));
- DEBUG(0,("Your server software is being unfriendly\n"));
- break;
- }
- return(False);
- }
- return(True);
-}
-
-static struct {
- int prot;
- char *name;
-} prots[] = {
- {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"},
- {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
- {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
- {PROTOCOL_LANMAN1,"LANMAN1.0"},
- {PROTOCOL_LANMAN2,"LM1.2X002"},
- {PROTOCOL_LANMAN2,"Samba"},
- {PROTOCOL_NT1,"NT LM 0.12"},
- {PROTOCOL_NT1,"NT LANMAN 1.0"},
- {-1,NULL}
-};
-
-
-/****************************************************************************
-send a login command
-****************************************************************************/
-static BOOL send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup)
-{
- BOOL was_null = (!inbuf && !outbuf);
- int sesskey=0;
- time_t servertime = 0;
- extern int serverzone;
- int sec_mode=0;
- int crypt_len;
- int max_vcs=0;
- char *pass = NULL;
- pstring dev;
- char *p;
- int numprots;
- int tries=0;
-
- if (was_null)
- {
- inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- }
-
-#if AJT
- if (strstr(service,"IPC$")) connect_as_ipc = True;
-#endif
-
- strcpy(dev,"A:");
- if (connect_as_printer)
- strcpy(dev,"LPT1:");
- if (connect_as_ipc)
- strcpy(dev,"IPC");
-
-
- if (start_session && !send_session_request(inbuf,outbuf))
- {
- if (was_null)
- {
- free(inbuf);
- free(outbuf);
- }
- return(False);
- }
-
- bzero(outbuf,smb_size);
-
- /* setup the protocol strings */
- {
- int plength;
-
- for (plength=0,numprots=0;
- prots[numprots].name && prots[numprots].prot<=max_protocol;
- numprots++)
- plength += strlen(prots[numprots].name)+2;
-
- set_message(outbuf,0,plength,True);
-
- p = smb_buf(outbuf);
- for (numprots=0;
- prots[numprots].name && prots[numprots].prot<=max_protocol;
- numprots++)
- {
- *p++ = 2;
- strcpy(p,prots[numprots].name);
- p += strlen(p) + 1;
- }
- }
-
- CVAL(outbuf,smb_com) = SMBnegprot;
- setup_pkt(outbuf);
-
- CVAL(smb_buf(outbuf),0) = 2;
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- show_msg(inbuf);
-
- if (CVAL(inbuf,smb_rcls) != 0 || ((int)SVAL(inbuf,smb_vwv0) >= numprots))
- {
- DEBUG(0,("SMBnegprot failed. myname=%s destname=%s - %s \n",
- myname,desthost,smb_errstr(inbuf)));
- if (was_null)
- {
- free(inbuf);
- free(outbuf);
- }
- return(False);
- }
-
- Protocol = prots[SVAL(inbuf,smb_vwv0)].prot;
-
-
- if (Protocol < PROTOCOL_NT1) {
- sec_mode = SVAL(inbuf,smb_vwv1);
- max_xmit = SVAL(inbuf,smb_vwv2);
- sesskey = IVAL(inbuf,smb_vwv6);
- serverzone = SVALS(inbuf,smb_vwv10)*60;
- /* this time is converted to GMT by make_unix_date */
- servertime = make_unix_date(inbuf+smb_vwv8);
- if (Protocol >= PROTOCOL_COREPLUS) {
- readbraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x1) != 0);
- writebraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x2) != 0);
- }
- crypt_len = smb_buflen(inbuf);
- memcpy(cryptkey,smb_buf(inbuf),8);
- DEBUG(3,("max mux %d\n",SVAL(inbuf,smb_vwv3)));
- max_vcs = SVAL(inbuf,smb_vwv4);
- DEBUG(3,("max vcs %d\n",max_vcs));
- DEBUG(3,("max blk %d\n",SVAL(inbuf,smb_vwv5)));
- } else {
- /* NT protocol */
- sec_mode = CVAL(inbuf,smb_vwv1);
- max_xmit = IVAL(inbuf,smb_vwv3+1);
- sesskey = IVAL(inbuf,smb_vwv7+1);
- serverzone = SVALS(inbuf,smb_vwv15+1)*60;
- /* this time arrives in real GMT */
- servertime = interpret_long_date(inbuf+smb_vwv11+1);
- crypt_len = CVAL(inbuf,smb_vwv16+1);
- memcpy(cryptkey,smb_buf(inbuf),8);
- if (IVAL(inbuf,smb_vwv9+1) & 1)
- readbraw_supported = writebraw_supported = True;
- DEBUG(3,("max mux %d\n",SVAL(inbuf,smb_vwv1+1)));
- max_vcs = SVAL(inbuf,smb_vwv2+1);
- DEBUG(3,("max vcs %d\n",max_vcs));
- DEBUG(3,("max raw %d\n",IVAL(inbuf,smb_vwv5+1)));
- DEBUG(3,("capabilities 0x%x\n",IVAL(inbuf,smb_vwv9+1)));
- }
-
- DEBUG(3,("Sec mode %d\n",SVAL(inbuf,smb_vwv1)));
- DEBUG(3,("max xmt %d\n",max_xmit));
- DEBUG(3,("Got %d byte crypt key\n",crypt_len));
- DEBUG(3,("Chose protocol [%s]\n",prots[SVAL(inbuf,smb_vwv0)].name));
-
- doencrypt = ((sec_mode & 2) != 0);
-
- if (servertime) {
- static BOOL done_time = False;
- if (!done_time) {
- DEBUG(1,("Server time is %sTimezone is UTC%+02.1f\n",
- asctime(LocalTime(&servertime)),
- -(double)(serverzone/3600.0)));
- done_time = True;
- }
- }
-
- get_pass:
-
- if (got_pass)
- pass = password;
- else
- pass = (char *)getpass("Password: ");
-
- /* use a blank username for the 2nd try with a blank password */
- if (tries++ && !*pass)
- *username = 0;
-
- if (Protocol >= PROTOCOL_LANMAN1 && use_setup)
- {
- fstring pword;
- int passlen = strlen(pass)+1;
- strcpy(pword,pass);
-
- if (doencrypt && *pass) {
- DEBUG(3,("Using encrypted passwords\n"));
- passlen = 24;
- SMBencrypt((uchar *)pass,(uchar *)cryptkey,(uchar *)pword);
- }
-
- /* if in share level security then don't send a password now */
- if (!(sec_mode & 1)) {strcpy(pword, "");passlen=1;}
-
- /* send a session setup command */
- bzero(outbuf,smb_size);
-
- if (Protocol < PROTOCOL_NT1) {
- set_message(outbuf,10,1 + strlen(username) + passlen,True);
- CVAL(outbuf,smb_com) = SMBsesssetupX;
- setup_pkt(outbuf);
-
- CVAL(outbuf,smb_vwv0) = 0xFF;
- SSVAL(outbuf,smb_vwv2,max_xmit);
- SSVAL(outbuf,smb_vwv3,2);
- SSVAL(outbuf,smb_vwv4,max_vcs-1);
- SIVAL(outbuf,smb_vwv5,sesskey);
- SSVAL(outbuf,smb_vwv7,passlen);
- p = smb_buf(outbuf);
- memcpy(p,pword,passlen);
- p += passlen;
- strcpy(p,username);
- } else {
- if (!doencrypt) passlen--;
- /* for Win95 */
- set_message(outbuf,13,0,True);
- CVAL(outbuf,smb_com) = SMBsesssetupX;
- setup_pkt(outbuf);
-
- CVAL(outbuf,smb_vwv0) = 0xFF;
- SSVAL(outbuf,smb_vwv2,BUFFER_SIZE);
- SSVAL(outbuf,smb_vwv3,2);
- SSVAL(outbuf,smb_vwv4,getpid());
- SIVAL(outbuf,smb_vwv5,sesskey);
- SSVAL(outbuf,smb_vwv7,passlen);
- SSVAL(outbuf,smb_vwv8,0);
- p = smb_buf(outbuf);
- memcpy(p,pword,passlen); p += SVAL(outbuf,smb_vwv7);
- strcpy(p,username);p = skip_string(p,1);
- strcpy(p,workgroup);p = skip_string(p,1);
- strcpy(p,"Unix");p = skip_string(p,1);
- strcpy(p,"Samba");p = skip_string(p,1);
- set_message(outbuf,13,PTR_DIFF(p,smb_buf(outbuf)),False);
- }
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- show_msg(inbuf);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- if (! *pass &&
- ((CVAL(inbuf,smb_rcls) == ERRDOS &&
- SVAL(inbuf,smb_err) == ERRnoaccess) ||
- (CVAL(inbuf,smb_rcls) == ERRSRV &&
- SVAL(inbuf,smb_err) == ERRbadpw)))
- {
- got_pass = False;
- DEBUG(3,("resending login\n"));
- goto get_pass;
- }
-
- DEBUG(0,("Session setup failed for username=%s myname=%s destname=%s %s\n",
- username,myname,desthost,smb_errstr(inbuf)));
- DEBUG(0,("You might find the -U, -W or -n options useful\n"));
- DEBUG(0,("Sometimes you have to use `-n USERNAME' (particularly with OS/2)\n"));
- DEBUG(0,("Some servers also insist on uppercase-only passwords\n"));
- if (was_null)
- {
- free(inbuf);
- free(outbuf);
- }
- return(False);
- }
-
- if (Protocol >= PROTOCOL_NT1) {
- char *domain,*os,*lanman;
- p = smb_buf(inbuf);
- os = p;
- lanman = skip_string(os,1);
- domain = skip_string(lanman,1);
- if (*domain || *os || *lanman)
- DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",domain,os,lanman));
- }
-
- /* use the returned uid from now on */
- if (SVAL(inbuf,smb_uid) != uid)
- DEBUG(3,("Server gave us a UID of %d. We gave %d\n",
- SVAL(inbuf,smb_uid),uid));
- uid = SVAL(inbuf,smb_uid);
- }
-
- /* now we've got a connection - send a tcon message */
- bzero(outbuf,smb_size);
-
- if (strncmp(service,"\\\\",2) != 0)
- {
- DEBUG(0,("\nWarning: Your service name doesn't start with \\\\. This is probably incorrect.\n"));
- DEBUG(0,("Perhaps try replacing each \\ with \\\\ on the command line?\n\n"));
- }
-
-
- again2:
-
- {
- int passlen = strlen(pass)+1;
- fstring pword;
- strcpy(pword,pass);
-
- if (doencrypt && *pass) {
- passlen=24;
- SMBencrypt((uchar *)pass,(uchar *)cryptkey,(uchar *)pword);
- }
-
- /* if in user level security then don't send a password now */
- if ((sec_mode & 1)) {
- strcpy(pword, ""); passlen=1;
- }
-
- if (Protocol <= PROTOCOL_COREPLUS) {
- set_message(outbuf,0,6 + strlen(service) + passlen + strlen(dev),True);
- CVAL(outbuf,smb_com) = SMBtcon;
- setup_pkt(outbuf);
-
- p = smb_buf(outbuf);
- *p++ = 0x04;
- strcpy(p, service);
- p = skip_string(p,1);
- *p++ = 0x04;
- memcpy(p,pword,passlen);
- p += passlen;
- *p++ = 0x04;
- strcpy(p, dev);
- }
- else {
- set_message(outbuf,4,2 + strlen(service) + passlen + strlen(dev),True);
- CVAL(outbuf,smb_com) = SMBtconX;
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,0xFF);
- SSVAL(outbuf,smb_vwv3,passlen);
-
- p = smb_buf(outbuf);
- memcpy(p,pword,passlen);
- p += passlen;
- strcpy(p,service);
- p = skip_string(p,1);
- strcpy(p,dev);
- }
- }
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- /* trying again with a blank password */
- if (CVAL(inbuf,smb_rcls) != 0 &&
- (int)strlen(pass) > 0 &&
- !doencrypt &&
- Protocol >= PROTOCOL_LANMAN1)
- {
- DEBUG(2,("first SMBtconX failed, trying again. %s\n",smb_errstr(inbuf)));
- strcpy(pass,"");
- goto again2;
- }
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("SMBtconX failed. %s\n",smb_errstr(inbuf)));
- DEBUG(0,("Perhaps you are using the wrong sharename, username or password?\n"));
- DEBUG(0,("Some servers insist that these be in uppercase\n"));
- if (was_null)
- {
- free(inbuf);
- free(outbuf);
- }
- return(False);
- }
-
-
- if (Protocol <= PROTOCOL_COREPLUS) {
- max_xmit = SVAL(inbuf,smb_vwv0);
-
- cnum = SVAL(inbuf,smb_vwv1);
- }
- else {
- max_xmit = MIN(max_xmit,BUFFER_SIZE-4);
- if (max_xmit <= 0)
- max_xmit = BUFFER_SIZE - 4;
-
- cnum = SVAL(inbuf,smb_tid);
- }
-
- DEBUG(3,("Connected with cnum=%d max_xmit=%d\n",cnum,max_xmit));
-
- if (was_null)
- {
- free(inbuf);
- free(outbuf);
- }
- return True;
-}
-
-
-/****************************************************************************
-send a logout command
-****************************************************************************/
-static void send_logout(void )
-{
- pstring inbuf,outbuf;
-
- bzero(outbuf,smb_size);
- set_message(outbuf,0,0,True);
- CVAL(outbuf,smb_com) = SMBtdis;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,SHORT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("SMBtdis failed %s\n",smb_errstr(inbuf)));
- }
-
-
-#ifdef STATS
- stats_report();
-#endif
- exit(0);
-}
-
-
-
-/****************************************************************************
-call a remote api
-****************************************************************************/
-static BOOL call_api(int prcnt,int drcnt,
- int mprcnt,int mdrcnt,
- int *rprcnt,int *rdrcnt,
- char *param,char *data,
- char **rparam,char **rdata)
-{
- static char *inbuf=NULL;
- static char *outbuf=NULL;
-
- if (!inbuf) inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- if (!outbuf) outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
- send_trans_request(outbuf,SMBtrans,"\\PIPE\\LANMAN",0,0,
- data,param,NULL,
- drcnt,prcnt,0,
- mdrcnt,mprcnt,0);
-
- return (receive_trans_response(inbuf,SMBtrans,
- rdrcnt,rprcnt,
- rdata,rparam));
-}
-
-/****************************************************************************
- send a SMB trans or trans2 request
- ****************************************************************************/
-static BOOL send_trans_request(char *outbuf,int trans,
- char *name,int fid,int flags,
- char *data,char *param,uint16 *setup,
- int ldata,int lparam,int lsetup,
- int mdata,int mparam,int msetup)
-{
- int i;
- int this_ldata,this_lparam;
- int tot_data=0,tot_param=0;
- char *outdata,*outparam;
- pstring inbuf;
- char *p;
-
- this_lparam = MIN(lparam,max_xmit - (500+lsetup*SIZEOFWORD)); /* hack */
- this_ldata = MIN(ldata,max_xmit - (500+lsetup*SIZEOFWORD+this_lparam));
-
- bzero(outbuf,smb_size);
- set_message(outbuf,14+lsetup,0,True);
- CVAL(outbuf,smb_com) = trans;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- outparam = smb_buf(outbuf)+(trans==SMBtrans ? strlen(name)+1 : 3);
- outdata = outparam+this_lparam;
-
- /* primary request */
- SSVAL(outbuf,smb_tpscnt,lparam); /* tpscnt */
- SSVAL(outbuf,smb_tdscnt,ldata); /* tdscnt */
- SSVAL(outbuf,smb_mprcnt,mparam); /* mprcnt */
- SSVAL(outbuf,smb_mdrcnt,mdata); /* mdrcnt */
- SCVAL(outbuf,smb_msrcnt,msetup); /* msrcnt */
- SSVAL(outbuf,smb_flags,flags); /* flags */
- SIVAL(outbuf,smb_timeout,0); /* timeout */
- SSVAL(outbuf,smb_pscnt,this_lparam); /* pscnt */
- SSVAL(outbuf,smb_psoff,smb_offset(outparam,outbuf)); /* psoff */
- SSVAL(outbuf,smb_dscnt,this_ldata); /* dscnt */
- SSVAL(outbuf,smb_dsoff,smb_offset(outdata,outbuf)); /* dsoff */
- SCVAL(outbuf,smb_suwcnt,lsetup); /* suwcnt */
- for (i=0;i<lsetup;i++) /* setup[] */
- SSVAL(outbuf,smb_setup+i*SIZEOFWORD,setup[i]);
- p = smb_buf(outbuf);
- if (trans==SMBtrans)
- strcpy(p,name); /* name[] */
- else
- {
- *p++ = 0; /* put in a null smb_name */
- *p++ = 'D'; *p++ = ' '; /* this was added because OS/2 does it */
- }
- if (this_lparam) /* param[] */
- memcpy(outparam,param,this_lparam);
- if (this_ldata) /* data[] */
- memcpy(outdata,data,this_ldata);
- set_message(outbuf,14+lsetup, /* wcnt, bcc */
- PTR_DIFF(outdata+this_ldata,smb_buf(outbuf)),False);
-
- show_msg(outbuf);
- send_smb(Client,outbuf);
-
- if (this_ldata < ldata || this_lparam < lparam)
- {
- /* receive interim response */
- if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("%s request failed (%s)\n",
- trans==SMBtrans?"SMBtrans":"SMBtrans2", smb_errstr(inbuf)));
- return(False);
- }
-
- tot_data = this_ldata;
- tot_param = this_lparam;
-
- while (tot_data < ldata || tot_param < lparam)
- {
- this_lparam = MIN(lparam-tot_param,max_xmit - 500); /* hack */
- this_ldata = MIN(ldata-tot_data,max_xmit - (500+this_lparam));
-
- set_message(outbuf,trans==SMBtrans?8:9,0,True);
- CVAL(outbuf,smb_com) = trans==SMBtrans ? SMBtranss : SMBtranss2;
-
- outparam = smb_buf(outbuf);
- outdata = outparam+this_lparam;
-
- /* secondary request */
- SSVAL(outbuf,smb_tpscnt,lparam); /* tpscnt */
- SSVAL(outbuf,smb_tdscnt,ldata); /* tdscnt */
- SSVAL(outbuf,smb_spscnt,this_lparam); /* pscnt */
- SSVAL(outbuf,smb_spsoff,smb_offset(outparam,outbuf)); /* psoff */
- SSVAL(outbuf,smb_spsdisp,tot_param); /* psdisp */
- SSVAL(outbuf,smb_sdscnt,this_ldata); /* dscnt */
- SSVAL(outbuf,smb_sdsoff,smb_offset(outdata,outbuf)); /* dsoff */
- SSVAL(outbuf,smb_sdsdisp,tot_data); /* dsdisp */
- if (trans==SMBtrans2)
- SSVAL(outbuf,smb_sfid,fid); /* fid */
- if (this_lparam) /* param[] */
- memcpy(outparam,param,this_lparam);
- if (this_ldata) /* data[] */
- memcpy(outdata,data,this_ldata);
- set_message(outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */
- PTR_DIFF(outdata+this_ldata,smb_buf(outbuf)),False);
-
- show_msg(outbuf);
- send_smb(Client,outbuf);
-
- tot_data += this_ldata;
- tot_param += this_lparam;
- }
- }
-
- return(True);
-}
-
-/****************************************************************************
-try and browse available connections on a host
-****************************************************************************/
-static BOOL browse_host(BOOL sort)
-{
-#ifdef NOSTRCASECMP
-/* If strcasecmp is already defined, remove it. */
-#ifdef strcasecmp
-#undef strcasecmp
-#endif /* strcasecmp */
-#define strcasecmp StrCaseCmp
-#endif /* NOSTRCASECMP */
-
- extern int strcasecmp();
-
- char *rparam = NULL;
- char *rdata = NULL;
- char *p;
- int rdrcnt,rprcnt;
- pstring param;
- int count = -1;
-
- /* now send a SMBtrans command with api RNetShareEnum */
- p = param;
- SSVAL(p,0,0); /* api number */
- p += 2;
- strcpy(p,"WrLeh");
- p = skip_string(p,1);
- strcpy(p,"B13BWz");
- p = skip_string(p,1);
- SSVAL(p,0,1);
- SSVAL(p,2,BUFFER_SIZE);
- p += 4;
-
- if (call_api(PTR_DIFF(p,param),0,
- 1024,BUFFER_SIZE,
- &rprcnt,&rdrcnt,
- param,NULL,
- &rparam,&rdata))
- {
- int res = SVAL(rparam,0);
- int converter=SVAL(rparam,2);
- int i;
- BOOL long_share_name=False;
-
- if (res == 0)
- {
- count=SVAL(rparam,4);
- p = rdata;
-
- if (count > 0)
- {
- printf("\n\tSharename Type Comment\n");
- printf("\t--------- ---- -------\n");
- }
-
- if (sort)
- qsort(p,count,20,QSORT_CAST strcasecmp);
-
- for (i=0;i<count;i++)
- {
- char *sname = p;
- int type = SVAL(p,14);
- int comment_offset = IVAL(p,16) & 0xFFFF;
- fstring typestr;
- *typestr=0;
-
- switch (type)
- {
- case STYPE_DISKTREE:
- strcpy(typestr,"Disk"); break;
- case STYPE_PRINTQ:
- strcpy(typestr,"Printer"); break;
- case STYPE_DEVICE:
- strcpy(typestr,"Device"); break;
- case STYPE_IPC:
- strcpy(typestr,"IPC"); break;
- }
-
- printf("\t%-15.15s%-10.10s%s\n",
- sname,
- typestr,
- comment_offset?rdata+comment_offset-converter:"");
-
- if (strlen(sname)>8) long_share_name=True;
-
- p += 20;
- }
-
- if (long_share_name) {
- printf("\nNOTE: There were share names longer than 8 chars.\nOn older clients these may not be accessible or may give browsing errors\n");
- }
- }
- }
-
- if (rparam) free(rparam);
- if (rdata) free(rdata);
-
- return(count>0);
-}
-
-
-/****************************************************************************
-get some server info
-****************************************************************************/
-static void server_info()
-{
- char *rparam = NULL;
- char *rdata = NULL;
- char *p;
- int rdrcnt,rprcnt;
- pstring param;
-
- bzero(param,sizeof(param));
-
- p = param;
- SSVAL(p,0,63); /* NetServerGetInfo()? */
- p += 2;
- strcpy(p,"WrLh");
- p = skip_string(p,1);
- strcpy(p,"zzzBBzz");
- p = skip_string(p,1);
- SSVAL(p,0,10); /* level 10 */
- SSVAL(p,2,1000);
- p += 6;
-
- if (call_api(PTR_DIFF(p,param),0,
- 6,1000,
- &rprcnt,&rdrcnt,
- param,NULL,
- &rparam,&rdata))
- {
- int res = SVAL(rparam,0);
- int converter=SVAL(rparam,2);
-
- if (res == 0)
- {
- p = rdata;
-
- printf("\nServer=[%s] User=[%s] Workgroup=[%s] Domain=[%s]\n",
- rdata+SVAL(p,0)-converter,
- rdata+SVAL(p,4)-converter,
- rdata+SVAL(p,8)-converter,
- rdata+SVAL(p,14)-converter);
- }
- }
-
- if (rparam) free(rparam);
- if (rdata) free(rdata);
-
- return;
-}
-
-
-/****************************************************************************
-try and browse available connections on a host
-****************************************************************************/
-static BOOL list_servers(char *wk_grp)
-{
- char *rparam = NULL;
- char *rdata = NULL;
- int rdrcnt,rprcnt;
- char *p,*svtype_p;
- pstring param;
- int uLevel = 1;
- int count = 0;
- BOOL ok = False;
- BOOL generic_request = False;
-
-
- if (strequal(wk_grp,"WORKGROUP")) {
- /* we won't specify a workgroup */
- generic_request = True;
- }
-
- /* now send a SMBtrans command with api ServerEnum? */
- p = param;
- SSVAL(p,0,0x68); /* api number */
- p += 2;
-
- strcpy(p,generic_request?"WrLehDO":"WrLehDz");
- p = skip_string(p,1);
-
- strcpy(p,"B16BBDz");
-
- p = skip_string(p,1);
- SSVAL(p,0,uLevel);
- SSVAL(p,2,BUFFER_SIZE - SAFETY_MARGIN); /* buf length */
- p += 4;
-
- svtype_p = p;
- p += 4;
-
- if (!generic_request) {
- strcpy(p, wk_grp);
- p = skip_string(p,1);
- }
-
- /* first ask for a list of servers in this workgroup */
- SIVAL(svtype_p,0,SV_TYPE_ALL);
-
- if (call_api(PTR_DIFF(p+4,param),0,
- 8,BUFFER_SIZE - SAFETY_MARGIN,
- &rprcnt,&rdrcnt,
- param,NULL,
- &rparam,&rdata))
- {
- int res = SVAL(rparam,0);
- int converter=SVAL(rparam,2);
- int i;
-
- if (res == 0) {
- char *p2 = rdata;
- count=SVAL(rparam,4);
-
- if (count > 0) {
- printf("\n\nThis machine has a browse list:\n");
- printf("\n\tServer Comment\n");
- printf("\t--------- -------\n");
- }
-
- for (i=0;i<count;i++) {
- char *sname = p2;
- int comment_offset = IVAL(p2,22) & 0xFFFF;
- printf("\t%-16.16s %s\n",
- sname,
- comment_offset?rdata+comment_offset-converter:"");
-
- ok=True;
- p2 += 26;
- }
- }
- }
-
- if (rparam) {free(rparam); rparam = NULL;}
- if (rdata) {free(rdata); rdata = NULL;}
-
- /* now ask for a list of workgroups */
- SIVAL(svtype_p,0,SV_TYPE_DOMAIN_ENUM);
-
- if (call_api(PTR_DIFF(p+4,param),0,
- 8,BUFFER_SIZE - SAFETY_MARGIN,
- &rprcnt,&rdrcnt,
- param,NULL,
- &rparam,&rdata))
- {
- int res = SVAL(rparam,0);
- int converter=SVAL(rparam,2);
- int i;
-
- if (res == 0) {
- char *p2 = rdata;
- count=SVAL(rparam,4);
-
- if (count > 0) {
- printf("\n\nThis machine has a workgroup list:\n");
- printf("\n\tWorkgroup Master\n");
- printf("\t--------- -------\n");
- }
-
- for (i=0;i<count;i++) {
- char *sname = p2;
- int comment_offset = IVAL(p2,22) & 0xFFFF;
- printf("\t%-16.16s %s\n",
- sname,
- comment_offset?rdata+comment_offset-converter:"");
-
- ok=True;
- p2 += 26;
- }
- }
- }
-
- if (rparam) free(rparam);
- if (rdata) free(rdata);
-
- return(ok);
-}
-
-
-/* This defines the commands supported by this client */
-struct
-{
- char *name;
- void (*fn)();
- char *description;
-} commands[] =
-{
- {"ls",cmd_dir,"<mask> list the contents of the current directory"},
- {"dir",cmd_dir,"<mask> list the contents of the current directory"},
- {"lcd",cmd_lcd,"[directory] change/report the local current working directory"},
- {"cd",cmd_cd,"[directory] change/report the remote directory"},
- {"pwd",cmd_pwd,"show current remote directory (same as 'cd' with no args)"},
- {"get",cmd_get,"<remote name> [local name] get a file"},
- {"mget",cmd_mget,"<mask> get all the matching files"},
- {"put",cmd_put,"<local name> [remote name] put a file"},
- {"mput",cmd_mput,"<mask> put all matching files"},
- {"rename",cmd_rename,"<src> <dest> rename some files"},
- {"more",cmd_more,"<remote name> view a remote file with your pager"},
- {"mask",cmd_select,"<mask> mask all filenames against this"},
- {"del",cmd_del,"<mask> delete all matching files"},
- {"rm",cmd_del,"<mask> delete all matching files"},
- {"mkdir",cmd_mkdir,"<directory> make a directory"},
- {"md",cmd_mkdir,"<directory> make a directory"},
- {"rmdir",cmd_rmdir,"<directory> remove a directory"},
- {"rd",cmd_rmdir,"<directory> remove a directory"},
- {"pq",cmd_p_queue_4,"enumerate the print queue"},
- {"prompt",cmd_prompt,"toggle prompting for filenames for mget and mput"},
- {"recurse",cmd_recurse,"toggle directory recursion for mget and mput"},
- {"translate",cmd_translate,"toggle text translation for printing"},
- {"lowercase",cmd_lowercase,"toggle lowercasing of filenames for get"},
- {"print",cmd_print,"<file name> print a file"},
- {"printmode",cmd_printmode,"<graphics or text> set the print mode"},
- {"queue",cmd_queue,"show the print queue"},
- {"qinfo",cmd_qinfo,"show print queue information"},
- {"cancel",cmd_cancel,"<jobid> cancel a print queue entry"},
- {"stat",cmd_stat,"<file> get info on a file (experimental!)"},
- {"quit",send_logout,"logoff the server"},
- {"q",send_logout,"logoff the server"},
- {"exit",send_logout,"logoff the server"},
- {"newer",cmd_newer,"<file> only mget files newer than the specified local file"},
- {"archive",cmd_archive,"<level>\n0=ignore archive bit\n1=only get archive files\n2=only get archive files and reset archive bit\n3=get all files and reset archive bit"},
- {"tar",cmd_tar,"tar <c|x>[IXbgNa] current directory to/from <file name>" },
- {"blocksize",cmd_block,"blocksize <number> (default 20)" },
- {"tarmode",cmd_tarmode,
- "<full|inc|reset|noreset> tar's behaviour towards archive bits" },
- {"setmode",cmd_setmode,"filename <setmode string> change modes of file"},
- {"help",cmd_help,"[command] give help on a command"},
- {"?",cmd_help,"[command] give help on a command"},
- {"!",NULL,"run a shell command on the local system"},
- {"",NULL,NULL}
-};
-
-
-/*******************************************************************
- lookup a command string in the list of commands, including
- abbreviations
- ******************************************************************/
-static int process_tok(fstring tok)
-{
- int i = 0, matches = 0;
- int cmd=0;
- int tok_len = strlen(tok);
-
- while (commands[i].fn != NULL)
- {
- if (strequal(commands[i].name,tok))
- {
- matches = 1;
- cmd = i;
- break;
- }
- else if (strnequal(commands[i].name, tok, tok_len+1))
- {
- matches++;
- cmd = i;
- }
- i++;
- }
-
- if (matches == 0)
- return(-1);
- else if (matches == 1)
- return(cmd);
- else
- return(-2);
-}
-
-/****************************************************************************
-help
-****************************************************************************/
-void cmd_help(void)
-{
- int i=0,j;
- fstring buf;
-
- if (next_token(NULL,buf,NULL))
- {
- if ((i = process_tok(buf)) >= 0)
- DEBUG(0,("HELP %s:\n\t%s\n\n",commands[i].name,commands[i].description));
- }
- else
- while (commands[i].description)
- {
- for (j=0; commands[i].description && (j<5); j++) {
- DEBUG(0,("%-15s",commands[i].name));
- i++;
- }
- DEBUG(0,("\n"));
- }
-}
-
-/****************************************************************************
-open the client sockets
-****************************************************************************/
-static BOOL open_sockets(int port )
-{
- static int last_port;
- char *host;
- pstring service2;
- extern int Client;
-#ifdef USENMB
- BOOL failed = True;
-#endif
-
- if (port == 0) port=last_port;
- last_port=port;
-
- strupper(service);
-
- if (*desthost)
- {
- host = desthost;
- }
- else
- {
- strcpy(service2,service);
- host = strtok(service2,"\\/");
- if (!host) {
- DEBUG(0,("Badly formed host name\n"));
- return(False);
- }
- strcpy(desthost,host);
- }
-
- if (*myname == 0) {
- get_myname(myname,NULL);
- }
- strupper(myname);
-
- DEBUG(3,("Opening sockets\n"));
-
- if (!have_ip)
- {
- struct hostent *hp;
-
- if ((hp = Get_Hostbyname(host))) {
- putip((char *)&dest_ip,(char *)hp->h_addr);
- failed = False;
- } else {
-#ifdef USENMB
- /* Try and resolve the name with the netbios server */
- int bcast;
-
- if ((bcast = open_socket_in(SOCK_DGRAM, 0, 3,
- interpret_addr(lp_socket_address()))) != -1) {
- set_socket_options(bcast, "SO_BROADCAST");
-
- if (name_query(bcast, host, name_type, True, True, *iface_bcast(dest_ip),
- &dest_ip,0)) {
- failed = False;
- }
- close (bcast);
- }
-#endif
- if (failed) {
- DEBUG(0,("Get_Hostbyname: Unknown host %s.\n",host));
- return False;
- }
- }
- }
-
- Client = open_socket_out(SOCK_STREAM, &dest_ip, port, LONG_CONNECT_TIMEOUT);
- if (Client == -1)
- return False;
-
- DEBUG(3,("Connected\n"));
-
- set_socket_options(Client,user_socket_options);
-
- return True;
-}
-
-/****************************************************************************
-wait for keyboard activity, swallowing network packets
-****************************************************************************/
-#ifdef CLIX
-static char wait_keyboard(char *buffer)
-#else
-static void wait_keyboard(char *buffer)
-#endif
-{
- fd_set fds;
- int selrtn;
- struct timeval timeout;
-
-#ifdef CLIX
- int delay = 0;
-#endif
-
- while (1)
- {
- extern int Client;
- FD_ZERO(&fds);
- FD_SET(Client,&fds);
-#ifndef CLIX
- FD_SET(fileno(stdin),&fds);
-#endif
-
- timeout.tv_sec = 20;
- timeout.tv_usec = 0;
-#ifdef CLIX
- timeout.tv_sec = 0;
-#endif
- selrtn = sys_select(&fds,&timeout);
-
-#ifndef CLIX
- if (FD_ISSET(fileno(stdin),&fds))
- return;
-#else
- {
- char ch;
- int readret;
-
- set_blocking(fileno(stdin), False);
- readret = read_data( fileno(stdin), &ch, 1);
- set_blocking(fileno(stdin), True);
- if (readret == -1)
- {
- if (errno != EAGAIN)
- {
- /* should crash here */
- DEBUG(1,("readchar stdin failed\n"));
- }
- }
- else if (readret != 0)
- {
- return ch;
- }
- }
-#endif
- if (FD_ISSET(Client,&fds))
- receive_smb(Client,buffer,0);
-
-#ifdef CLIX
- delay++;
- if (delay > 100000)
- {
- delay = 0;
- chkpath("\\",False);
- }
-#else
- chkpath("\\",False);
-#endif
- }
-}
-
-
-/****************************************************************************
-close and open the connection again
-****************************************************************************/
-BOOL reopen_connection(char *inbuf,char *outbuf)
-{
- static int open_count=0;
-
- open_count++;
-
- if (open_count>5) return(False);
-
- DEBUG(1,("Trying to re-open connection\n"));
-
- set_message(outbuf,0,0,True);
- SCVAL(outbuf,smb_com,SMBtdis);
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,SHORT_TIMEOUT);
-
- close_sockets();
- if (!open_sockets(0)) return(False);
-
- return(send_login(inbuf,outbuf,True,True));
-}
-
-/****************************************************************************
- process commands from the client
-****************************************************************************/
-static BOOL process(char *base_directory)
-{
- extern FILE *dbf;
- pstring line;
- char *cmd;
-
- char *InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- char *OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
- if ((InBuffer == NULL) || (OutBuffer == NULL))
- return(False);
-
- bzero(OutBuffer,smb_size);
-
- if (!send_login(InBuffer,OutBuffer,True,True))
- return(False);
-
- if (*base_directory) do_cd(base_directory);
-
- cmd = cmdstr;
- if (cmd[0] != '\0') while (cmd[0] != '\0')
- {
- char *p;
- fstring tok;
- int i;
-
- if ((p = strchr(cmd, ';')) == 0)
- {
- strncpy(line, cmd, 999);
- line[1000] = '\0';
- cmd += strlen(cmd);
- }
- else
- {
- if (p - cmd > 999) p = cmd + 999;
- strncpy(line, cmd, p - cmd);
- line[p - cmd] = '\0';
- cmd = p + 1;
- }
-
- /* input language code to internal one */
- CNV_INPUT (line);
-
- /* and get the first part of the command */
- {
- char *ptr = line;
- if (!next_token(&ptr,tok,NULL)) continue;
- }
-
- if ((i = process_tok(tok)) >= 0)
- commands[i].fn(InBuffer,OutBuffer);
- else if (i == -2)
- DEBUG(0,("%s: command abbreviation ambiguous\n",CNV_LANG(tok)));
- else
- DEBUG(0,("%s: command not found\n",CNV_LANG(tok)));
- }
- else while (!feof(stdin))
- {
- fstring tok;
- int i;
-
- bzero(OutBuffer,smb_size);
-
- /* display a prompt */
- DEBUG(0,("smb: %s> ", CNV_LANG(cur_dir)));
- fflush(dbf);
-
-#ifdef CLIX
- line[0] = wait_keyboard(InBuffer);
- /* this might not be such a good idea... */
- if ( line[0] == EOF)
- break;
-#else
- wait_keyboard(InBuffer);
-#endif
-
- /* and get a response */
-#ifdef CLIX
- fgets( &line[1],999, stdin);
-#else
- if (!fgets(line,1000,stdin))
- break;
-#endif
-
- /* input language code to internal one */
- CNV_INPUT (line);
-
- /* special case - first char is ! */
- if (*line == '!')
- {
- system(line + 1);
- continue;
- }
-
- /* and get the first part of the command */
- {
- char *ptr = line;
- if (!next_token(&ptr,tok,NULL)) continue;
- }
-
- if ((i = process_tok(tok)) >= 0)
- commands[i].fn(InBuffer,OutBuffer);
- else if (i == -2)
- DEBUG(0,("%s: command abbreviation ambiguous\n",CNV_LANG(tok)));
- else
- DEBUG(0,("%s: command not found\n",CNV_LANG(tok)));
- }
-
- send_logout();
- return(True);
-}
-
-
-/****************************************************************************
-usage on the program
-****************************************************************************/
-static void usage(char *pname)
-{
- DEBUG(0,("Usage: %s service <password> [-p port] [-d debuglevel] [-l log] ",
- pname));
-
- DEBUG(0,("\nVersion %s\n",VERSION));
- DEBUG(0,("\t-p port listen on the specified port\n"));
- DEBUG(0,("\t-d debuglevel set the debuglevel\n"));
- DEBUG(0,("\t-l log basename. Basename for log/debug files\n"));
- DEBUG(0,("\t-n netbios name. Use this name as my netbios name\n"));
- DEBUG(0,("\t-N don't ask for a password\n"));
- DEBUG(0,("\t-P connect to service as a printer\n"));
- DEBUG(0,("\t-M host send a winpopup message to the host\n"));
- DEBUG(0,("\t-m max protocol set the max protocol level\n"));
- DEBUG(0,("\t-L host get a list of shares available on a host\n"));
- DEBUG(0,("\t-I dest IP use this IP to connect to\n"));
- DEBUG(0,("\t-E write messages to stderr instead of stdout\n"));
- DEBUG(0,("\t-U username set the network username\n"));
- DEBUG(0,("\t-W workgroup set the workgroup name\n"));
- DEBUG(0,("\t-c command string execute semicolon separated commands\n"));
- DEBUG(0,("\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n"));
- DEBUG(0,("\t-T<c|x>IXgbNa command line tar\n"));
- DEBUG(0,("\t-D directory start from directory\n"));
- DEBUG(0,("\n"));
-}
-
-/****************************************************************************
- main program
-****************************************************************************/
- int main(int argc,char *argv[])
-{
- fstring base_directory;
- char *pname = argv[0];
- int port = SMB_PORT;
- int opt;
- extern FILE *dbf;
- extern char *optarg;
- extern int optind;
- pstring query_host;
- BOOL message = False;
- extern char tar_type;
- static pstring servicesf = CONFIGFILE;
- pstring term_code;
- char *p;
-
-#ifdef KANJI
- strcpy(term_code, KANJI);
-#else /* KANJI */
- *term_code = 0;
-#endif /* KANJI */
-
- *query_host = 0;
- *base_directory = 0;
-
- DEBUGLEVEL = 2;
-
- setup_logging(pname,True);
-
- TimeInit();
- charset_initialise();
-
- pid = getpid();
- uid = getuid();
- gid = getgid();
- mid = pid + 100;
- myumask = umask(0);
- umask(myumask);
-
- if (getenv("USER"))
- {
- strcpy(username,getenv("USER"));
-
- /* modification to support userid%passwd syntax in the USER var
- 25.Aug.97, jdblair@uab.edu */
-
- if ((p=strchr(username,'%')))
- {
- *p = 0;
- strcpy(password,p+1);
- got_pass = True;
- memset(strchr(getenv("USER"),'%')+1,'X',strlen(password));
- }
- strupper(username);
- }
-
- /* modification to support PASSWD environmental var
- 25.Aug.97, jdblair@uab.edu */
-
- if (getenv("PASSWD"))
- strcpy(password,getenv("PASSWD"));
-
- if (*username == 0 && getenv("LOGNAME"))
- {
- strcpy(username,getenv("LOGNAME"));
- strupper(username);
- }
-
- if (argc < 2)
- {
- usage(pname);
- exit(1);
- }
-
- if (*argv[1] != '-')
- {
-
- strcpy(service,argv[1]);
- /* Convert any '/' characters in the service name to '\' characters */
- string_replace( service, '/','\\');
- argc--;
- argv++;
-
- if (count_chars(service,'\\') < 3)
- {
- usage(pname);
- printf("\n%s: Not enough '\\' characters in service\n",service);
- exit(1);
- }
-
-/*
- if (count_chars(service,'\\') > 3)
- {
- usage(pname);
- printf("\n%s: Too many '\\' characters in service\n",service);
- exit(1);
- }
- */
-
- if (argc > 1 && (*argv[1] != '-'))
- {
- got_pass = True;
- strcpy(password,argv[1]);
- memset(argv[1],'X',strlen(argv[1]));
- argc--;
- argv++;
- }
- }
-
- while ((opt =
- getopt(argc, argv,"s:B:O:M:i:Nn:d:Pp:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF)
- switch (opt)
- {
- case 'm':
- max_protocol = interpret_protocol(optarg,max_protocol);
- break;
- case 'O':
- strcpy(user_socket_options,optarg);
- break;
- case 'M':
- name_type = 0x03; /* messages are sent to NetBIOS name type 0x3 */
- strcpy(desthost,optarg);
- strupper(desthost);
- message = True;
- break;
- case 'B':
- iface_set_default(NULL,optarg,NULL);
- break;
- case 'D':
- strcpy(base_directory,optarg);
- break;
- case 'T':
- if (!tar_parseargs(argc, argv, optarg, optind)) {
- usage(pname);
- exit(1);
- }
- break;
- case 'i':
- strcpy(scope,optarg);
- break;
- case 'L':
- got_pass = True;
- strcpy(query_host,optarg);
- break;
- case 'U':
- {
- char *lp;
- strcpy(username,optarg);
- if ((lp=strchr(username,'%')))
- {
- *lp = 0;
- strcpy(password,lp+1);
- got_pass = True;
- memset(strchr(optarg,'%')+1,'X',strlen(password));
- }
- }
-
- break;
- case 'W':
- strcpy(workgroup,optarg);
- break;
- case 'E':
- dbf = stderr;
- break;
- case 'I':
- {
- dest_ip = *interpret_addr2(optarg);
- if (zero_ip(dest_ip)) exit(1);
- have_ip = True;
- }
- break;
- case 'n':
- strcpy(myname,optarg);
- break;
- case 'N':
- got_pass = True;
- break;
- case 'P':
- connect_as_printer = True;
- break;
- case 'd':
- if (*optarg == 'A')
- DEBUGLEVEL = 10000;
- else
- DEBUGLEVEL = atoi(optarg);
- break;
- case 'l':
- sprintf(debugf,"%s.client",optarg);
- break;
- case 'p':
- port = atoi(optarg);
- break;
- case 'c':
- cmdstr = optarg;
- got_pass = True;
- break;
- case 'h':
- usage(pname);
- exit(0);
- break;
- case 's':
- strcpy(servicesf, optarg);
- break;
- case 't':
- strcpy(term_code, optarg);
- break;
- default:
- usage(pname);
- exit(1);
- }
-
- if (!tar_type && !*query_host && !*service && !message)
- {
- usage(pname);
- exit(1);
- }
-
-
- DEBUG(3,("%s client started (version %s)\n",timestring(),VERSION));
-
- if(!get_myname(myhostname,NULL))
- {
- DEBUG(0,("Failed to get my hostname.\n"));
- }
-
- if (!lp_load(servicesf,True)) {
- fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
- }
-
- codepage_initialise(lp_client_code_page());
-
- if(lp_client_code_page() == KANJI_CODEPAGE)
- {
- if (!setup_term_code (term_code))
- {
- DEBUG(0, ("%s: unknown terminal code name\n", optarg));
- usage (pname);
- exit (1);
- }
- }
-
- if (*workgroup == 0)
- strcpy(workgroup,lp_workgroup());
-
- load_interfaces();
- get_myname(*myname?NULL:myname,NULL);
- strupper(myname);
-
- if (tar_type) {
- recurse=True;
-
- if (open_sockets(port)) {
- char *InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- char *OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- int ret;
-
- if ((InBuffer == NULL) || (OutBuffer == NULL))
- return(1);
-
- bzero(OutBuffer,smb_size);
- if (!send_login(InBuffer,OutBuffer,True,True))
- return(False);
-
- if (*base_directory) do_cd(base_directory);
-
- ret=process_tar(InBuffer, OutBuffer);
-
- send_logout();
- close_sockets();
- return(ret);
- } else
- return(1);
- }
-
- if (*query_host)
- {
- int ret = 0;
- sprintf(service,"\\\\%s\\IPC$",query_host);
- strupper(service);
- connect_as_ipc = True;
- if (open_sockets(port))
- {
-#if 0
- *username = 0;
-#endif
- if (!send_login(NULL,NULL,True,True))
- return(1);
-
- server_info();
- if (!browse_host(True)) {
- sleep(1);
- browse_host(True);
- }
- if (!list_servers(workgroup)) {
- sleep(1);
- list_servers(workgroup);
- }
-
- send_logout();
- close_sockets();
- }
-
- return(ret);
- }
-
- if (message)
- {
- int ret = 0;
- if (open_sockets(port))
- {
- pstring inbuf,outbuf;
- bzero(outbuf,smb_size);
- if (!send_session_request(inbuf,outbuf))
- return(1);
-
- send_message(inbuf,outbuf);
-
- close_sockets();
- }
-
- return(ret);
- }
-
- if (open_sockets(port))
- {
- if (!process(base_directory))
- {
- close_sockets();
- return(1);
- }
- close_sockets();
- }
- else
- return(1);
-
- return(0);
-}
-
-
-/* error code stuff - put together by Merik Karman
- merik@blackadder.dsh.oz.au */
-
-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."},
- {"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."},
- {"ERRinvgroup",2455,"Invalid workgroup (try the -W option)"},
- {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,"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."},
- {"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,"An 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."},
- {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 a SMB error string from a SMB buffer
-****************************************************************************/
-char *smb_errstr(char *inbuf)
-{
- static pstring ret;
- int class = CVAL(inbuf,smb_rcls);
- int num = SVAL(inbuf,smb_err);
- int i,j;
-
- for (i=0;err_classes[i].class;i++)
- if (err_classes[i].code == class)
- {
- if (err_classes[i].err_msgs)
- {
- err_code_struct *err = err_classes[i].err_msgs;
- for (j=0;err[j].name;j++)
- if (num == err[j].code)
- {
- if (DEBUGLEVEL > 0)
- sprintf(ret,"%s - %s (%s)",err_classes[i].class,
- err[j].name,err[j].message);
- else
- sprintf(ret,"%s - %s",err_classes[i].class,err[j].name);
- return ret;
- }
- }
-
- sprintf(ret,"%s - %d",err_classes[i].class,num);
- return ret;
- }
-
- sprintf(ret,"Error: Unknown error (%d,%d)",class,num);
- return(ret);
-}
diff --git a/source/client/clientutil.c b/source/client/clientutil.c
deleted file mode 100644
index 01b4a093214..00000000000
--- a/source/client/clientutil.c
+++ /dev/null
@@ -1,1040 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- SMB client
- Copyright (C) Andrew Tridgell 1994-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.
-*/
-
-#ifdef SYSLOG
-#undef SYSLOG
-#endif
-
-#include "includes.h"
-
-#ifndef REGISTER
-#define REGISTER 0
-#endif
-
-pstring service="";
-pstring desthost="";
-extern pstring myname;
-pstring password = "";
-pstring username="";
-pstring workgroup=WORKGROUP;
-BOOL got_pass = False;
-BOOL connect_as_printer = False;
-BOOL connect_as_ipc = False;
-
-char cryptkey[8];
-BOOL doencrypt=False;
-
-extern pstring user_socket_options;
-
-/* 30 second timeout on most commands */
-#define CLIENT_TIMEOUT (30*1000)
-#define SHORT_TIMEOUT (5*1000)
-
-int name_type = 0x20;
-
-int max_protocol = PROTOCOL_NT1;
-
-BOOL readbraw_supported = False;
-BOOL writebraw_supported = False;
-
-extern int DEBUGLEVEL;
-
-int cnum = 0;
-int pid = 0;
-int gid = 0;
-int uid = 0;
-int mid = 0;
-
-int max_xmit = BUFFER_SIZE;
-
-BOOL have_ip = False;
-
-struct in_addr dest_ip;
-
-extern int Protocol;
-
-extern int Client;
-
-
-/****************************************************************************
-setup basics in a outgoing packet
-****************************************************************************/
-void cli_setup_pkt(char *outbuf)
-{
- SSVAL(outbuf,smb_pid,pid);
- SSVAL(outbuf,smb_uid,uid);
- SSVAL(outbuf,smb_mid,mid);
- if (Protocol > PROTOCOL_CORE)
- {
- SCVAL(outbuf,smb_flg,0x8);
- SSVAL(outbuf,smb_flg2,0x1);
- }
-}
-
-/****************************************************************************
- receive a SMB trans or trans2 response allocating the necessary memory
- ****************************************************************************/
-BOOL cli_receive_trans_response(char *inbuf,int trans,int *data_len,
- int *param_len, char **data,char **param)
-{
- int total_data=0;
- int total_param=0;
- int this_data,this_param;
-
- *data_len = *param_len = 0;
-
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
- show_msg(inbuf);
-
- /* sanity check */
- if (CVAL(inbuf,smb_com) != trans)
- {
- DEBUG(0,("Expected %s response, got command 0x%02x\n",
- trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(inbuf,smb_com)));
- return(False);
- }
- if (CVAL(inbuf,smb_rcls) != 0)
- return(False);
-
- /* parse out the lengths */
- total_data = SVAL(inbuf,smb_tdrcnt);
- total_param = SVAL(inbuf,smb_tprcnt);
-
- /* allocate it */
- *data = Realloc(*data,total_data);
- *param = Realloc(*param,total_param);
-
- while (1)
- {
- this_data = SVAL(inbuf,smb_drcnt);
- this_param = SVAL(inbuf,smb_prcnt);
-
- if (this_data + *data_len > total_data ||
- this_param + *param_len > total_param) {
- DEBUG(1,("Data overflow in cli_receive_trans_response\n"));
- return False;
- }
-
- if (this_data)
- memcpy(*data + SVAL(inbuf,smb_drdisp),
- smb_base(inbuf) + SVAL(inbuf,smb_droff),
- this_data);
- if (this_param)
- memcpy(*param + SVAL(inbuf,smb_prdisp),
- smb_base(inbuf) + SVAL(inbuf,smb_proff),
- this_param);
- *data_len += this_data;
- *param_len += this_param;
-
- /* parse out the total lengths again - they can shrink! */
- total_data = SVAL(inbuf,smb_tdrcnt);
- total_param = SVAL(inbuf,smb_tprcnt);
-
- if (total_data <= *data_len && total_param <= *param_len)
- break;
-
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
- show_msg(inbuf);
-
- /* sanity check */
- if (CVAL(inbuf,smb_com) != trans)
- {
- DEBUG(0,("Expected %s response, got command 0x%02x\n",
- trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(inbuf,smb_com)));
- return(False);
- }
- if (CVAL(inbuf,smb_rcls) != 0)
- return(False);
- }
-
- return(True);
-}
-
-/****************************************************************************
-send a session request
-****************************************************************************/
-BOOL cli_send_session_request(char *inbuf, char *outbuf)
-{
- fstring dest;
- char *p;
- int len = 4;
- /* send a session request (RFC 8002) */
-
- fstrcpy(dest,desthost);
-
- p = strchr(dest,'.');
- if (p) *p = 0;
-
- /* put in the destination name */
- p = outbuf+len;
- name_mangle(dest,p,name_type);
- len += name_len(p);
-
- /* and my name */
- p = outbuf+len;
- name_mangle(myname,p,0);
- len += name_len(p);
-
- /* setup the packet length */
- _smb_setlen(outbuf,len);
- CVAL(outbuf,0) = 0x81;
-
- send_smb(Client,outbuf);
- DEBUG(5,("Sent session request\n"));
-
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,0) == 0x84) /* C. Hoch 9/14/95 Start */
- {
- /* For information, here is the response structure.
- * We do the byte-twiddling to for portability.
- struct RetargetResponse{
- unsigned char type;
- unsigned char flags;
- int16 length;
- int32 ip_addr;
- int16 port;
- };
- */
- extern int Client;
- int port = (CVAL(inbuf,8)<<8)+CVAL(inbuf,9);
- /* SESSION RETARGET */
- putip((char *)&dest_ip,inbuf+4);
-
- close_sockets();
- Client = open_socket_out(SOCK_STREAM, &dest_ip, port, SHORT_CONNECT_TIMEOUT);
- if (Client == -1)
- return False;
-
- DEBUG(5,("Retargeted\n"));
-
- set_socket_options(Client,user_socket_options);
-
- /* Try again */
- return cli_send_session_request(inbuf,outbuf);
- } /* C. Hoch 9/14/95 End */
-
-
- if (CVAL(inbuf,0) != 0x82)
- {
- int ecode = CVAL(inbuf,4);
- DEBUG(0,("Session request failed (%d,%d) with myname=%s destname=%s\n",
- CVAL(inbuf,0),ecode,myname,desthost));
- switch (ecode)
- {
- case 0x80:
- DEBUG(0,("Not listening on called name\n"));
- DEBUG(0,("Try to connect to another name (instead of %s)\n",desthost));
- DEBUG(0,("You may find the -I option useful for this\n"));
- break;
- case 0x81:
- DEBUG(0,("Not listening for calling name\n"));
- DEBUG(0,("Try to connect as another name (instead of %s)\n",myname));
- DEBUG(0,("You may find the -n option useful for this\n"));
- break;
- case 0x82:
- DEBUG(0,("Called name not present\n"));
- DEBUG(0,("Try to connect to another name (instead of %s)\n",desthost));
- DEBUG(0,("You may find the -I option useful for this\n"));
- break;
- case 0x83:
- DEBUG(0,("Called name present, but insufficient resources\n"));
- DEBUG(0,("Perhaps you should try again later?\n"));
- break;
- default:
- DEBUG(0,("Unspecified error 0x%X\n",ecode));
- DEBUG(0,("Your server software is being unfriendly\n"));
- break;
- }
- return(False);
- }
- return(True);
-}
-
-
-static struct {
- int prot;
- char *name;
- }
-prots[] =
- {
- {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"},
- {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
- {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
- {PROTOCOL_LANMAN1,"LANMAN1.0"},
- {PROTOCOL_LANMAN2,"LM1.2X002"},
- {PROTOCOL_LANMAN2,"Samba"},
- {PROTOCOL_NT1,"NT LM 0.12"},
- {PROTOCOL_NT1,"NT LANMAN 1.0"},
- {-1,NULL}
- };
-
-/****************************************************************************
-send a login command
-****************************************************************************/
-BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setup)
-{
- BOOL was_null = (!inbuf && !outbuf);
- int sesskey=0;
- time_t servertime = 0;
- extern int serverzone;
- int sec_mode=0;
- int crypt_len;
- int max_vcs=0;
- char *pass = NULL;
- pstring dev;
- char *p;
- int numprots;
-
- if (was_null)
- {
- inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- }
-
- pstrcpy(dev,"A:");
- if (connect_as_printer)
- pstrcpy(dev,"LPT1:");
- if (connect_as_ipc)
- pstrcpy(dev,"IPC");
-
-
- if (start_session && !cli_send_session_request(inbuf,outbuf))
- {
- if (was_null)
- {
- free(inbuf);
- free(outbuf);
- }
- return(False);
- }
-
- bzero(outbuf,smb_size);
-
- /* setup the protocol strings */
- {
- int plength;
-
- for (plength=0,numprots=0;
- prots[numprots].name && prots[numprots].prot<=max_protocol;
- numprots++)
- plength += strlen(prots[numprots].name)+2;
-
- set_message(outbuf,0,plength,True);
-
- p = smb_buf(outbuf);
- for (numprots=0;
- prots[numprots].name && prots[numprots].prot<=max_protocol;
- numprots++)
- {
- *p++ = 2;
- strcpy(p,prots[numprots].name);
- p += strlen(p) + 1;
- }
- }
-
- CVAL(outbuf,smb_com) = SMBnegprot;
- cli_setup_pkt(outbuf);
-
- CVAL(smb_buf(outbuf),0) = 2;
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- show_msg(inbuf);
-
- if (CVAL(inbuf,smb_rcls) != 0 || ((int)SVAL(inbuf,smb_vwv0) >= numprots))
- {
- DEBUG(0,("SMBnegprot failed. myname=%s destname=%s - %s \n",
- myname,desthost,smb_errstr(inbuf)));
- if (was_null)
- {
- free(inbuf);
- free(outbuf);
- }
- return(False);
- }
-
- Protocol = prots[SVAL(inbuf,smb_vwv0)].prot;
-
-
- if (Protocol < PROTOCOL_NT1) {
- sec_mode = SVAL(inbuf,smb_vwv1);
- max_xmit = SVAL(inbuf,smb_vwv2);
- sesskey = IVAL(inbuf,smb_vwv6);
- serverzone = SVALS(inbuf,smb_vwv10)*60;
- /* this time is converted to GMT by make_unix_date */
- servertime = make_unix_date(inbuf+smb_vwv8);
- if (Protocol >= PROTOCOL_COREPLUS) {
- readbraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x1) != 0);
- writebraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x2) != 0);
- }
- crypt_len = smb_buflen(inbuf);
- memcpy(cryptkey,smb_buf(inbuf),8);
- DEBUG(5,("max mux %d\n",SVAL(inbuf,smb_vwv3)));
- max_vcs = SVAL(inbuf,smb_vwv4);
- DEBUG(5,("max vcs %d\n",max_vcs));
- DEBUG(5,("max blk %d\n",SVAL(inbuf,smb_vwv5)));
- } else {
- /* NT protocol */
- sec_mode = CVAL(inbuf,smb_vwv1);
- max_xmit = IVAL(inbuf,smb_vwv3+1);
- sesskey = IVAL(inbuf,smb_vwv7+1);
- serverzone = SVALS(inbuf,smb_vwv15+1)*60;
- /* this time arrives in real GMT */
- servertime = interpret_long_date(inbuf+smb_vwv11+1);
- crypt_len = CVAL(inbuf,smb_vwv16+1);
- memcpy(cryptkey,smb_buf(inbuf),8);
- if (IVAL(inbuf,smb_vwv9+1) & 1)
- readbraw_supported = writebraw_supported = True;
- DEBUG(5,("max mux %d\n",SVAL(inbuf,smb_vwv1+1)));
- max_vcs = SVAL(inbuf,smb_vwv2+1);
- DEBUG(5,("max vcs %d\n",max_vcs));
- DEBUG(5,("max raw %d\n",IVAL(inbuf,smb_vwv5+1)));
- DEBUG(5,("capabilities 0x%x\n",IVAL(inbuf,smb_vwv9+1)));
- }
-
- DEBUG(5,("Sec mode %d\n",SVAL(inbuf,smb_vwv1)));
- DEBUG(5,("max xmt %d\n",max_xmit));
- DEBUG(5,("Got %d byte crypt key\n",crypt_len));
- DEBUG(5,("Chose protocol [%s]\n",prots[SVAL(inbuf,smb_vwv0)].name));
-
- doencrypt = ((sec_mode & 2) != 0);
-
- if (servertime) {
- static BOOL done_time = False;
- if (!done_time) {
- DEBUG(1,("Server time is %sTimezone is UTC%+02.1f\n",
- asctime(LocalTime(&servertime)),
- -(double)(serverzone/3600.0)));
- done_time = True;
- }
- }
-
- get_pass:
-
- if (got_pass)
- pass = password;
- else
- pass = (char *)getpass("Password: ");
-
- if(pass == NULL)
- {
- DEBUG(0, ("cli_send_login : no password available - logon failed.\n"));
- return False;
- }
-
- if (Protocol >= PROTOCOL_LANMAN1 && use_setup)
- {
- fstring pword;
- int passlen = strlen(pass)+1;
- fstrcpy(pword,pass);
-
- if (doencrypt && *pass) {
- DEBUG(5,("Using encrypted passwords\n"));
- passlen = 24;
- SMBencrypt((uchar *)pass,(uchar *)cryptkey,(uchar *)pword);
- }
-
- /* if in share level security then don't send a password now */
- if (!(sec_mode & 1)) {fstrcpy(pword, "");passlen=1;}
-
- /* send a session setup command */
- bzero(outbuf,smb_size);
-
- if (passlen > MAX_PASS_LEN) {
- DEBUG(1,("password too long %d\n", passlen));
- return False;
- }
-
- if (Protocol < PROTOCOL_NT1) {
- set_message(outbuf,10,1 + strlen(username) + passlen,True);
- CVAL(outbuf,smb_com) = SMBsesssetupX;
- cli_setup_pkt(outbuf);
-
- CVAL(outbuf,smb_vwv0) = 0xFF;
- SSVAL(outbuf,smb_vwv2,max_xmit);
- SSVAL(outbuf,smb_vwv3,2);
- SSVAL(outbuf,smb_vwv4,max_vcs-1);
- SIVAL(outbuf,smb_vwv5,sesskey);
- SSVAL(outbuf,smb_vwv7,passlen);
- p = smb_buf(outbuf);
- memcpy(p,pword,passlen);
- p += passlen;
- strcpy(p,username);
- } else {
- if (!doencrypt) passlen--;
- /* for Win95 */
- set_message(outbuf,13,0,True);
- CVAL(outbuf,smb_com) = SMBsesssetupX;
- cli_setup_pkt(outbuf);
-
- CVAL(outbuf,smb_vwv0) = 0xFF;
- SSVAL(outbuf,smb_vwv2,BUFFER_SIZE);
- SSVAL(outbuf,smb_vwv3,2);
- SSVAL(outbuf,smb_vwv4,getpid());
- SIVAL(outbuf,smb_vwv5,sesskey);
- SSVAL(outbuf,smb_vwv7,passlen);
- SSVAL(outbuf,smb_vwv8,0);
- p = smb_buf(outbuf);
- memcpy(p,pword,passlen); p += SVAL(outbuf,smb_vwv7);
- strcpy(p,username);p = skip_string(p,1);
- strcpy(p,workgroup);p = skip_string(p,1);
- strcpy(p,"Unix");p = skip_string(p,1);
- strcpy(p,"Samba");p = skip_string(p,1);
- set_message(outbuf,13,PTR_DIFF(p,smb_buf(outbuf)),False);
- }
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- show_msg(inbuf);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- if (! *pass &&
- ((CVAL(inbuf,smb_rcls) == ERRDOS &&
- SVAL(inbuf,smb_err) == ERRnoaccess) ||
- (CVAL(inbuf,smb_rcls) == ERRSRV &&
- SVAL(inbuf,smb_err) == ERRbadpw)))
- {
- got_pass = False;
- DEBUG(5,("resending login\n"));
- goto get_pass;
- }
-
- DEBUG(0,("Session setup failed for username=%s myname=%s destname=%s %s\n",
- username,myname,desthost,smb_errstr(inbuf)));
- DEBUG(0,("You might find the -U or -n options useful\n"));
- DEBUG(0,("Sometimes you have to use `-n USERNAME' (particularly with OS/2)\n"));
- DEBUG(0,("Some servers also insist on uppercase-only passwords\n"));
- if (was_null)
- {
- free(inbuf);
- free(outbuf);
- }
- return(False);
- }
-
- if (Protocol >= PROTOCOL_NT1) {
- char *domain,*os,*lanman;
- p = smb_buf(inbuf);
- os = p;
- lanman = skip_string(os,1);
- domain = skip_string(lanman,1);
- if (*domain || *os || *lanman)
- DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",domain,os,lanman));
- }
-
- /* use the returned uid from now on */
- if (SVAL(inbuf,smb_uid) != uid)
- DEBUG(5,("Server gave us a UID of %d. We gave %d\n",
- SVAL(inbuf,smb_uid),uid));
- uid = SVAL(inbuf,smb_uid);
- }
-
- /* now we've got a connection - send a tcon message */
- bzero(outbuf,smb_size);
-
- if (strncmp(service,"\\\\",2) != 0)
- {
- DEBUG(0,("\nWarning: Your service name doesn't start with \\\\. This is probably incorrect.\n"));
- DEBUG(0,("Perhaps try replacing each \\ with \\\\ on the command line?\n\n"));
- }
-
-
- again2:
-
- {
- int passlen = strlen(pass)+1;
- fstring pword;
- fstrcpy(pword,pass);
-
- if (doencrypt && *pass) {
- passlen=24;
- SMBencrypt((uchar *)pass,(uchar *)cryptkey,(uchar *)pword);
- }
-
- /* if in user level security then don't send a password now */
- if ((sec_mode & 1)) {
- fstrcpy(pword, ""); passlen=1;
- }
-
- set_message(outbuf,4,2 + strlen(service) + passlen + strlen(dev),True);
- CVAL(outbuf,smb_com) = SMBtconX;
- cli_setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,0xFF);
- SSVAL(outbuf,smb_vwv3,passlen);
-
- p = smb_buf(outbuf);
- memcpy(p,pword,passlen);
- p += passlen;
- strcpy(p,service);
- p = skip_string(p,1);
- strcpy(p,dev);
- }
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- /* trying again with a blank password */
- if (CVAL(inbuf,smb_rcls) != 0 &&
- (int)strlen(pass) > 0 &&
- !doencrypt &&
- Protocol >= PROTOCOL_LANMAN1)
- {
- DEBUG(2,("first SMBtconX failed, trying again. %s\n",smb_errstr(inbuf)));
- strcpy(pass,"");
- goto again2;
- }
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("SMBtconX failed. %s\n",smb_errstr(inbuf)));
- DEBUG(0,("Perhaps you are using the wrong sharename, username or password?\n"));
- DEBUG(0,("Some servers insist that these be in uppercase\n"));
- if (was_null)
- {
- free(inbuf);
- free(outbuf);
- }
- return(False);
- }
-
-
- max_xmit = MIN(max_xmit,BUFFER_SIZE-4);
- if (max_xmit <= 0)
- max_xmit = BUFFER_SIZE - 4;
-
- cnum = SVAL(inbuf,smb_tid);
-
- DEBUG(5,("Connected with cnum=%d max_xmit=%d\n",cnum,max_xmit));
-
- if (was_null)
- {
- free(inbuf);
- free(outbuf);
- }
- return True;
-}
-
-
-/****************************************************************************
-send a logout command
-****************************************************************************/
-void cli_send_logout(void)
-{
- pstring inbuf,outbuf;
-
- bzero(outbuf,smb_size);
- set_message(outbuf,0,0,True);
- CVAL(outbuf,smb_com) = SMBtdis;
- SSVAL(outbuf,smb_tid,cnum);
- cli_setup_pkt(outbuf);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,SHORT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("SMBtdis failed %s\n",smb_errstr(inbuf)));
- }
-
-
-#ifdef STATS
- stats_report();
-#endif
- exit(0);
-}
-
-
-
-/****************************************************************************
-call a remote api
-****************************************************************************/
-BOOL cli_call_api(int prcnt,int drcnt,int mprcnt,int mdrcnt,int *rprcnt,
- int *rdrcnt, char *param,char *data, char **rparam,char **rdata)
-{
- static char *inbuf=NULL;
- static char *outbuf=NULL;
-
- if (!inbuf) inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- if (!outbuf) outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
- cli_send_trans_request(outbuf,SMBtrans,"\\PIPE\\LANMAN",0,0,
- data,param,NULL,
- drcnt,prcnt,0,
- mdrcnt,mprcnt,0);
-
- return (cli_receive_trans_response(inbuf,SMBtrans,
- rdrcnt,rprcnt,
- rdata,rparam));
-}
-
-/****************************************************************************
- send a SMB trans or trans2 request
- ****************************************************************************/
-BOOL cli_send_trans_request(char *outbuf, int trans, char *name, int fid, int flags,
- char *data,char *param,uint16 *setup, int ldata,int lparam,
- int lsetup,int mdata,int mparam,int msetup)
-{
- int i;
- int this_ldata,this_lparam;
- int tot_data=0,tot_param=0;
- char *outdata,*outparam;
- pstring inbuf;
- char *p;
-
- this_lparam = MIN(lparam,max_xmit - (500+lsetup*SIZEOFWORD)); /* hack */
- this_ldata = MIN(ldata,max_xmit - (500+lsetup*SIZEOFWORD+this_lparam));
-
- bzero(outbuf,smb_size);
- set_message(outbuf,14+lsetup,0,True);
- CVAL(outbuf,smb_com) = trans;
- SSVAL(outbuf,smb_tid,cnum);
- cli_setup_pkt(outbuf);
-
- outparam = smb_buf(outbuf)+(trans==SMBtrans ? strlen(name)+1 : 3);
- outdata = outparam+this_lparam;
-
- /* primary request */
- SSVAL(outbuf,smb_tpscnt,lparam); /* tpscnt */
- SSVAL(outbuf,smb_tdscnt,ldata); /* tdscnt */
- SSVAL(outbuf,smb_mprcnt,mparam); /* mprcnt */
- SSVAL(outbuf,smb_mdrcnt,mdata); /* mdrcnt */
- SCVAL(outbuf,smb_msrcnt,msetup); /* msrcnt */
- SSVAL(outbuf,smb_flags,flags); /* flags */
- SIVAL(outbuf,smb_timeout,0); /* timeout */
- SSVAL(outbuf,smb_pscnt,this_lparam); /* pscnt */
- SSVAL(outbuf,smb_psoff,smb_offset(outparam,outbuf)); /* psoff */
- SSVAL(outbuf,smb_dscnt,this_ldata); /* dscnt */
- SSVAL(outbuf,smb_dsoff,smb_offset(outdata,outbuf)); /* dsoff */
- SCVAL(outbuf,smb_suwcnt,lsetup); /* suwcnt */
- for (i=0;i<lsetup;i++) /* setup[] */
- SSVAL(outbuf,smb_setup+i*SIZEOFWORD,setup[i]);
- p = smb_buf(outbuf);
- if (trans==SMBtrans)
- strcpy(p,name); /* name[] */
- else
- {
- *p++ = 0; /* put in a null smb_name */
- *p++ = 'D'; *p++ = ' '; /* this was added because OS/2 does it */
- }
- if (this_lparam) /* param[] */
- memcpy(outparam,param,this_lparam);
- if (this_ldata) /* data[] */
- memcpy(outdata,data,this_ldata);
- set_message(outbuf,14+lsetup, /* wcnt, bcc */
- PTR_DIFF(outdata+this_ldata,smb_buf(outbuf)),False);
-
- show_msg(outbuf);
- send_smb(Client,outbuf);
-
- if (this_ldata < ldata || this_lparam < lparam)
- {
- /* receive interim response */
- if (!receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("%s request failed (%s)\n",
- trans==SMBtrans?"SMBtrans":"SMBtrans2", smb_errstr(inbuf)));
- return(False);
- }
-
- tot_data = this_ldata;
- tot_param = this_lparam;
-
- while (tot_data < ldata || tot_param < lparam)
- {
- this_lparam = MIN(lparam-tot_param,max_xmit - 500); /* hack */
- this_ldata = MIN(ldata-tot_data,max_xmit - (500+this_lparam));
-
- set_message(outbuf,trans==SMBtrans?8:9,0,True);
- CVAL(outbuf,smb_com) = trans==SMBtrans ? SMBtranss : SMBtranss2;
-
- outparam = smb_buf(outbuf);
- outdata = outparam+this_lparam;
-
- /* secondary request */
- SSVAL(outbuf,smb_tpscnt,lparam); /* tpscnt */
- SSVAL(outbuf,smb_tdscnt,ldata); /* tdscnt */
- SSVAL(outbuf,smb_spscnt,this_lparam); /* pscnt */
- SSVAL(outbuf,smb_spsoff,smb_offset(outparam,outbuf)); /* psoff */
- SSVAL(outbuf,smb_spsdisp,tot_param); /* psdisp */
- SSVAL(outbuf,smb_sdscnt,this_ldata); /* dscnt */
- SSVAL(outbuf,smb_sdsoff,smb_offset(outdata,outbuf)); /* dsoff */
- SSVAL(outbuf,smb_sdsdisp,tot_data); /* dsdisp */
- if (trans==SMBtrans2)
- SSVAL(outbuf,smb_sfid,fid); /* fid */
- if (this_lparam) /* param[] */
- memcpy(outparam,param,this_lparam);
- if (this_ldata) /* data[] */
- memcpy(outdata,data,this_ldata);
- set_message(outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */
- PTR_DIFF(outdata+this_ldata,smb_buf(outbuf)),False);
-
- show_msg(outbuf);
- send_smb(Client,outbuf);
-
- tot_data += this_ldata;
- tot_param += this_lparam;
- }
- }
-
- return(True);
-}
-
-
-/****************************************************************************
-open the client sockets
-****************************************************************************/
-BOOL cli_open_sockets(int port)
-{
- static int last_port;
- char *host;
- pstring service2;
- extern int Client;
-
- if (port == 0) port=last_port;
- last_port=port;
-
- strupper(service);
-
- if (*desthost)
- {
- host = desthost;
- }
- else
- {
- pstrcpy(service2,service);
- host = strtok(service2,"\\/");
- pstrcpy(desthost,host);
- }
-
- DEBUG(5,("Opening sockets\n"));
-
- if (*myname == 0)
- get_myname(myname,NULL);
- strupper(myname);
-
- if (!have_ip)
- {
- struct hostent *hp;
-
- if ((hp = Get_Hostbyname(host)) == 0)
- {
- DEBUG(0,("Get_Hostbyname: Unknown host %s.\n",host));
- return False;
- }
-
- putip((char *)&dest_ip,(char *)hp->h_addr);
- }
-
- Client = open_socket_out(SOCK_STREAM, &dest_ip, port, SHORT_CONNECT_TIMEOUT);
- if (Client == -1)
- return False;
-
- DEBUG(5,("Connected\n"));
-
- set_socket_options(Client,user_socket_options);
-
- return True;
-}
-
-/****************************************************************************
-close and open the connection again
-****************************************************************************/
-BOOL cli_reopen_connection(char *inbuf,char *outbuf)
-{
- static int open_count=0;
-
- open_count++;
-
- if (open_count>5) return(False);
-
- DEBUG(1,("Trying to re-open connection\n"));
-
- set_message(outbuf,0,0,True);
- SCVAL(outbuf,smb_com,SMBtdis);
- SSVAL(outbuf,smb_tid,cnum);
- cli_setup_pkt(outbuf);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,SHORT_TIMEOUT);
-
- close_sockets();
- if (!cli_open_sockets(0)) return(False);
-
- return(cli_send_login(inbuf,outbuf,True,True));
-}
-
-/* error code stuff - put together by Merik Karman
- merik@blackadder.dsh.oz.au */
-
-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."},
- {"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."},
- {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,"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."},
- {"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."},
- {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 a SMB error string from a SMB buffer
-****************************************************************************/
-char *smb_errstr(char *inbuf)
-{
- static pstring ret;
- int class = CVAL(inbuf,smb_rcls);
- int num = SVAL(inbuf,smb_err);
- int i,j;
-
- for (i=0;err_classes[i].class;i++)
- if (err_classes[i].code == class)
- {
- if (err_classes[i].err_msgs)
- {
- err_code_struct *err = err_classes[i].err_msgs;
- for (j=0;err[j].name;j++)
- if (num == err[j].code)
- {
- if (DEBUGLEVEL > 0)
- sprintf(ret,"%s - %s (%s)",err_classes[i].class,
- err[j].name,err[j].message);
- else
- sprintf(ret,"%s - %s",err_classes[i].class,err[j].name);
- return ret;
- }
- }
-
- sprintf(ret,"%s - %d",err_classes[i].class,num);
- return ret;
- }
-
- sprintf(ret,"ERROR: Unknown error (%d,%d)",class,num);
- return(ret);
-}
diff --git a/source/client/clitar.c b/source/client/clitar.c
deleted file mode 100644
index c085cd9e5a1..00000000000
--- a/source/client/clitar.c
+++ /dev/null
@@ -1,1771 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Tar Extensions
- Copyright (C) Ricky Poulten 1995-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.
-*/
-
-
-#include "includes.h"
-#include "clitar.h"
-
-extern BOOL recurse;
-
-#define SEPARATORS " \t\n\r"
-extern int DEBUGLEVEL;
-extern int Client;
-
-/* These defines are for the do_setrattr routine, to indicate
- * setting and reseting of file attributes in the function call */
-#define ATTRSET 1
-#define ATTRRESET 0
-
-static int attribute = aDIR | aSYSTEM | aHIDDEN;
-
-#ifndef CLIENT_TIMEOUT
-#define CLIENT_TIMEOUT (30*1000)
-#endif
-
-static char *tarbuf;
-static int tp, ntarf, tbufsiz, ttarf;
-/* Incremental mode */
-BOOL tar_inc=False;
-/* Reset archive bit */
-BOOL tar_reset=False;
-/* Include / exclude mode (true=include, false=exclude) */
-BOOL tar_excl=True;
-char tar_type='\0';
-static char **cliplist=NULL;
-static int clipn=0;
-
-extern file_info def_finfo;
-extern BOOL lowercase;
-extern int cnum;
-extern BOOL readbraw_supported;
-extern int max_xmit;
-extern pstring cur_dir;
-extern int get_total_time_ms;
-extern int get_total_size;
-extern int Protocol;
-
-int blocksize=20;
-int tarhandle;
-
-static void writetarheader();
-static void do_atar();
-static void do_tar();
-static void oct_it();
-static void fixtarname();
-static int dotarbuf();
-static void dozerobuf();
-static void dotareof();
-static void initarbuf();
-static int do_setrattr();
-
-/* restore functions */
-static long readtarheader();
-static long unoct();
-static void do_tarput();
-static void unfixtarname();
-
-/*
- * tar specific utitlities
- */
-
-/****************************************************************************
-Write a tar header to buffer
-****************************************************************************/
-static void writetarheader(int f, char *aname, int size, time_t mtime,
- char *amode)
-{
- union hblock hb;
- int i, chk, l;
- char *jp;
-
- memset(hb.dummy, 0, sizeof(hb.dummy));
-
- l=strlen(aname);
- if (l >= NAMSIZ) {
- /* write a GNU tar style long header */
- char *b;
- b = (char *)malloc(l+TBLOCK+100);
- if (!b) {
- DEBUG(0,("out of memory\n"));
- exit(1);
- }
- writetarheader(f, "/./@LongLink", l+1, 0, " 0 \0");
- memset(b, 0, l+TBLOCK+100);
- fixtarname(b, aname, l+1);
- i = strlen(b)+1;
- dotarbuf(f, b, TBLOCK*((i+(TBLOCK-1)/TBLOCK)));
- free(b);
- }
-
- /* use l + 1 to do the null too */
- fixtarname(hb.dbuf.name, aname, (l >= NAMSIZ) ? NAMSIZ : l + 1);
-
- if (lowercase)
- strlower(hb.dbuf.name);
-
- /* write out a "standard" tar format header */
-
- hb.dbuf.name[NAMSIZ-1]='\0';
- strcpy(hb.dbuf.mode, amode);
- oct_it(0L, 8, hb.dbuf.uid);
- oct_it(0L, 8, hb.dbuf.gid);
- oct_it((long) size, 13, hb.dbuf.size);
- oct_it((long) mtime, 13, hb.dbuf.mtime);
- memcpy(hb.dbuf.chksum, " ", sizeof(hb.dbuf.chksum));
- memset(hb.dbuf.linkname, 0, NAMSIZ);
- if (strcmp("/./@LongLink", aname) == 0) {
- /* we're doing a GNU tar long filename */
- hb.dbuf.linkflag='L';
- } else {
- hb.dbuf.linkflag='0';
- }
-
- for (chk=0, i=sizeof(hb.dummy), jp=hb.dummy; --i>=0;) chk+=(0xFF & *jp++);
-
- oct_it((long) chk, 8, hb.dbuf.chksum);
- hb.dbuf.chksum[6] = '\0';
-
- (void) dotarbuf(f, hb.dummy, sizeof(hb.dummy));
-}
-
-/****************************************************************************
-Read a tar header into a hblock structure, and validate
-***************************************************************************/
-static long readtarheader(union hblock *hb, file_info *finfo, char *prefix)
-{
- long chk, fchk;
- int i;
- char *jp;
-
- /*
- * read in a "standard" tar format header - we're not that interested
- * in that many fields, though
- */
-
- /* check the checksum */
- for (chk=0, i=sizeof(hb->dummy), jp=hb->dummy; --i>=0;) chk+=(0xFF & *jp++);
-
- if (chk == 0)
- return chk;
-
- /* compensate for blanks in chksum header */
- for (i=sizeof(hb->dbuf.chksum), jp=hb->dbuf.chksum; --i>=0;)
- chk-=(0xFF & *jp++);
-
- chk += ' ' * sizeof(hb->dbuf.chksum);
-
- fchk=unoct(hb->dbuf.chksum, sizeof(hb->dbuf.chksum));
-
- DEBUG(5, ("checksum totals chk=%d fchk=%d chksum=%s\n",
- chk, fchk, hb->dbuf.chksum));
-
- if (fchk != chk)
- {
- DEBUG(0, ("checksums don't match %d %d\n", fchk, chk));
- return -1;
- }
-
- strcpy(finfo->name, prefix);
-
- /* use l + 1 to do the null too; do prefix - prefcnt to zap leading slash */
- unfixtarname(finfo->name + strlen(prefix), hb->dbuf.name,
- strlen(hb->dbuf.name) + 1);
-
-/* can't handle links at present */
- if (hb->dbuf.linkflag != '0') {
- if (hb->dbuf.linkflag == 0) {
- DEBUG(6, ("Warning: NULL link flag (gnu tar archive ?) %s\n",
- finfo->name));
- } else {
- DEBUG(0, ("this tar file appears to contain some kind of link - ignoring\n"));
- return -2;
- }
- }
-
- if ((unoct(hb->dbuf.mode, sizeof(hb->dbuf.mode)) & S_IFDIR)
- || (*(finfo->name+strlen(finfo->name)-1) == '\\'))
- {
- finfo->mode=aDIR;
- }
- else
- finfo->mode=0; /* we don't care about mode at the moment, we'll
- * just make it a regular file */
- /*
- * Bug fix by richard@sj.co.uk
- *
- * REC: restore times correctly (as does tar)
- * We only get the modification time of the file; set the creation time
- * from the mod. time, and the access time to current time
- */
- finfo->mtime = finfo->ctime = strtol(hb->dbuf.mtime, NULL, 8);
- finfo->atime = time(NULL);
- finfo->size = unoct(hb->dbuf.size, sizeof(hb->dbuf.size));
-
- return True;
-}
-
-/****************************************************************************
-Write out the tar buffer to tape or wherever
-****************************************************************************/
-static int dotarbuf(int f, char *b, int n)
-{
- int fail=1, writ=n;
-
- /* This routine and the next one should be the only ones that do write()s */
- if (tp + n >= tbufsiz)
- {
- int diff;
-
- diff=tbufsiz-tp;
- memcpy(tarbuf + tp, b, diff);
- fail=fail && (1+write(f, tarbuf, tbufsiz));
- n-=diff;
- b+=diff;
- tp=0;
-
- while (n >= tbufsiz)
- {
- fail=fail && (1 + write(f, b, tbufsiz));
- n-=tbufsiz;
- b+=tbufsiz;
- }
- }
- if (n>0) {
- memcpy(tarbuf+tp, b, n);
- tp+=n;
- }
-
- return(fail ? writ : 0);
-}
-
-/****************************************************************************
-Write a zeros to buffer / tape
-****************************************************************************/
-static void dozerobuf(int f, int n)
-{
- /* short routine just to write out n zeros to buffer -
- * used to round files to nearest block
- * and to do tar EOFs */
-
- if (n+tp >= tbufsiz)
- {
- memset(tarbuf+tp, 0, tbufsiz-tp);
- write(f, tarbuf, tbufsiz);
- memset(tarbuf, 0, (tp+=n-tbufsiz));
- }
- else
- {
- memset(tarbuf+tp, 0, n);
- tp+=n;
- }
-}
-
-/****************************************************************************
-Malloc tape buffer
-****************************************************************************/
-static void initarbuf()
-{
- /* initialize tar buffer */
- tbufsiz=blocksize*TBLOCK;
- tarbuf=malloc(tbufsiz);
-
- /* reset tar buffer pointer and tar file counter and total dumped */
- tp=0; ntarf=0; ttarf=0;
-}
-
-/****************************************************************************
-Write two zero blocks at end of file
-****************************************************************************/
-static void dotareof(int f)
-{
- struct stat stbuf;
- /* Two zero blocks at end of file, write out full buffer */
-
- (void) dozerobuf(f, TBLOCK);
- (void) dozerobuf(f, TBLOCK);
-
- if (fstat(f, &stbuf) == -1)
- {
- DEBUG(0, ("Couldn't stat file handle\n"));
- return;
- }
-
- /* Could be a pipe, in which case S_ISREG should fail,
- * and we should write out at full size */
- if (tp > 0) write(f, tarbuf, S_ISREG(stbuf.st_mode) ? tp : tbufsiz);
-}
-
-/****************************************************************************
-(Un)mangle DOS pathname, make nonabsolute
-****************************************************************************/
-static void fixtarname(char *tptr, char *fp, int l)
-{
- /* add a '.' to start of file name, convert from ugly dos \'s in path
- * to lovely unix /'s :-} */
-
- *tptr++='.';
- if(lp_client_code_page() == KANJI_CODEPAGE)
- {
- while (l > 0) {
- if (is_shift_jis (*fp)) {
- *tptr++ = *fp++;
- *tptr++ = *fp++;
- l -= 2;
- } else if (is_kana (*fp)) {
- *tptr++ = *fp++;
- l--;
- } else if (*fp == '\\') {
- *tptr++ = '/';
- fp++;
- l--;
- } else {
- *tptr++ = *fp++;
- l--;
- }
- }
- }
- else
- {
- while (l--)
- {
- *tptr=(*fp == '\\') ? '/' : *fp;
- tptr++;
- fp++;
- }
- }
-}
-
-/****************************************************************************
-Convert from decimal to octal string
-****************************************************************************/
-static void oct_it (register long value, register int ndgs, register char *p)
-{
- /* Converts long to octal string, pads with leading zeros */
-
- /* skip final null, but do final space */
- --ndgs;
- p[--ndgs] = ' ';
-
- /* Loop does at least one digit */
- do {
- p[--ndgs] = '0' + (char) (value & 7);
- value >>= 3;
- }
- while (ndgs > 0 && value != 0);
-
- /* Do leading zeros */
- while (ndgs > 0)
- p[--ndgs] = '0';
-}
-
-/****************************************************************************
-Convert from octal string to long
-***************************************************************************/
-static long unoct(char *p, int ndgs)
-{
- long value=0;
- /* Converts octal string to long, ignoring any non-digit */
-
- while (--ndgs)
- {
- if (isdigit(*p))
- value = (value << 3) | (long) (*p - '0');
-
- p++;
- }
-
- return value;
-}
-
-/****************************************************************************
-Compare two strings in a slash insensitive way, allowing s1 to match s2
-if s1 is an "initial" string (up to directory marker). Thus, if s2 is
-a file in any subdirectory of s1, declare a match.
-***************************************************************************/
-static int strslashcmp(char *s1, char *s2)
-{
- char *s1_0=s1;
-
- while(*s1 && *s2 &&
- (*s1 == *s2
- || tolower(*s1) == tolower(*s2)
- || (*s1 == '\\' && *s2=='/')
- || (*s1 == '/' && *s2=='\\'))) {
- s1++; s2++;
- }
-
- /* if s1 has a trailing slash, it compared equal, so s1 is an "initial"
- string of s2.
- */
- if (!*s1 && s1 != s1_0 && (*(s1-1) == '/' || *(s1-1) == '\\')) return 0;
-
- /* ignore trailing slash on s1 */
- if (!*s2 && (*s1 == '/' || *s1 == '\\') && !*(s1+1)) return 0;
-
- /* check for s1 is an "initial" string of s2 */
- if (*s2 == '/' || *s2 == '\\') return 0;
-
- return *s1-*s2;
-}
-
-/*
- * general smb utility functions
- */
-/****************************************************************************
-Set DOS file attributes
-***************************************************************************/
-static int do_setrattr(char *fname, int attr, int setit)
-{
- /*
- * First get the existing attribs from existing file
- */
- char *inbuf,*outbuf;
- char *p;
- pstring name;
- int fattr;
-
- strcpy(name,fname);
- strcpy(fname,"\\");
- strcat(fname,name);
-
- inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
- if (!inbuf || !outbuf)
- {
- DEBUG(0,("out of memory\n"));
- return False;
- }
-
- /* send an smb getatr message */
-
- memset(outbuf,0,smb_size);
- set_message(outbuf,0,2 + strlen(fname),True);
- CVAL(outbuf,smb_com) = SMBgetatr;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- p = smb_buf(outbuf);
- *p++ = 4;
- strcpy(p,fname);
- p += (strlen(fname)+1);
-
- *p++ = 4;
- *p++ = 0;
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- DEBUG(5,("getatr: %s\n",smb_errstr(inbuf)));
- else
- {
- DEBUG(5,("\nattr 0x%X time %d size %d\n",
- (int)CVAL(inbuf,smb_vwv0),
- SVAL(inbuf,smb_vwv1),
- SVAL(inbuf,smb_vwv3)));
- }
-
- fattr=CVAL(inbuf,smb_vwv0);
-
- /* combine found attributes with bits to be set or reset */
-
- attr=setit ? (fattr | attr) : (fattr & ~attr);
-
- /* now try and set attributes by sending smb reset message */
-
- /* clear out buffer and start again */
- memset(outbuf,0,smb_size);
- set_message(outbuf,8,4 + strlen(fname),True);
- CVAL(outbuf,smb_com) = SMBsetatr;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,attr);
-
- p = smb_buf(outbuf);
- *p++ = 4;
- strcpy(p,fname);
- p += (strlen(fname)+1);
-
- *p++ = 4;
- *p++ = 0;
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("%s setting attributes on file %s\n",
- smb_errstr(inbuf), fname));
- free(inbuf);free(outbuf);
- return(False);
- }
-
- free(inbuf);free(outbuf);
- return(True);
-}
-
-/****************************************************************************
-Create a file on a share
-***************************************************************************/
-static BOOL smbcreat(file_info finfo, int *fnum, char *inbuf, char *outbuf)
-{
- char *p;
- /* *must* be called with buffer ready malloc'ed */
- /* open remote file */
-
- memset(outbuf,0,smb_size);
- set_message(outbuf,3,2 + strlen(finfo.name),True);
- CVAL(outbuf,smb_com) = SMBcreate;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,finfo.mode);
- put_dos_date3(outbuf,smb_vwv1,finfo.mtime);
-
- p = smb_buf(outbuf);
- *p++ = 4;
- strcpy(p,finfo.name);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("%s opening remote file %s\n",smb_errstr(inbuf),
- finfo.name));
- return 0;
- }
-
- *fnum = SVAL(inbuf,smb_vwv0);
- return True;
-}
-
-/****************************************************************************
-Write a file to a share
-***************************************************************************/
-static BOOL smbwrite(int fnum, int n, int low, int high, int left,
- char *bufferp, char *inbuf, char *outbuf)
-{
- /* *must* be called with buffer ready malloc'ed */
-
- memset(outbuf,0,smb_size);
- set_message(outbuf,5,n + 3,True);
-
- memcpy(smb_buf(outbuf)+3, bufferp, n);
-
- set_message(outbuf,5,n + 3, False);
- CVAL(outbuf,smb_com) = SMBwrite;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,fnum);
- SSVAL(outbuf,smb_vwv1,n);
- SIVAL(outbuf,smb_vwv2,low);
- SSVAL(outbuf,smb_vwv4,left);
- CVAL(smb_buf(outbuf),0) = 1;
- SSVAL(smb_buf(outbuf),1,n);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("%s writing remote file\n",smb_errstr(inbuf)));
- return False;
- }
-
- if (n != SVAL(inbuf,smb_vwv0))
- {
- DEBUG(0,("Error: only wrote %d bytes out of %d\n",
- SVAL(inbuf,smb_vwv0), n));
- return False;
- }
-
- return True;
-}
-
-/****************************************************************************
-Close a file on a share
-***************************************************************************/
-static BOOL smbshut(file_info finfo, int fnum, char *inbuf, char *outbuf)
-{
- /* *must* be called with buffer ready malloc'ed */
-
- memset(outbuf,0,smb_size);
- set_message(outbuf,3,0,True);
- CVAL(outbuf,smb_com) = SMBclose;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,fnum);
- put_dos_date3(outbuf,smb_vwv1,finfo.mtime);
-
- DEBUG(3,("Setting date to %s (0x%X)",
- asctime(LocalTime(&finfo.mtime)),
- finfo.mtime));
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("%s closing remote file %s\n",smb_errstr(inbuf),
- finfo.name));
- return False;
- }
-
- return True;
-}
-
-/****************************************************************************
-Verify existence of path on share
-***************************************************************************/
-static BOOL smbchkpath(char *fname, char *inbuf, char *outbuf)
-{
- char *p;
-
- memset(outbuf,0,smb_size);
- set_message(outbuf,0,4 + strlen(fname),True);
- CVAL(outbuf,smb_com) = SMBchkpth;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- p = smb_buf(outbuf);
- *p++ = 4;
- strcpy(p,fname);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- DEBUG(5,("smbchkpath: %s\n",smb_errstr(inbuf)));
-
- return(CVAL(inbuf,smb_rcls) == 0);
-}
-
-/****************************************************************************
-Make a directory on share
-***************************************************************************/
-static BOOL smbmkdir(char *fname, char *inbuf, char *outbuf)
-{
- /* *must* be called with buffer ready malloc'ed */
- char *p;
-
- memset(outbuf,0,smb_size);
- set_message(outbuf,0,2 + strlen(fname),True);
-
- CVAL(outbuf,smb_com) = SMBmkdir;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- p = smb_buf(outbuf);
- *p++ = 4;
- strcpy(p,fname);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("%s making remote directory %s\n",
- smb_errstr(inbuf),fname));
- return(False);
- }
-
- return(True);
-}
-
-/****************************************************************************
-Ensure a remote path exists (make if necessary)
-***************************************************************************/
-static BOOL ensurepath(char *fname, char *inbuf, char *outbuf)
-{
- /* *must* be called with buffer ready malloc'ed */
- /* ensures path exists */
-
- pstring partpath, ffname;
- char *p=fname, *basehack;
-
- *partpath = 0;
-
- /* fname copied to ffname so can strtok */
-
- strcpy(ffname, fname);
-
- /* do a `basename' on ffname, so don't try and make file name directory */
- if ((basehack=strrchr(ffname, '\\')) == NULL)
- return True;
- else
- *basehack='\0';
-
- p=strtok(ffname, "\\");
-
- while (p)
- {
- strcat(partpath, p);
-
- if (!smbchkpath(partpath, inbuf, outbuf)) {
- if (!smbmkdir(partpath, inbuf, outbuf))
- {
- DEBUG(0, ("Error mkdirhiering\n"));
- return False;
- }
- else
- DEBUG(3, ("mkdirhiering %s\n", partpath));
-
- }
-
- strcat(partpath, "\\");
- p = strtok(NULL,"/\\");
- }
-
- return True;
-}
-
-int padit(char *buf, int bufsize, int padsize)
-{
- int berr= 0;
- int bytestowrite;
-
- DEBUG(0, ("Padding with %d zeros\n", padsize));
- memset(buf, 0, bufsize);
- while( !berr && padsize > 0 ) {
- bytestowrite= MIN(bufsize, padsize);
- berr = dotarbuf(tarhandle, buf, bytestowrite) != bytestowrite;
- padsize -= bytestowrite;
- }
-
- return berr;
-}
-
-/*
- * smbclient functions
- */
-/****************************************************************************
-append one remote file to the tar file
-***************************************************************************/
-static void do_atar(char *rname,char *lname,file_info *finfo1)
-{
- int fnum;
- uint32 nread=0;
- char *p;
- char *inbuf,*outbuf;
- file_info finfo;
- BOOL close_done = False;
- BOOL shallitime=True;
- BOOL ignore_close_error = False;
- char *dataptr=NULL;
- int datalen=0;
-
- struct timeval tp_start;
- GetTimeOfDay(&tp_start);
-
- if (finfo1)
- finfo = *finfo1;
- else
- finfo = def_finfo;
-
- inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
- if (!inbuf || !outbuf)
- {
- DEBUG(0,("out of memory\n"));
- return;
- }
-
- memset(outbuf,0,smb_size);
- set_message(outbuf,15,1 + strlen(rname),True);
-
- CVAL(outbuf,smb_com) = SMBopenX;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,0xFF);
- SSVAL(outbuf,smb_vwv2,1);
- SSVAL(outbuf,smb_vwv3,(DENY_NONE<<4));
- SSVAL(outbuf,smb_vwv4,aSYSTEM | aHIDDEN);
- SSVAL(outbuf,smb_vwv5,aSYSTEM | aHIDDEN);
- SSVAL(outbuf,smb_vwv8,1);
-
- p = smb_buf(outbuf);
- strcpy(p,rname);
- p = skip_string(p,1);
-
- dos_clean_name(rname);
-
- /* do a chained openX with a readX? */
- if (finfo.size > 0)
- {
- SSVAL(outbuf,smb_vwv0,SMBreadX);
- SSVAL(outbuf,smb_vwv1,PTR_DIFF(p,outbuf) - 4);
- memset(p,0,200);
- p -= smb_wct;
- SSVAL(p,smb_wct,10);
- SSVAL(p,smb_vwv0,0xFF);
- SSVAL(p,smb_vwv5,MIN(max_xmit-500,finfo.size));
- SSVAL(p,smb_vwv9,MIN(0xFFFF,finfo.size));
- smb_setlen(outbuf,smb_len(outbuf)+11*2+1);
- }
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- if (CVAL(inbuf,smb_rcls) == ERRSRV &&
- SVAL(inbuf,smb_err) == ERRnoresource &&
- reopen_connection(inbuf,outbuf))
- {
- do_atar(rname,lname,finfo1);
- free(inbuf);free(outbuf);
- return;
- }
-
- DEBUG(0,("%s opening remote file %s\n",smb_errstr(inbuf),rname));
- free(inbuf);free(outbuf);
- return;
- }
-
- strcpy(finfo.name,rname);
- if (!finfo1)
- {
- finfo.mode = SVAL(inbuf,smb_vwv3);
- finfo.size = IVAL(inbuf,smb_vwv4);
- finfo.mtime = make_unix_date3(inbuf+smb_vwv6);
- finfo.atime = finfo.ctime = finfo.mtime;
- }
-
- DEBUG(3,("file %s attrib 0x%X\n",finfo.name,finfo.mode));
-
- fnum = SVAL(inbuf,smb_vwv2);
-
- if (tar_inc && !(finfo.mode & aARCH))
- {
- DEBUG(4, ("skipping %s - archive bit not set\n", finfo.name));
- shallitime=0;
- }
- else
- {
- if (SVAL(inbuf,smb_vwv0) == SMBreadX)
- {
- p = (inbuf+4+SVAL(inbuf,smb_vwv1)) - smb_wct;
- datalen = SVAL(p,smb_vwv5);
- dataptr = inbuf + 4 + SVAL(p,smb_vwv6);
- }
- else
- {
- dataptr = NULL;
- datalen = 0;
- }
-
- DEBUG(1,("getting file %s of size %d bytes as a tar file %s",
- finfo.name,
- finfo.size,
- lname));
-
- /* write a tar header, don't bother with mode - just set to 100644 */
- writetarheader(tarhandle, rname, finfo.size, finfo.mtime, "100644 \0");
-
- while (nread < finfo.size && !close_done)
- {
- int method = -1;
- static BOOL can_chain_close=True;
-
- p=NULL;
-
- DEBUG(3,("nread=%d\n",nread));
-
- /* 3 possible read types. readbraw if a large block is required.
- readX + close if not much left and read if neither is supported */
-
- /* we might have already read some data from a chained readX */
- if (dataptr && datalen>0)
- method=3;
-
- /* if we can finish now then readX+close */
- if (method<0 && can_chain_close && (Protocol >= PROTOCOL_LANMAN1) &&
- ((finfo.size - nread) <
- (max_xmit - (2*smb_size + 13*SIZEOFWORD + 300))))
- method = 0;
-
- /* if we support readraw then use that */
- if (method<0 && readbraw_supported)
- method = 1;
-
- /* if we can then use readX */
- if (method<0 && (Protocol >= PROTOCOL_LANMAN1))
- method = 2;
-
-
- switch (method)
- {
- /* use readX */
- case 0:
- case 2:
- if (method == 0)
- close_done = True;
-
- /* use readX + close */
- memset(outbuf,0,smb_size);
- set_message(outbuf,10,0,True);
- CVAL(outbuf,smb_com) = SMBreadX;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- if (close_done)
- {
- CVAL(outbuf,smb_vwv0) = SMBclose;
- SSVAL(outbuf,smb_vwv1,PTR_DIFF(smb_buf(outbuf),outbuf) - 4);
- }
- else
- CVAL(outbuf,smb_vwv0) = 0xFF;
-
-
- SSVAL(outbuf,smb_vwv2,fnum);
- SIVAL(outbuf,smb_vwv3,nread);
- SSVAL(outbuf,smb_vwv5,MIN(max_xmit-200,finfo.size - nread));
- SSVAL(outbuf,smb_vwv6,0);
- SIVAL(outbuf,smb_vwv7,0);
- SSVAL(outbuf,smb_vwv9,MIN(0xFFFF,finfo.size-nread));
-
- if (close_done)
- {
- p = smb_buf(outbuf);
- memset(p,0,9);
-
- CVAL(p,0) = 3;
- SSVAL(p,1,fnum);
- SIVALS(p,3,-1);
-
- /* now set the total packet length */
- smb_setlen(outbuf,smb_len(outbuf)+9);
- }
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("Error %s reading remote file\n",smb_errstr(inbuf)));
- break;
- }
-
- if (close_done &&
- SVAL(inbuf,smb_vwv0) != SMBclose)
- {
- /* NOTE: WfWg sometimes just ignores the chained
- command! This seems to break the spec? */
- DEBUG(3,("Rejected chained close?\n"));
- close_done = False;
- can_chain_close = False;
- ignore_close_error = True;
- }
-
- datalen = SVAL(inbuf,smb_vwv5);
- dataptr = inbuf + 4 + SVAL(inbuf,smb_vwv6);
- break;
-
-
- /* use readbraw */
- case 1:
- {
- static int readbraw_size = 0xFFFF;
-
- extern int Client;
- memset(outbuf,0,smb_size);
- set_message(outbuf,8,0,True);
- CVAL(outbuf,smb_com) = SMBreadbraw;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
- SSVAL(outbuf,smb_vwv0,fnum);
- SIVAL(outbuf,smb_vwv1,nread);
- SSVAL(outbuf,smb_vwv3,MIN(finfo.size-nread,readbraw_size));
- SSVAL(outbuf,smb_vwv4,0);
- SIVALS(outbuf,smb_vwv5,-1);
- send_smb(Client,outbuf);
-
- /* Now read the raw data into the buffer and write it */
- if(read_smb_length(Client,inbuf,0) == -1) {
- DEBUG(0,("Failed to read length in readbraw\n"));
- exit(1);
- }
-
- /* Even though this is not an smb message, smb_len
- returns the generic length of an smb message */
- datalen = smb_len(inbuf);
-
- if (datalen == 0)
- {
- /* we got a readbraw error */
- DEBUG(4,("readbraw error - reducing size\n"));
- readbraw_size = (readbraw_size * 9) / 10;
-
- if (readbraw_size < max_xmit)
- {
- DEBUG(0,("disabling readbraw\n"));
- readbraw_supported = False;
- }
-
- dataptr=NULL;
- continue;
- }
-
- if(read_data(Client,inbuf,datalen) != datalen) {
- DEBUG(0,("Failed to read data in readbraw\n"));
- exit(1);
- }
- dataptr = inbuf;
- }
- break;
-
- case 3:
- /* we've already read some data with a chained readX */
- break;
-
- default:
- /* use plain read */
- memset(outbuf,0,smb_size);
- set_message(outbuf,5,0,True);
- CVAL(outbuf,smb_com) = SMBread;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,fnum);
- SSVAL(outbuf,smb_vwv1,MIN(max_xmit-200,finfo.size - nread));
- SIVAL(outbuf,smb_vwv2,nread);
- SSVAL(outbuf,smb_vwv4,finfo.size - nread);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("Error %s reading remote file\n",smb_errstr(inbuf)));
- break;
- }
-
- datalen = SVAL(inbuf,smb_vwv0);
- dataptr = smb_buf(inbuf) + 3;
- break;
- }
-
-
- /* add received bits of file to buffer - dotarbuf will
- * write out in 512 byte intervals */
- if (dotarbuf(tarhandle,dataptr,datalen) != datalen)
- {
- DEBUG(0,("Error writing to tar file - %s\n", strerror(errno)));
- break;
- }
-
- nread += datalen;
- if (datalen == 0)
- {
- DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname));
- break;
- }
-
- dataptr=NULL;
- datalen=0;
- }
-
- /* pad tar file with zero's if we couldn't get entire file */
- if (nread < finfo.size)
- {
- DEBUG(0, ("Didn't get entire file. size=%d, nread=%d\n", finfo.size, nread));
- if (padit(inbuf, BUFFER_SIZE, finfo.size - nread))
- DEBUG(0,("Error writing tar file - %s\n", strerror(errno)));
- }
-
- /* round tar file to nearest block */
- if (finfo.size % TBLOCK)
- dozerobuf(tarhandle, TBLOCK - (finfo.size % TBLOCK));
-
- ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
- ntarf++;
- }
-
- if (!close_done)
- {
- memset(outbuf,0,smb_size);
- set_message(outbuf,3,0,True);
- CVAL(outbuf,smb_com) = SMBclose;
- SSVAL(outbuf,smb_tid,cnum);
- setup_pkt(outbuf);
-
- SSVAL(outbuf,smb_vwv0,fnum);
- SIVALS(outbuf,smb_vwv1,-1);
-
- send_smb(Client,outbuf);
- receive_smb(Client,inbuf,CLIENT_TIMEOUT);
-
- if (!ignore_close_error && CVAL(inbuf,smb_rcls) != 0)
- {
- DEBUG(0,("Error %s closing remote file\n",smb_errstr(inbuf)));
- free(inbuf);free(outbuf);
- return;
- }
- }
-
- if (shallitime)
- {
- struct timeval tp_end;
- int this_time;
-
- /* if shallitime is true then we didn't skip */
- if (tar_reset) (void) do_setrattr(finfo.name, aARCH, ATTRRESET);
-
- GetTimeOfDay(&tp_end);
- this_time =
- (tp_end.tv_sec - tp_start.tv_sec)*1000 +
- (tp_end.tv_usec - tp_start.tv_usec)/1000;
- get_total_time_ms += this_time;
- get_total_size += finfo.size;
-
- /* Thanks to Carel-Jan Engel (ease@mail.wirehub.nl) for this one */
- DEBUG(1,("(%g kb/s) (average %g kb/s)\n",
- finfo.size / MAX(0.001, (1.024*this_time)),
- get_total_size / MAX(0.001, (1.024*get_total_time_ms))));
- }
-
- free(inbuf);free(outbuf);
-}
-
-/****************************************************************************
-Append single file to tar file (or not)
-***************************************************************************/
-static void do_tar(file_info *finfo)
-{
- pstring rname;
-
- if (strequal(finfo->name,".") || strequal(finfo->name,".."))
- return;
-
- /* Is it on the exclude list ? */
- if (!tar_excl && clipn) {
- pstring exclaim;
-
- strcpy(exclaim, cur_dir);
- *(exclaim+strlen(exclaim)-1)='\0';
-
- strcat(exclaim, "\\");
- strcat(exclaim, finfo->name);
-
- if (clipfind(cliplist, clipn, exclaim)) {
- DEBUG(3,("Skipping file %s\n", exclaim));
- return;
- }
- }
-
- if (finfo->mode & aDIR)
- {
- pstring saved_curdir;
- pstring mtar_mask;
- char *inbuf,*outbuf;
-
- inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
- if (!inbuf || !outbuf)
- {
- DEBUG(0,("out of memory\n"));
- return;
- }
-
- strcpy(saved_curdir,cur_dir);
-
- strcat(cur_dir,finfo->name);
- strcat(cur_dir,"\\");
-
- /* write a tar directory, don't bother with mode - just set it to
- * 40755 */
- writetarheader(tarhandle, cur_dir, 0, finfo->mtime, "040755 \0");
- strcpy(mtar_mask,cur_dir);
- strcat(mtar_mask,"*");
-
- do_dir((char *)inbuf,(char *)outbuf,mtar_mask,attribute,do_tar,recurse);
- strcpy(cur_dir,saved_curdir);
- free(inbuf);free(outbuf);
- }
- else
- {
- strcpy(rname,cur_dir);
- strcat(rname,finfo->name);
- do_atar(rname,finfo->name,finfo);
- }
-}
-
-/****************************************************************************
-Convert from UNIX to DOS file names
-***************************************************************************/
-static void unfixtarname(char *tptr, char *fp, int l)
-{
- /* remove '.' from start of file name, convert from unix /'s to
- * dos \'s in path. Kill any absolute path names.
- */
-
- if (*fp == '.') fp++;
- if (*fp == '\\' || *fp == '/') fp++;
-
- if(lp_client_code_page() == KANJI_CODEPAGE)
- {
- while (l > 0) {
- if (is_shift_jis (*fp)) {
- *tptr++ = *fp++;
- *tptr++ = *fp++;
- l -= 2;
- } else if (is_kana (*fp)) {
- *tptr++ = *fp++;
- l--;
- } else if (*fp == '/') {
- *tptr++ = '\\';
- fp++;
- l--;
- } else {
- *tptr++ = *fp++;
- l--;
- }
- }
- }
- else
- {
- while (l--)
- {
- *tptr=(*fp == '/') ? '\\' : *fp;
- tptr++;
- fp++;
- }
- }
-}
-
-static void do_tarput()
-{
- file_info finfo;
- int nread=0, bufread;
- char *inbuf,*outbuf;
- int fsize=0;
- int fnum;
- struct timeval tp_start;
- BOOL tskip=False; /* We'll take each file as it comes */
-
- GetTimeOfDay(&tp_start);
-
- inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
-
- if (!inbuf || !outbuf)
- {
- DEBUG(0,("out of memory\n"));
- return;
- }
-
- /*
- * Must read in tbufsiz dollops
- */
-
- /* These should be the only reads in clitar.c */
- while ((bufread=read(tarhandle, tarbuf, tbufsiz))>0) {
- char *bufferp, *endofbuffer;
- int chunk;
-
- /* Code to handle a short read.
- * We always need a TBLOCK full of stuff
- */
- if (bufread % TBLOCK) {
- int lchunk=TBLOCK-(bufread % TBLOCK);
- int lread;
-
- /* It's a shorty - a short read that is */
- DEBUG(3, ("Short read, read %d so far (need %d)\n", bufread, lchunk));
-
- while ((lread=read(tarhandle, tarbuf+bufread, lchunk))>0) {
- bufread+=lread;
- if (!(lchunk-=lread)) break;
- }
-
- /* If we've reached EOF then that must be a short file */
- if (lread<=0) break;
- }
-
- bufferp=tarbuf;
- endofbuffer=tarbuf+bufread;
-
- if (tskip) {
- if (fsize<bufread) {
- tskip=False;
- bufferp+=fsize;
- fsize=0;
- } else {
- if (fsize==bufread) tskip=False;
- fsize-=bufread;
- continue;
- }
- }
-
- do {
- if (!fsize)
- {
- switch (readtarheader((union hblock *) bufferp, &finfo, cur_dir))
- {
- case -2: /* something dodgy but not fatal about this */
- DEBUG(0, ("skipping %s...\n", finfo.name));
- bufferp+=TBLOCK; /* header - like a link */
- continue;
- case -1:
- DEBUG(0, ("abandoning restore\n"));
- free(inbuf); free(outbuf);
- return;
- case 0: /* chksum is zero - we assume that one all zero
- *header block will do for eof */
- DEBUG(0,
- ("total of %d tar files restored to share\n", ntarf));
- free(inbuf); free(outbuf);
- return;
- default:
- break;
- }
-
- tskip=clipn
- && (clipfind(cliplist, clipn, finfo.name) ^ tar_excl);
- if (tskip) {
- bufferp+=TBLOCK;
- if (finfo.mode & aDIR)
- continue;
- else if ((fsize=finfo.size) % TBLOCK) {
- fsize+=TBLOCK-(fsize%TBLOCK);
- }
- if (fsize<endofbuffer-bufferp) {
- bufferp+=fsize;
- fsize=0;
- continue;
- } else {
- fsize-=endofbuffer-bufferp;
- break;
- }
- }
-
- if (finfo.mode & aDIR)
- {
- if (!smbchkpath(finfo.name, inbuf, outbuf)
- && !smbmkdir(finfo.name, inbuf, outbuf))
- {
- DEBUG(0, ("abandoning restore\n"));
- free(inbuf); free(outbuf);
- return;
- }
- else
- {
- bufferp+=TBLOCK;
- continue;
- }
- }
-
- fsize=finfo.size;
-
- if (ensurepath(finfo.name, inbuf, outbuf)
- && !smbcreat(finfo, &fnum, inbuf, outbuf))
- {
- DEBUG(0, ("abandoning restore\n"));
- free(inbuf);free(outbuf);
- return;
- }
-
- DEBUG(0,("restore tar file %s of size %d bytes\n",
- finfo.name,finfo.size));
-
- nread=0;
- if ((bufferp+=TBLOCK) >= endofbuffer) break;
- } /* if (!fsize) */
-
- /* write out the file in chunk sized chunks - don't
- * go past end of buffer though */
- chunk=(fsize-nread < endofbuffer - bufferp)
- ? fsize - nread : endofbuffer - bufferp;
-
- while (chunk > 0) {
- int minichunk=MIN(chunk, max_xmit-200);
-
- if (!smbwrite(fnum, /* file descriptor */
- minichunk, /* n */
- nread, /* offset low */
- 0, /* offset high - not implemented */
- fsize-nread, /* left - only hint to server */
- bufferp,
- inbuf,
- outbuf))
- {
- DEBUG(0, ("Error writing remote file\n"));
- free(inbuf); free(outbuf);
- return;
- }
- DEBUG(5, ("chunk writing fname=%s fnum=%d nread=%d minichunk=%d chunk=%d size=%d\n", finfo.name, fnum, nread, minichunk, chunk, fsize));
-
- bufferp+=minichunk; nread+=minichunk;
- chunk-=minichunk;
- }
-
- if (nread>=fsize)
- {
- if (!smbshut(finfo, fnum, inbuf, outbuf))
- {
- DEBUG(0, ("Error closing remote file\n"));
- free(inbuf);free(outbuf);
- return;
- }
- if (fsize % TBLOCK) bufferp+=TBLOCK - (fsize % TBLOCK);
- DEBUG(5, ("bufferp is now %d (psn=%d)\n",
- (long) bufferp, (long)(bufferp - tarbuf)));
- ntarf++;
- fsize=0;
- }
- } while (bufferp < endofbuffer);
- }
-
- DEBUG(0, ("premature eof on tar file ?\n"));
- DEBUG(0,("total of %d tar files restored to share\n", ntarf));
-
- free(inbuf); free(outbuf);
-}
-
-/*
- * samba interactive commands
- */
-
-/****************************************************************************
-Blocksize command
-***************************************************************************/
-void cmd_block(void)
-{
- fstring buf;
- int block;
-
- if (!next_token(NULL,buf,NULL))
- {
- DEBUG(0, ("blocksize <n>\n"));
- return;
- }
-
- block=atoi(buf);
- if (block < 0 || block > 65535)
- {
- DEBUG(0, ("blocksize out of range"));
- return;
- }
-
- blocksize=block;
- DEBUG(1,("blocksize is now %d\n", blocksize));
-}
-
-/****************************************************************************
-command to set incremental / reset mode
-***************************************************************************/
-void cmd_tarmode(void)
-{
- fstring buf;
-
- while (next_token(NULL,buf,NULL)) {
- if (strequal(buf, "full"))
- tar_inc=False;
- else if (strequal(buf, "inc"))
- tar_inc=True;
- else if (strequal(buf, "reset"))
- tar_reset=True;
- else if (strequal(buf, "noreset"))
- tar_reset=False;
- else DEBUG(0, ("tarmode: unrecognised option %s\n", buf));
- }
-
- DEBUG(0, ("tarmode is now %s, %s\n",
- tar_inc ? "incremental" : "full",
- tar_reset ? "reset" : "noreset"));
-}
-
-/****************************************************************************
-Feeble attrib command
-***************************************************************************/
-void cmd_setmode(void)
-{
- char *q;
- fstring buf;
- pstring fname;
- int attra[2];
- int direct=1;
-
- attra[0] = attra[1] = 0;
-
- if (!next_token(NULL,buf,NULL))
- {
- DEBUG(0, ("setmode <filename> <perm=[+|-]rsha>\n"));
- return;
- }
-
- strcpy(fname, cur_dir);
- strcat(fname, buf);
-
- while (next_token(NULL,buf,NULL)) {
- q=buf;
-
- while(*q)
- switch (*q++) {
- case '+': direct=1;
- break;
- case '-': direct=0;
- break;
- case 'r': attra[direct]|=aRONLY;
- break;
- case 'h': attra[direct]|=aHIDDEN;
- break;
- case 's': attra[direct]|=aSYSTEM;
- break;
- case 'a': attra[direct]|=aARCH;
- break;
- default: DEBUG(0, ("setmode <filename> <perm=[+|-]rsha>\n"));
- return;
- }
- }
-
- if (attra[ATTRSET]==0 && attra[ATTRRESET]==0)
- {
- DEBUG(0, ("setmode <filename> <perm=[+|-]rsha>\n"));
- return;
- }
-
- DEBUG(1, ("\nperm set %d %d\n", attra[ATTRSET], attra[ATTRRESET]));
- (void) do_setrattr(fname, attra[ATTRSET], ATTRSET);
- (void) do_setrattr(fname, attra[ATTRRESET], ATTRRESET);
-}
-
-/****************************************************************************
-Principal command for creating / extracting
-***************************************************************************/
-void cmd_tar(char *inbuf, char *outbuf)
-{
- fstring buf;
- char **argl;
- int argcl;
-
- if (!next_token(NULL,buf,NULL))
- {
- DEBUG(0,("tar <c|x>[IXbga] <filename>\n"));
- return;
- }
-
- argl=toktocliplist(&argcl, NULL);
- if (!tar_parseargs(argcl, argl, buf, 0))
- return;
-
- process_tar(inbuf, outbuf);
-
- free(argl);
-}
-
-/****************************************************************************
-Command line (option) version
-***************************************************************************/
-int process_tar(char *inbuf, char *outbuf)
-{
- initarbuf();
- switch(tar_type) {
- case 'x':
- do_tarput();
- free(tarbuf);
- close(tarhandle);
- break;
- case 'r':
- case 'c':
- if (clipn && tar_excl) {
- int i;
- pstring tarmac;
-
- for (i=0; i<clipn; i++) {
- DEBUG(0,("arg %d = %s\n", i, cliplist[i]));
-
- if (*(cliplist[i]+strlen(cliplist[i])-1)=='\\') {
- *(cliplist[i]+strlen(cliplist[i])-1)='\0';
- }
-
- if (strrchr(cliplist[i], '\\')) {
- pstring saved_dir;
-
- strcpy(saved_dir, cur_dir);
-
- if (*cliplist[i]=='\\') {
- strcpy(tarmac, cliplist[i]);
- } else {
- strcpy(tarmac, cur_dir);
- strcat(tarmac, cliplist[i]);
- }
- strcpy(cur_dir, tarmac);
- *(strrchr(cur_dir, '\\')+1)='\0';
-
- do_dir((char *)inbuf,(char *)outbuf,tarmac,attribute,do_tar,recurse);
- strcpy(cur_dir,saved_dir);
- } else {
- strcpy(tarmac, cur_dir);
- strcat(tarmac, cliplist[i]);
- do_dir((char *)inbuf,(char *)outbuf,tarmac,attribute,do_tar,recurse);
- }
- }
- } else {
- pstring mask;
- strcpy(mask,cur_dir);
- strcat(mask,"\\*");
- do_dir((char *)inbuf,(char *)outbuf,mask,attribute,do_tar,recurse);
- }
-
- if (ntarf) dotareof(tarhandle);
- close(tarhandle);
- free(tarbuf);
-
- DEBUG(0, ("tar: dumped %d tar files\n", ntarf));
- DEBUG(0, ("Total bytes written: %d\n", ttarf));
- break;
- }
-
- return(0);
-}
-
-/****************************************************************************
-Find a token (filename) in a clip list
-***************************************************************************/
-int clipfind(char **aret, int ret, char *tok)
-{
- if (aret==NULL) return 0;
-
- /* ignore leading slashes or dots in token */
- while(strchr("/\\.", *tok)) tok++;
-
- while(ret--) {
- char *pkey=*aret++;
-
- /* ignore leading slashes or dots in list */
- while(strchr("/\\.", *pkey)) pkey++;
-
- if (!strslashcmp(pkey, tok)) return 1;
- }
-
- return 0;
-}
-
-/****************************************************************************
-Parse tar arguments. Sets tar_type, tar_excl, etc.
-***************************************************************************/
-int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind)
-{
- char tar_clipfl='\0';
-
- /* Reset back to defaults - could be from interactive version
- * reset mode and archive mode left as they are though
- */
- tar_type='\0';
- tar_excl=True;
-
- while (*Optarg)
- switch(*Optarg++) {
- case 'c':
- tar_type='c';
- break;
- case 'x':
- if (tar_type=='c') {
- printf("Tar must be followed by only one of c or x.\n");
- return 0;
- }
- tar_type='x';
- break;
- case 'b':
- if (Optind>=argc || !(blocksize=atoi(argv[Optind]))) {
- DEBUG(0,("Option b must be followed by valid blocksize\n"));
- return 0;
- } else {
- Optind++;
- }
- break;
- case 'g':
- tar_inc=True;
- break;
- case 'N':
- if (Optind>=argc) {
- DEBUG(0,("Option N must be followed by valid file name\n"));
- return 0;
- } else {
- struct stat stbuf;
- extern time_t newer_than;
-
- if (sys_stat(argv[Optind], &stbuf) == 0) {
- newer_than = stbuf.st_mtime;
- DEBUG(1,("Getting files newer than %s",
- asctime(LocalTime(&newer_than))));
- Optind++;
- } else {
- DEBUG(0,("Error setting newer-than time\n"));
- return 0;
- }
- }
- break;
- case 'a':
- tar_reset=True;
- break;
- case 'I':
- if (tar_clipfl) {
- DEBUG(0,("Only one of I,X must be specified\n"));
- return 0;
- }
- tar_clipfl='I';
- break;
- case 'X':
- if (tar_clipfl) {
- DEBUG(0,("Only one of I,X must be specified\n"));
- return 0;
- }
- tar_clipfl='X';
- break;
- default:
- DEBUG(0,("Unknown tar option\n"));
- return 0;
- }
-
- if (!tar_type) {
- printf("Option T must be followed by one of c or x.\n");
- return 0;
- }
-
- tar_excl=tar_clipfl!='X';
- if (Optind+1<argc) {
- cliplist=argv+Optind+1;
- clipn=argc-Optind-1;
- }
- if (Optind>=argc || !strcmp(argv[Optind], "-")) {
- /* Sets tar handle to either 0 or 1, as appropriate */
- tarhandle=(tar_type=='c');
- } else {
- if ((tar_type=='x' && (tarhandle = open(argv[Optind], O_RDONLY)) == -1)
- || (tar_type=='c' && (tarhandle=creat(argv[Optind], 0644)) < 0))
- {
- DEBUG(0,("Error opening local file %s - %s\n",
- argv[Optind], strerror(errno)));
- return(0);
- }
- }
-
- return 1;
-}
diff --git a/source/codepages/codepage_def.437 b/source/codepages/codepage_def.437
deleted file mode 100644
index d357c074e44..00000000000
--- a/source/codepages/codepage_def.437
+++ /dev/null
@@ -1,70 +0,0 @@
-#
-# 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.
-#
-
-# Codepage definition file for IBM Code Page 437 - MS-DOS Latin US
-# defines lower->upper mapping.
-# Written by Jeremy Allison <jallison@whistle.com>
-
-# The columns are :
-# lower upper map upper to lower map lower to upper
-#
- 0x87 0x80 True True
- 0x81 0x9A True True
- 0x82 0x90 True True
- 0x83 0x41 True False
- 0x84 0x8E True True
- 0x85 0x41 True False
- 0x86 0x8F True True
- 0x88 0x45 True False
- 0x89 0x45 True False
- 0x8A 0x45 True False
- 0x8B 0x49 True False
- 0x8C 0x49 True False
- 0x8D 0x49 True False
- 0x91 0x92 True True
- 0x93 0x4F True False
- 0x94 0x99 True True
- 0x95 0x4F True False
- 0x96 0x55 True False
- 0x97 0x55 True False
- 0x9B 0 False False
- 0x9C 0 False False
- 0x9D 0 False False
- 0xA0 0x41 True False
- 0xA1 0x49 True False
- 0xA2 0x4F True False
- 0xA3 0x55 True False
- 0xA4 0xA5 True True
- 0xA8 0 False False
- 0xAD 0 False False
- 0xAE 0 False False
- 0xAF 0 False False
- 0xE0 0 False False
- 0xE1 0 False False
- 0xE2 0 False False
- 0xE3 0 False False
- 0xE4 0 False False
- 0xE5 0 False False
- 0xE6 0 False False
- 0xE7 0 False False
- 0xE8 0 False False
- 0xE9 0 False False
- 0xEA 0 False False
- 0xEB 0 False False
- 0xEC 0 False False
- 0xED 0 False False
- 0xEE 0 False False
- 0xEF 0 False False
diff --git a/source/codepages/codepage_def.850 b/source/codepages/codepage_def.850
deleted file mode 100644
index e2466a707af..00000000000
--- a/source/codepages/codepage_def.850
+++ /dev/null
@@ -1,54 +0,0 @@
-#
-# 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.
-#
-
-# Codepage definition file for IBM Code Page 850 - MS-DOS Latin 1
-# defines lower->upper mapping.
-# Written by Jeremy Allison (jallison@whistle.com)
-
-# The columns are :
-# lower upper map upper to lower map lower to upper
-#
- 0x85 0xB7 True True
- 0xA0 0xB5 True True
- 0x83 0xB6 True True
- 0xC6 0xC7 True True
- 0x84 0x8E True True
- 0x86 0x8F True True
- 0x91 0x92 True True
- 0x87 0x80 True True
- 0x8A 0xD4 True True
- 0x82 0x90 True True
- 0x88 0xD2 True True
- 0x89 0xD3 True True
- 0x8D 0xDE True True
- 0xA1 0xD6 True True
- 0x8C 0xD7 True True
- 0x8B 0xD8 True True
- 0xD0 0xD1 True True
- 0xA4 0xA5 True True
- 0x95 0xE3 True True
- 0xA2 0xE0 True True
- 0x93 0xE2 True True
- 0xE4 0xE5 True True
- 0x94 0x99 True True
- 0x9B 0x9D True True
- 0x97 0xEB True True
- 0xA3 0xE9 True True
- 0x96 0xEA True True
- 0x81 0x9A True True
- 0xEC 0xED True True
- 0xE7 0xE8 True True
- 0x9C 0 False False
diff --git a/source/codepages/codepage_def.852 b/source/codepages/codepage_def.852
deleted file mode 100644
index ed1423428ca..00000000000
--- a/source/codepages/codepage_def.852
+++ /dev/null
@@ -1,63 +0,0 @@
-#
-# 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.
-#
-
-# Codepage definition file for IBM Code Page 852 - MS-DOS Latin 2
-# defines lower->upper mapping.
-# Written by Leos Bitto <bitto@altec.cz>
-
-# The columns are :
-# lower upper map upper to lower map lower to upper
-#
- 0x81 0x9A True True
- 0x82 0x90 True True
- 0x83 0xB6 True True
- 0x84 0x8E True True
- 0x85 0xDE True True
- 0x86 0x8F True True
- 0x87 0x80 True True
- 0x88 0x9D True True
- 0x89 0xD3 True True
- 0x8B 0x8A True True
- 0x8C 0xD7 True True
- 0x92 0x91 True True
- 0x93 0xE2 True True
- 0x94 0x99 True True
- 0x96 0x95 True True
- 0x98 0x97 True True
- 0x9C 0x9B True True
- 0x9F 0xAC True True
- 0xA0 0xB5 True True
- 0xA1 0xD6 True True
- 0xA2 0xE0 True True
- 0xA3 0xE9 True True
- 0xA5 0xA4 True True
- 0xA7 0xA6 True True
- 0xA9 0xA8 True True
- 0xAB 0x8D True True
- 0xAD 0xB8 True True
- 0xBE 0xBD True True
- 0xC7 0xC6 True True
- 0xD0 0xD1 True True
- 0xD4 0xD2 True True
- 0xD8 0xB7 True True
- 0xE4 0xE3 True True
- 0xE5 0xD5 True True
- 0xE7 0xE6 True True
- 0xEA 0xE8 True True
- 0xEC 0xED True True
- 0xEE 0xDD True True
- 0xFB 0xEB True True
- 0xFD 0xFC True True
diff --git a/source/codepages/codepage_def.932 b/source/codepages/codepage_def.932
deleted file mode 100644
index 8d9ff631fba..00000000000
--- a/source/codepages/codepage_def.932
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# 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.
-#
-
-# Codepage definition file for IBM Code Page 932 - MS-DOS Japanese SJIS
-# defines lower->upper mapping.
-# Written by Jeremy Allison <jallison@whistle.com>
-
-# The columns are :
-# lower upper map upper to lower map lower to upper
-#
-# This file is intentionaly empty - no mappings are done. \ No newline at end of file
diff --git a/source/include/byteorder.h b/source/include/byteorder.h
deleted file mode 100644
index 0664a338175..00000000000
--- a/source/include/byteorder.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- SMB Byte handling
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-
-/*
- This file implements macros for machine independent short and
- int manipulation
-
-Here is a description of this file that I emailed to the samba list once:
-
-> I am confused about the way that byteorder.h works in Samba. I have
-> looked at it, and I would have thought that you might make a distinction
-> between LE and BE machines, but you only seem to distinguish between 386
-> and all other architectures.
->
-> Can you give me a clue?
-
-sure.
-
-The distinction between 386 and other architectures is only there as
-an optimisation. You can take it out completely and it will make no
-difference. The routines (macros) in byteorder.h are totally byteorder
-independent. The 386 optimsation just takes advantage of the fact that
-the x86 processors don't care about alignment, so we don't have to
-align ints on int boundaries etc. If there are other processors out
-there that aren't alignment sensitive then you could also define
-CAREFUL_ALIGNMENT=0 on those processors as well.
-
-Ok, now to the macros themselves. I'll take a simple example, say we
-want to extract a 2 byte integer from a SMB packet and put it into a
-type called uint16 that is in the local machines byte order, and you
-want to do it with only the assumption that uint16 is _at_least_ 16
-bits long (this last condition is very important for architectures
-that don't have any int types that are 2 bytes long)
-
-You do this:
-
-#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
-#define PVAL(buf,pos) ((unsigned)CVAL(buf,pos))
-#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8)
-
-then to extract a uint16 value at offset 25 in a buffer you do this:
-
-char *buffer = foo_bar();
-uint16 xx = SVAL(buffer,25);
-
-We are using the byteoder independence of the ANSI C bitshifts to do
-the work. A good optimising compiler should turn this into efficient
-code, especially if it happens to have the right byteorder :-)
-
-I know these macros can be made a bit tidier by removing some of the
-casts, but you need to look at byteorder.h as a whole to see the
-reasoning behind them. byteorder.h defines the following macros:
-
-SVAL(buf,pos) - extract a 2 byte SMB value
-IVAL(buf,pos) - extract a 4 byte SMB value
-SVALS(buf,pos) signed version of SVAL()
-IVALS(buf,pos) signed version of IVAL()
-
-SSVAL(buf,pos,val) - put a 2 byte SMB value into a buffer
-SIVAL(buf,pos,val) - put a 4 byte SMB value into a buffer
-SSVALS(buf,pos,val) - signed version of SSVAL()
-SIVALS(buf,pos,val) - signed version of SIVAL()
-
-RSVAL(buf,pos) - like SVAL() but for NMB byte ordering
-RIVAL(buf,pos) - like IVAL() but for NMB byte ordering
-RSSVAL(buf,pos,val) - like SSVAL() but for NMB ordering
-RSIVAL(buf,pos,val) - like SIVAL() but for NMB ordering
-
-it also defines lots of intermediate macros, just ignore those :-)
-
-*/
-
-/* some switch macros that do both store and read to and from SMB buffers */
-
-#define RW_PCVAL(read,inbuf,outbuf,len) \
- if (read) { PCVAL (inbuf,0,outbuf,len) } \
- else { PSCVAL(inbuf,0,outbuf,len) }
-
-#define RW_PSVAL(read,inbuf,outbuf,len) \
- if (read) { PSVAL (inbuf,0,outbuf,len) } \
- else { PSSVAL(inbuf,0,outbuf,len) }
-
-#define RW_CVAL(read, inbuf, outbuf, offset) \
- if (read) (outbuf) = CVAL (inbuf,offset); \
- else SCVAL(inbuf,offset,outbuf);
-
-#define RW_IVAL(read, inbuf, outbuf, offset) \
- if (read) (outbuf)= IVAL (inbuf,offset); \
- else SIVAL(inbuf,offset,outbuf);
-
-#define RW_SVAL(read, inbuf, outbuf, offset) \
- if (read) (outbuf)= SVAL (inbuf,offset); \
- else SSVAL(inbuf,offset,outbuf);
-
-#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
-*/
-
-/* get single value from an SMB buffer */
-#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)))
-
-/* store single value in an SMB buffer */
-#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
-
-
-/* macros for reading / writing arrays */
-
-#define SMBMACRO(macro,buf,pos,val,len,size) \
-{ int l; for (l = 0; l < (len); l++) (val)[l] = macro((buf), (pos) + (size)*l); }
-
-#define SSMBMACRO(macro,buf,pos,val,len,size) \
-{ int l; for (l = 0; l < (len); l++) macro((buf), (pos) + (size)*l, (val)[l]); }
-
-/* reads multiple data from an SMB buffer */
-#define PCVAL(buf,pos,val,len) SMBMACRO(CVAL,buf,pos,val,len,1)
-#define PSVAL(buf,pos,val,len) SMBMACRO(SVAL,buf,pos,val,len,2)
-#define PIVAL(buf,pos,val,len) SMBMACRO(IVAL,buf,pos,val,len,4)
-#define PCVALS(buf,pos,val,len) SMBMACRO(CVALS,buf,pos,val,len,1)
-#define PSVALS(buf,pos,val,len) SMBMACRO(SVALS,buf,pos,val,len,2)
-#define PIVALS(buf,pos,val,len) SMBMACRO(IVALS,buf,pos,val,len,4)
-
-/* stores multiple data in an SMB buffer */
-#define PSCVAL(buf,pos,val,len) SSMBMACRO(SCVAL,buf,pos,val,len,1)
-#define PSSVAL(buf,pos,val,len) SSMBMACRO(SSVAL,buf,pos,val,len,2)
-#define PSIVAL(buf,pos,val,len) SSMBMACRO(SIVAL,buf,pos,val,len,4)
-#define PSCVALS(buf,pos,val,len) SSMBMACRO(SCVALS,buf,pos,val,len,1)
-#define PSSVALS(buf,pos,val,len) SSMBMACRO(SSVALS,buf,pos,val,len,2)
-#define PSIVALS(buf,pos,val,len) SSMBMACRO(SIVALS,buf,pos,val,len,4)
-
-
-/* now the reverse routines - these are used in nmb packets (mostly) */
-#define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
-#define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16)))
-
-#define RSVAL(buf,pos) SREV(SVAL(buf,pos))
-#define RIVAL(buf,pos) IREV(IVAL(buf,pos))
-#define RSSVAL(buf,pos,val) SSVAL(buf,pos,SREV(val))
-#define RSIVAL(buf,pos,val) SIVAL(buf,pos,IREV(val))
-
diff --git a/source/include/charset.h b/source/include/charset.h
deleted file mode 100644
index fb184897c07..00000000000
--- a/source/include/charset.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Character set handling
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-
-#ifndef CHARSET_C
-
-extern char *dos_char_map;
-extern char *upper_char_map;
-extern char *lower_char_map;
-extern void add_char_string(char *s);
-extern void charset_initialise(void);
-
-#ifdef toupper
-#undef toupper
-#endif
-
-#ifdef tolower
-#undef tolower
-#endif
-
-#ifdef isupper
-#undef isupper
-#endif
-
-#ifdef islower
-#undef islower
-#endif
-
-#ifdef isdoschar
-#undef isdoschar
-#endif
-
-#ifdef isspace
-#undef isspace
-#endif
-
-#define toupper(c) (upper_char_map[(c&0xff)] & 0xff)
-#define tolower(c) (lower_char_map[(c&0xff)] & 0xff)
-#define isupper(c) ((c&0xff) != tolower(c&0xff))
-#define islower(c) ((c&0xff) != toupper(c&0xff))
-#define isdoschar(c) (dos_char_map[(c&0xff)] != 0)
-#define isspace(c) ((c)==' ' || (c) == '\t')
-
-/* this is used to determine if a character is safe to use in
- something that may be put on a command line */
-#define issafe(c) (isalnum((c&0xff)) || strchr("-._",c))
-#endif
-
-/* Dynamic codepage files defines. */
-
-/* Version id for dynamically loadable codepage files. */
-#define CODEPAGE_FILE_VERSION_ID 0x1
-/* Version 1 codepage file header size. */
-#define CODEPAGE_HEADER_SIZE 8
-/* Offsets for codepage file header entries. */
-#define CODEPAGE_VERSION_OFFSET 0
-#define CODEPAGE_CLIENT_CODEPAGE_OFFSET 2
-#define CODEPAGE_LENGTH_OFFSET 4
diff --git a/source/include/clitar.h b/source/include/clitar.h
deleted file mode 100644
index 2305fceeec7..00000000000
--- a/source/include/clitar.h
+++ /dev/null
@@ -1,17 +0,0 @@
-
-#define TBLOCK 512
-#define NAMSIZ 100
-union hblock {
- char dummy[TBLOCK];
- struct header {
- char name[NAMSIZ];
- char mode[8];
- char uid[8];
- char gid[8];
- char size[12];
- char mtime[12];
- char chksum[8];
- char linkflag;
- char linkname[NAMSIZ];
- } dbuf;
-};
diff --git a/source/include/includes.h b/source/include/includes.h
deleted file mode 100644
index a877f1ffb35..00000000000
--- a/source/include/includes.h
+++ /dev/null
@@ -1,1290 +0,0 @@
-#ifndef _INCLUDES_H
-#define _INCLUDES_H
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Machine customisation and include handling
- Copyright (C) Andrew Tridgell 1994-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.
-*/
-/*
- This file does all the #includes's. This makes it easier to
- port to a new unix. Hopefully a port will only have to edit the Makefile
- and add a section for the new unix below.
-*/
-
-
-/* the first OS dependent section is to setup what includes will be used.
- the main OS dependent section comes later on
-*/
-
-#ifdef ALTOS
-#define NO_UTIMEH
-#endif
-
-#ifdef MIPS
-#define POSIX_H
-#define NO_UTIMEH
-#endif
-
-#ifdef sun386
-#define NO_UTIMEH
-#endif
-
-#ifdef NEXT2
-#define NO_UTIMEH
-#endif
-
-#ifdef NEXT3_0
-#define NO_UTIMEH
-#define NO_UNISTDH
-#endif
-
-#ifdef APOLLO
-#define NO_UTIMEH
-#define NO_SYSMOUNTH
-#define NO_UNISTDH
-#endif
-
-#ifdef AIX
-#define NO_SYSMOUNTH
-#endif
-
-#ifdef M88K_R3
-#define SVR3H
-#define NO_RESOURCEH
-#endif
-
-#ifdef DNIX
-#define NO_SYSMOUNTH
-#define NO_NETIFH
-#define NO_RESOURCEH
-#define PRIME_NMBD 0
-#define NO_SETGROUPS
-#endif
-
-
-#ifdef ISC
-#define SYSSTREAMH
-#define NO_RESOURCEH
-#endif
-
-#ifdef QNX
-#define NO_RESOURCEH
-#define NO_SYSMOUNTH
-#define USE_MMAP 1
-#ifdef __386__
- #define __i386__
-#endif
-#endif
-
-#ifdef NEWS42
-#define NO_UTIMEH
-#define NO_STRFTIME
-#define NO_UTIMBUF
-#define REPLACE_MKTIME
-#define NO_TM_NAME
-#endif
-
-#ifdef OS2
-#define NO_SYSMOUNTH
-#define NO_NETIFH
-#endif
-
-#ifdef LYNX
-#define NO_SYSMOUNTH
-#endif
-
-
-#if (defined(SHADOW_PWD)||defined(OSF1_ENH_SEC)||defined(SecureWare)||defined(PWDAUTH))
-#define PASSWORD_LENGTH 16
-#endif
-
-/* here is the general includes section - with some ifdefs generated
- by the previous section
-*/
-#include "local.h"
-#include <stdio.h>
-#ifdef POSIX_STDLIBH
-#include <posix/stdlib.h>
-#else
-#include <stdlib.h>
-#endif
-#include <ctype.h>
-#include <time.h>
-#ifndef NO_UTIMEH
-#include <utime.h>
-#endif
-#include <sys/types.h>
-
-#ifdef SVR3H
-#include <sys/statfs.h>
-#include <sys/stream.h>
-#include <netinet/types.h>
-#include <netinet/ether.h>
-#include <netinet/ip_if.h>
-#endif
-
-#include <sys/socket.h>
-#ifdef AXPROC
-#include <termio.h>
-#endif
-#include <sys/ioctl.h>
-#include <stddef.h>
-#ifdef POSIX_H
-#include <posix/utime.h>
-#include <bsd/sys/time.h>
-#include <bsd/netinet/in.h>
-#else
-#include <sys/time.h>
-#include <netinet/in.h>
-#endif
-#include <netdb.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <sys/param.h>
-#include <grp.h>
-#ifndef NO_RESOURCEH
-#include <sys/resource.h>
-#endif
-#ifndef NO_SYSMOUNTH
-#include <sys/mount.h>
-#endif
-#include <pwd.h>
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-#ifndef NO_UNISTDH
-#include <unistd.h>
-#endif
-#include <sys/wait.h>
-#ifdef SYSSTREAMH
-#include <sys/stream.h>
-#endif
-#ifndef NO_NETIFH
-#ifdef POSIX_H
-#include <bsd/net/if.h>
-#else
-#include <net/if.h>
-#endif
-#endif
-
-#if defined(GETPWANAM)
-#include <sys/types.h>
-#include <sys/label.h>
-#include <sys/audit.h>
-#include <pwdadj.h>
-#endif
-
-#if defined(SHADOW_PWD) && !defined(NETBSD) && !defined(FreeBSD) && !defined(CONVEX)
-#include <shadow.h>
-#endif
-
-#ifdef SYSLOG
-#include <syslog.h>
-#endif
-
-
-
-/***************************************************************************
-Here come some platform specific sections
-***************************************************************************/
-
-
-#ifdef LINUX
-#include <arpa/inet.h>
-#include <dirent.h>
-#include <string.h>
-#include <sys/vfs.h>
-#include <netinet/in.h>
-#ifndef NO_ASMSIGNALH
-#include <asm/signal.h>
-#endif
-#ifdef GLIBC2
-#define _LINUX_C_LIB_VERSION_MAJOR 6
-#include <termios.h>
-#include <rpcsvc/ypclnt.h>
-#include <crypt.h>
-#include <netinet/tcp.h>
-#include <netinet/ip.h>
-#endif
-#define SIGNAL_CAST (__sighandler_t)
-#define USE_GETCWD
-#define USE_SETSID
-#define HAVE_BZERO
-#define HAVE_MEMMOVE
-#define USE_SIGPROCMASK
-#define USE_WAITPID
-#if 0
-/* SETFS disabled until we can check on some bug reports */
-#if _LINUX_C_LIB_VERSION_MAJOR >= 5
-#define USE_SETFS
-#endif
-#endif
-#ifdef SHADOW_PWD
-#if _LINUX_C_LIB_VERSION_MAJOR < 5
-#ifndef crypt
-#define crypt pw_encrypt
-#endif
-#endif
-#endif
-#endif
-
-#ifdef SUNOS4
-#define SIGNAL_CAST (void (*)(int))
-#include <netinet/tcp.h>
-#include <dirent.h>
-#include <sys/acct.h>
-#include <sys/vfs.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/wait.h>
-#include <signal.h>
-/* #include <termios.h> */
-#ifdef sun386
-#define NO_STRFTIME
-#define NO_UTIMBUF
-#define mktime timelocal
-typedef unsigned short mode_t;
-#else
-#include <utime.h>
-#define NO_STRERROR
-#endif
-#ifndef REPLACE_GETPASS
-#define REPLACE_GETPASS
-#endif
-#ifndef BSD_TERMIO
-#define BSD_TERMIO
-#endif
-#ifndef USE_SIGPROCMASK
-#define USE_SIGPROCMASK
-#endif
-#ifndef USE_WAITPID
-#define USE_WAITPID
-#endif
-/* SunOS doesn't have POSIX atexit */
-#define atexit on_exit
-#endif
-
-
-#ifdef SUNOS5
-#include <fcntl.h>
-#include <dirent.h>
-#include <sys/acct.h>
-#include <sys/statfs.h>
-#include <sys/statvfs.h>
-#include <sys/filio.h>
-#include <sys/sockio.h>
-#include <netinet/in_systm.h>
-#include <netinet/tcp.h>
-#include <netinet/ip.h>
-#include <string.h>
-#include <arpa/inet.h>
-#include <rpcsvc/ypclnt.h>
-#include <termios.h>
-#include <sys/stropts.h>
-#ifndef USE_LIBDES
-#include <crypt.h>
-#endif /* USE_LIBDES */
-extern int gettimeofday (struct timeval *, void *);
-extern int gethostname (char *name, int namelen);
-extern int innetgr (const char *, const char *, const char *, const char *);
-#define USE_SETVBUF
-#define SIGNAL_CAST (void (*)(int))
-#ifndef SYSV
-#define SYSV
-#endif
-#define USE_WAITPID
-#define REPLACE_STRLEN
-#define USE_STATVFS
-#define USE_GETCWD
-#define USE_SETSID
-#ifndef REPLACE_GETPASS
-#define REPLACE_GETPASS
-#endif /* REPLACE_GETPASS */
-#define USE_SIGPROCMASK
-#endif
-
-
-#ifdef ULTRIX
-#include <strings.h>
-#include <nfs/nfs_clnt.h>
-#include <nfs/vfs.h>
-#include <netinet/tcp.h>
-#ifdef ULTRIX_AUTH
-#include <auth.h>
-#endif
-char *getwd(char *);
-#define NOSTRDUP
-#ifdef __STDC__
-#define SIGNAL_CAST (void(*)(int))
-#endif
-#define USE_DIRECT
-#define USE_WAITPID
-#endif
-
-#ifdef SGI4
-#include <netinet/tcp.h>
-#include <sys/statfs.h>
-#include <string.h>
-#include <signal.h>
-#ifndef SYSV
-#define SYSV
-#endif
-#define SIGNAL_CAST (void (*)())
-#define STATFS4
-#define USE_WAITPID
-#define USE_DIRECT
-#define USE_SETSID
-#endif
-
-#if defined(SGI5) || defined(SGI6)
-#include <arpa/inet.h>
-#include <netinet/tcp.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <sys/statvfs.h>
-#include <string.h>
-#include <signal.h>
-#include <dirent.h>
-#define USE_WAITPID
-#define NETGROUP
-#ifndef SYSV
-#define SYSV
-#endif
-#define SIGNAL_CAST (void (*)())
-#define USE_STATVFS
-#define USE_WAITPID
-#define USE_SETSID
-#endif
-
-
-#ifdef MIPS
-#include <bsd/net/soioctl.h>
-#include <string.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <sys/statfs.h>
-#include <sys/wait.h>
-#include <sys/termio.h>
-#define SIGNAL_CAST (void (*)())
-typedef int mode_t;
-extern struct group *getgrnam();
-extern struct passwd *getpwnam();
-#define STATFS4
-#define NO_STRERROR
-#define REPLACE_STRSTR
-#endif /* MIPS */
-
-
-
-#ifdef DGUX
-#include <string.h>
-#include <dirent.h>
-#include <sys/statfs.h>
-#include <sys/statvfs.h>
-#include <fcntl.h>
-#include <termios.h>
-#define SYSV
-#define USE_WAITPID
-#define SIGNAL_CAST (void (*)(int))
-#define STATFS4
-#define USE_GETCWD
-#endif
-
-
-#ifdef SVR4
-#include <string.h>
-#include <sys/dir.h>
-#include <dirent.h>
-#include <sys/statfs.h>
-#include <sys/statvfs.h>
-#include <sys/vfs.h>
-#include <sys/filio.h>
-#include <fcntl.h>
-#include <sys/sockio.h>
-#include <netinet/tcp.h>
-#include <stropts.h>
-#include <termios.h>
-#define SYSV
-#define USE_WAITPID
-#define SIGNAL_CAST (void (*)(int))
-#define USE_STATVFS
-#define USE_GETCWD
-#define USE_SETSID
-#endif
-
-
-#ifdef OSF1
-#include <termios.h>
-#include <strings.h>
-#include <dirent.h>
-char *getwd(char *);
-char *mktemp(char *); /* No standard include */
-#include <netinet/in.h>
-#include <arpa/inet.h> /* both for inet_ntoa */
-#define SIGNAL_CAST ( void (*) (int) )
-#define STATFS3
-#define USE_F_FSIZE
-#define USE_SETSID
-#include <netinet/tcp.h>
-#ifdef OSF1_ENH_SEC
-#include <pwd.h>
-#include <sys/types.h>
-#include <sys/security.h>
-#include <prot.h>
-#include <unistd.h>
-#define PASSWORD_LENGTH 16
-#define NEED_AUTH_PARAMETERS
-#endif /* OSF1_ENH_SEC */
-#endif
-
-
-#ifdef CLIX
-#include <dirent.h>
-#define SIGNAL_CAST (void (*)())
-#include <sys/fcntl.h>
-#include <sys/statfs.h>
-#include <string.h>
-#define NO_EID
-#define USE_WAITPID
-#define STATFS4
-#define NO_FSYNC
-#define USE_GETCWD
-#define USE_SETSID
-#ifndef REPLACE_GETPASS
-#define REPLACE_GETPASS
-#endif /* REPLACE_GETPASS */
-#define NO_GETRLIMIT
-#endif /* CLIX */
-
-
-
-#ifdef BSDI
-#include <string.h>
-#include <netinet/tcp.h>
-#define SIGNAL_CAST (void (*)())
-#define USE_DIRECT
-#endif
-
-
-#ifdef NETBSD
-#include <strings.h>
-#include <netinet/tcp.h>
-/* you may not need this */
-#define NO_GETSPNAM
-#define SIGNAL_CAST (void (*)())
-#define USE_DIRECT
-#define REPLACE_INNETGR
-#endif
-
-
-
-#ifdef FreeBSD
-#include <arpa/inet.h>
-#include <strings.h>
-#include <netinet/tcp.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#define SIGNAL_CAST (void (*)())
-#define USE_SETVBUF
-#define USE_SETSID
-#define USE_GETCWD
-#define USE_WAITPID
-#define USE_DIRECT
-#define HAVE_MEMMOVE
-#define HAVE_BZERO
-#define HAVE_GETTIMEOFDAY
-#define HAVE_PATHCONF
-#define HAVE_GETGRNAM 1
-#endif
-
-
-
-#ifdef AIX
-#include <strings.h>
-#include <sys/dir.h>
-#include <sys/select.h>
-#include <dirent.h>
-#include <sys/statfs.h>
-#include <sys/vfs.h>
-#include <sys/id.h>
-#include <sys/priv.h>
-#include <netinet/tcp.h>
-#include <locale.h>
-#define SYSV
-#define USE_WAITPID
-#define USE_SIGBLOCK
-#define SIGNAL_CAST (void (*)())
-#define DEFAULT_PRINTING PRINT_AIX
-/* we undef this because sys/param.h is broken in aix. uggh. */
-#undef MAXHOSTNAMELEN
-#endif
-
-
-#ifdef HPUX
-#include <string.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <sys/vfs.h>
-#include <sys/types.h>
-#include <sys/termios.h>
-#include <netinet/tcp.h>
-#ifdef HPUX_10_TRUSTED
-#include <hpsecurity.h>
-#include <prot.h>
-#define NEED_AUTH_PARAMETERS
-#endif
-#define SIGNAL_CAST (void (*)(__harg))
-#ifndef HPUX10 /* This is only needed for HPUX 9.x */
-#define SELECT_CAST (int *)
-#endif /* HPUX10 */
-#define SYSV
-#define USE_WAITPID
-#define WAIT3_CAST2 (int *)
-#define USE_GETCWD
-#define USE_SETSID
-#define USE_SETRES
-#define DEFAULT_PRINTING PRINT_HPUX
-/* Ken Weiss <krweiss@ucdavis.edu> tells us that SIGCLD_IGNORE is
- not good for HPUX */
-/* #define SIGCLD_IGNORE */
-#endif /* HPUX */
-
-
-#ifdef SEQUENT
-#include <signal.h>
-#include <string.h>
-#include <dirent.h>
-#include <sys/types.h>
-#include <sys/statfs.h>
-#include <sys/stat.h>
-#include <sys/buf.h>
-#include <sys/socket.h>
-#include <unistd.h>
-#include <fcntl.h>
-#define SIGNAL_CAST (void (*)(int))
-#define USE_WAITPID
-#define USE_GETCWD
-#define NO_EID
-#define STATFS4
-#define USE_DIRECT
-#ifdef PTX4
-#undef USE_DIRECT
-#endif
-#endif
-
-
-
-#ifdef SEQUENT_PTX4
-#include <string.h>
-#include <sys/dir.h>
-#include <dirent.h>
-#include <sys/statfs.h>
-#include <sys/statvfs.h>
-#include <sys/vfs.h>
-#include <fcntl.h>
-#include <sys/sockio.h>
-#include <netinet/tcp.h>
-#include <stropts.h>
-#include <termios.h>
-#define SYSV
-#define USE_WAITPID
-#define SIGNAL_CAST (void (*)(int))
-#define USE_STATVFS
-#define USE_GETCWD
-#ifndef seteuid
-#define seteuid(uid) setreuid(-1,uid)
-#endif
-#ifndef setegid
-#define setegid(gid) setregid(-1,gid)
-#endif
-#endif
-
-
-#ifdef NEXT2
-#include <sys/types.h>
-#include <strings.h>
-#include <dirent.h>
-#include <sys/vfs.h>
-#define bzero(b,len) memset(b,0,len)
-#define mode_t int
-#define NO_UTIMBUF
-#include <libc.h>
-#define NOSTRDUP
-#define USE_DIRECT
-#define USE_WAITPID
-#endif
-
-
-#ifdef NEXT3_0
-#include <strings.h>
-#include <sys/dir.h>
-#include <sys/vfs.h>
-#define bzero(b,len) memset(b,0,len)
-#define NO_UTIMBUF
-#include <libc.h>
-#define NOSTRDUP
-#define USE_DIRECT
-#define mode_t int
-#define GID_TYPE int
-#define gid_t int
-#define pid_t int
-#define SIGNAL_CAST (void (*)(int))
-#define WAIT3_CAST1 (union wait *)
-#define HAVE_GMTOFF
-#endif
-
-
-
-#ifdef APOLLO
-#include <string.h>
-#include <fcntl.h>
-#include <sys/statfs.h>
-#define NO_UTIMBUF
-#define USE_DIRECT
-#define USE_GETCWD
-#define SIGNAL_CAST (void (*)())
-#define HAVE_FCNTL_LOCK 0
-#define HAVE_GETTIMEOFDAY
-#define STATFS4
-#endif
-
-
-
-#ifdef SCO
-#include <sys/netinet/tcp.h>
-#include <sys/netinet/in_systm.h>
-#include <sys/netinet/ip.h>
-#include <dirent.h>
-#include <string.h>
-#include <fcntl.h>
-#include <sys/statfs.h>
-#include <sys/stropts.h>
-#include <limits.h>
-#include <locale.h>
-#ifdef EVEREST
-#include <unistd.h>
-#endif /* EVEREST */
-#ifdef NETGROUP
-#include <rpcsvc/ypclnt.h>
-#endif /* NETGROUP */
-#ifdef SecureWare
-#include <sys/security.h>
-#include <sys/audit.h>
-#include <prot.h>
-#define crypt bigcrypt
-#endif /* SecureWare */
-#define SIGNAL_CAST (void (*)(int))
-#define USE_WAITPID
-#define USE_GETCWD
-#define USE_SETSID
-#ifdef SCO3_2_2
-#define setuid(u) setreuid(u,-1)
-#define seteuid(u) setreuid(-1,u)
-#else /* SCO3_2_2 */
-#ifndef EVEREST
-#define ftruncate(f,l) syscall(0x0a28,f,l)
-#define USE_IFREQ
-#define NO_INITGROUPS
-#endif /* EVEREST */
-#endif /* SCO3_2_2 */
-#define STATFS4
-#define NO_FSYNC
-#define HAVE_PATHCONF
-#define NO_GETRLIMIT
-#endif /* SCO */
-
-
-
-/* Definitions for RiscIX */
-#ifdef RiscIX
-#define SIGNAL_CAST (void (*)(int))
-#include <sys/dirent.h>
-#include <sys/acct.h>
-#include <sys/vfs.h>
-#include <string.h>
-#include <utime.h>
-#include <signal.h>
-#define HAVE_GETTIMEOFDAY
-#define NOSTRCASECMP
-#define NOSTRDUP
-#endif
-
-
-
-#ifdef ISC
-#include <net/errno.h>
-#include <string.h>
-#include <sys/dir.h>
-#include <dirent.h>
-#include <sys/statfs.h>
-#include <fcntl.h>
-#include <sys/sioctl.h>
-#include <stropts.h>
-#include <limits.h>
-#include <netinet/tcp.h>
-#define FIONREAD FIORDCHK
-#define SYSV
-#define USE_WAITPID
-#define SIGNAL_CAST (void (*)(int))
-#define USE_GETCWD
-#define USE_SETSID
-#define USE_IFREQ
-#define NO_FTRUNCATE
-#define STATFS4
-#define NO_FSYNC
-#endif
-
-
-
-#ifdef AUX
-#include <fstab.h>
-#include <string.h>
-#include <dirent.h>
-#include <sys/vfs.h>
-#include <fcntl.h>
-#include <termios.h>
-#define SYSV
-#define USE_WAITPID
-#define SIGNAL_CAST (void (*)(int))
-char *strdup (char *);
-#define USE_GETCWD
-#endif
-
-
-#ifdef M88K_R3
-#include <string.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <termios.h>
-#define STATFS4
-#define SYSV
-#define USE_WAITPID
-#define SIGNAL_CAST (void (*)(int))
-char *strdup (char *);
-#define USE_GETCWD
-#define NO_FSYNC
-#define NO_EID
-#endif
-
-
-#ifdef DNIX
-#include <dirent.h>
-#include <string.h>
-#include <fcntl.h>
-#include <sys/statfs.h>
-#include <sys/stropts.h>
-#define NO_GET_BROADCAST
-#define USE_WAITPID
-#define USE_GETCWD
-#define USE_SETSID
-#define STATFS4
-#define NO_EID
-#define PF_INET AF_INET
-#define NO_STRERROR
-#define ftruncate(f,l) chsize(f,l)
-#endif /* DNIX */
-
-#ifdef CONVEX
-#include <netinet/tcp.h>
-#include <arpa/inet.h>
-#include <dirent.h>
-#include <string.h>
-#include <sys/vfs.h>
-#include <fcntl.h>
-#define DONT_REINSTALL_SIG
-#define USE_SIGBLOCK
-#define USE_WAITPID
-#define SIGNAL_CAST (_SigFunc_Ptr_t)
-#define NO_GETSPNAM
-#define HAVE_MEMMOVE
-extern char *mktemp(char *);
-extern int fsync(int);
-extern int seteuid(uid_t);
-extern int setgroups(int, int *);
-extern int initgroups(char *, int);
-extern int statfs(char *, struct statfs *);
-extern int setegid(gid_t);
-extern int getopt(int, char *const *, const char *);
-extern int chroot(char *);
-extern int gettimeofday(struct timeval *, struct timezone *);
-extern int gethostname(char *, int);
-extern char *crypt(char *, char *);
-extern char *getpass(char *);
-#endif
-
-
-#ifdef CRAY
-#define MAXPATHLEN 1024
-#include <dirent.h>
-#include <string.h>
-#include <fcntl.h>
-#include <sys/statfs.h>
-#define SIGNAL_CAST (void (*)(int))
-#define SIGCLD_IGNORE
-#define HAVE_FCNTL_LOCK 1
-#define USE_SETSID
-#define STATFS4
-#endif
-
-
-#ifdef ALTOS
-#include <unistd.h>
-#include <string.h>
-#include <dirent.h>
-#include <sys/fcntl.h>
-#include <sys/statfs.h>
-#define const
-#define uid_t int
-#define gid_t int
-#define mode_t int
-#define ptrdiff_t int
-#define HAVE_GETGRNAM 0
-#define NO_EID
-#define NO_FSYNC
-#define NO_FTRUNCATE
-#define NO_GETRLIMIT
-#define NO_INITGROUPS
-#define NO_SELECT
-#define NO_SETGROUPS
-#define NO_STRERROR
-#define NO_STRFTIME
-#define NO_TM_NAME
-#define NO_UTIMEH
-#define NOSTRCASECMP
-#define REPLACE_MKTIME
-#define REPLACE_RENAME
-#define REPLACE_STRSTR
-#define STATFS4
-#define USE_GETCWD
-#endif
-
-#ifdef QNX
-#define STATFS4
-#include <sys/statfs.h>
-#include <sys/select.h>
-#include <signal.h>
-#include <sys/dir.h>
-#define SIGNAL_CAST (void (*)())
-#define USE_WAITPID
-#define NO_INITGROUPS
-#define NO_SETGROUPS
-#define HAVE_TIMEZONE
-#define USE_GETCWD
-#define USE_SETSID
-#define HAVE_FCNTL_LOCK 1
-#define DEFAULT_PRINTING PRINT_QNX
-#endif
-
-
-#ifdef NEWS42
-#include <string.h>
-#include <dirent.h>
-#include <sys/vfs.h>
-#include <sys/timeb.h>
-typedef int mode_t;
-#endif
-
-#ifdef OS2
-#include <dirent.h>
-#include <sys/statfs.h>
-#include <string.h>
-#include <limits.h>
-#define SIGNAL_CAST (void (*)())
-#define HAVE_FCNTL_LOCK 0
-#define USE_WAITPID
-#define NO_GET_BROADCAST
-#define NO_EID
-#define NO_SETGROUPS
-#define NO_INITGROUPS
-#define NO_CRYPT
-#define NO_STATFS
-#define NO_CHROOT
-#define NO_CHOWN
-#define strcasecmp stricmp
-#define strncasecmp strnicmp
-#endif
-
-
-#ifdef LYNX
-#define SIGNAL_CAST (void (*)())
-#define WAIT3_CAST1 (union wait *)
-#define STATFS4
-#include <fcntl.h>
-#include <resource.h>
-#include <stat.h>
-#include <string.h>
-#include <dirent.h>
-#include <sys/statfs.h>
-#define USE_GETCWD
-#define USE_GETSID
-#endif
-
-
-#ifdef BOS
-#define SIGNAL_CAST (void (*)(int))
-#include <string.h>
-#include <sys/dir.h>
-#include <sys/select.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <sys/statfs.h>
-#include <sys/bsdioctl.h>
-#endif
-
-#ifdef AMIGA
-#include <arpa/inet.h>
-#include <dirent.h>
-#include <string.h>
-#include <netinet/tcp.h>
-#include <sys/acct.h>
-#include <sys/fcntl.h>
-#include <sys/filio.h>
-#include <sys/sockio.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <sys/termios.h>
-#include <limits.h>
-#include <sys/timeb.h>
-
-#define SIGNAL_CAST (void (*)(int))
-#define USE_GETCWD
-#define HAVE_BZERO
-#define HAVE_MEMMOVE
-#define USE_SIGPROCMASK
-#define USE_WAITPID
-#define USE_DIRECT
-#define USE_F_FSIZE
-#define HAVE_FCNTL_LOCK 0
-#define HAVE_GETTIMEOFDAY
-#define HAVE_PATHCONF
-
-#define HAVE_NO_PROC
-#define NO_FORK_DEBUG
-#define HAVE_FORK 0
-#define HAVE_VFORK 1
-#endif
-
-/* For UnixWare 2.x's ia_uinfo routines. (tangent@cyberport.com) */
-#ifdef IA_UINFO
-#include <iaf.h>
-#include <ia.h>
-#endif
-
-
-/*******************************************************************
-end of the platform specific sections
-********************************************************************/
-
-#if defined(USE_MMAP) || defined(FAST_SHARE_MODES)
-#include <sys/mman.h>
-#endif
-
-#ifdef SecureWare
-#define NEED_AUTH_PARAMETERS
-#endif
-
-#ifdef REPLACE_GETPASS
-extern char *getsmbpass(char *);
-#define getpass(s) getsmbpass(s)
-#endif
-
-#ifdef REPLACE_INNETGR
-#define innetgr(group,host,user,dom) InNetGr(group,host,user,dom)
-#endif
-
-#ifndef FD_SETSIZE
-#define FD_SETSIZE 255
-#endif
-
-#ifndef __STDC__
-#define const
-#endif
-
-/* Now for some other grungy stuff */
-#ifdef NO_GETSPNAM
-struct spwd { /* fake shadow password structure */
- char *sp_pwdp;
-};
-#endif
-
-#ifndef HAVE_BZERO
-#ifndef bzero
-#define bzero(p,s) memset(p,0,s)
-#endif
-#endif
-
-#ifndef HAVE_MEMMOVE
-#ifndef memmove
-#define memmove(d,s,n) MemMove(d,s,n)
-#endif
-#endif
-
-#ifdef USE_DIRECT
-#include <sys/dir.h>
-#endif
-
-/* some unixes have ENOTTY instead of TIOCNOTTY */
-#ifndef TIOCNOTTY
-#ifdef ENOTTY
-#define TIOCNOTTY ENOTTY
-#endif
-#endif
-
-#ifndef SIGHUP
-#define SIGHUP 1
-#endif
-
-/* if undefined then use bsd or sysv printing */
-#ifndef DEFAULT_PRINTING
-#ifdef SYSV
-#define DEFAULT_PRINTING PRINT_SYSV
-#else
-#define DEFAULT_PRINTING PRINT_BSD
-#endif
-#endif
-
-
-#ifdef AFS_AUTH
-#include <afs/stds.h>
-#include <afs/kautils.h>
-#endif
-
-#ifdef DFS_AUTH
-#include <dce/dce_error.h>
-#include <dce/sec_login.h>
-#endif
-
-#ifdef KRB5_AUTH
-#include <krb5.h>
-#endif
-
-#ifdef NO_UTIMBUF
-struct utimbuf {
- time_t actime;
- time_t modtime;
-};
-#endif
-
-#ifdef NO_STRERROR
-#ifndef strerror
-extern char *sys_errlist[];
-#define strerror(i) sys_errlist[i]
-#endif
-#endif
-
-#ifndef perror
-#define perror(m) printf("%s: %s\n",m,strerror(errno))
-#endif
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 255
-#endif
-
-#include "version.h"
-#include "smb.h"
-#include "nameserv.h"
-#include "proto.h"
-#include "byteorder.h"
-
-#include "kanji.h"
-#include "charset.h"
-
-#ifndef S_IFREG
-#define S_IFREG 0100000
-#endif
-
-#ifndef S_ISREG
-#define S_ISREG(x) ((S_IFREG & (x))!=0)
-#endif
-
-#ifndef S_ISDIR
-#define S_ISDIR(x) ((S_IFDIR & (x))!=0)
-#endif
-
-#if !defined(S_ISLNK) && defined(S_IFLNK)
-#define S_ISLNK(x) ((S_IFLNK & (x))!=0)
-#endif
-
-#ifdef UFC_CRYPT
-#define crypt ufc_crypt
-#endif
-
-#ifdef REPLACE_STRLEN
-#define strlen(s) Strlen(s)
-#endif
-
-#ifdef REPLACE_STRSTR
-#define strstr(s,p) Strstr(s,p)
-#endif
-
-#ifdef REPLACE_MKTIME
-#define mktime(t) Mktime(t)
-#endif
-
-#ifndef NGROUPS_MAX
-#define NGROUPS_MAX 128
-#endif
-
-#ifndef EDQUOT
-#define EDQUOT ENOSPC
-#endif
-
-#ifndef HAVE_GETGRNAM
-#define HAVE_GETGRNAM 1
-#endif
-
-#ifndef SOL_TCP
-#define SOL_TCP 6
-#endif
-
-/* default to using ftruncate workaround as this is safer than assuming
-it works and getting lots of bug reports */
-#ifndef FTRUNCATE_CAN_EXTEND
-#define FTRUNCATE_CAN_EXTEND 0
-#endif
-
-/* maybe this unix doesn't separate RD and WR locks? */
-#ifndef F_RDLCK
-#define F_RDLCK F_WRLCK
-#endif
-
-#ifndef ENOTSOCK
-#define ENOTSOCK EINVAL
-#endif
-
-#ifndef SIGCLD
-#define SIGCLD SIGCHLD
-#endif
-
-#ifndef MAP_FILE
-#define MAP_FILE 0
-#endif
-
-#ifndef HAVE_FCNTL_LOCK
-#define HAVE_FCNTL_LOCK 1
-#endif
-
-#ifndef WAIT3_CAST2
-#define WAIT3_CAST2 (struct rusage *)
-#endif
-
-#ifndef WAIT3_CAST1
-#define WAIT3_CAST1 (int *)
-#endif
-
-#ifndef QSORT_CAST
-#define QSORT_CAST (int (*)())
-#endif
-
-#ifndef INADDR_LOOPBACK
-#define INADDR_LOOPBACK 0x7f000001
-#endif /* INADDR_LOOPBACK */
-
-/* this is a rough check to see if this machine has a lstat() call.
- it is not guaranteed to work */
-#if !defined(S_ISLNK)
-#define lstat stat
-#endif
-
-/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
-#ifndef errno
-extern int errno;
-#endif
-
-
-#ifdef NO_EID
-#define geteuid() getuid()
-#define getegid() getgid()
-#define seteuid(x) setuid(x)
-#define setegid(x) setgid(x)
-#endif
-
-
-#if (HAVE_FCNTL_LOCK == 0)
-/* since there is no locking available, system includes */
-/* for DomainOS 10.4 do not contain any of the following */
-/* #define's. So, to satisfy the compiler, add these */
-/* #define's, although they arn't really necessary. */
-#define F_GETLK 0
-#define F_SETLK 0
-#define F_WRLCK 0
-#define F_UNLCK 0
-#endif /* HAVE_FCNTL_LOCK == 0 */
-
-#ifdef NOSTRCASECMP
-#define strcasecmp(s1,s2) StrCaseCmp(s1,s2)
-#define strncasecmp(s1,s2,n) StrnCaseCmp(s1,s2,n)
-#endif
-
-#ifndef strcpy
-#define strcpy(dest,src) StrCpy(dest,src)
-#endif
-
-
-/* possibly wrap the malloc calls */
-#if WRAP_MALLOC
-
-/* undo the old malloc def if necessary */
-#ifdef malloc
-#define xx_old_malloc malloc
-#undef malloc
-#endif
-
-#define malloc(size) malloc_wrapped(size,__FILE__,__LINE__)
-
-/* undo the old realloc def if necessary */
-#ifdef realloc
-#define xx_old_realloc realloc
-#undef realloc
-#endif
-
-#define realloc(ptr,size) realloc_wrapped(ptr,size,__FILE__,__LINE__)
-
-/* undo the old free def if necessary */
-#ifdef free
-#define xx_old_free free
-#undef free
-#endif
-
-#define free(ptr) free_wrapped(ptr,__FILE__,__LINE__)
-
-/* and the malloc prototypes */
-void *malloc_wrapped(int,char *,int);
-void *realloc_wrapped(void *,int,char *,int);
-void free_wrapped(void *,char *,int);
-
-#endif
-
-
-#if WRAP_MEMCPY
-/* undo the old memcpy def if necessary */
-#ifdef memcpy
-#define xx_old_memcpy memcpy
-#undef memcpy
-#endif
-
-#define memcpy(d,s,l) memcpy_wrapped(d,s,l,__FILE__,__LINE__)
-void *memcpy_wrapped(void *d,void *s,int l,char *fname,int line);
-#endif
-
-#endif
diff --git a/source/include/kanji.h b/source/include/kanji.h
deleted file mode 100644
index cf303659208..00000000000
--- a/source/include/kanji.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Kanji Extensions
- Copyright (C) Andrew Tridgell 1992-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.
-
- Adding for Japanese language by <fujita@ainix.isac.co.jp> 1994.9.5
- and extend coding system to EUC/SJIS/JIS/HEX at 1994.10.11
- and add all jis codes sequence at 1995.8.16
- Notes: Hexadecimal code by <ohki@gssm.otuka.tsukuba.ac.jp>
- and add upper/lower case conversion 1997.8.21
-*/
-#ifndef _KANJI_H_
-#define _KANJI_H_
-
-/* FOR SHIFT JIS CODE */
-#define is_shift_jis(c) \
- ((0x81 <= ((unsigned char) (c)) && ((unsigned char) (c)) <= 0x9f) \
- || (0xe0 <= ((unsigned char) (c)) && ((unsigned char) (c)) <= 0xef))
-#define is_shift_jis2(c) \
- (0x40 <= ((unsigned char) (c)) && ((unsigned char) (c)) <= 0xfc \
- && ((unsigned char) (c)) != 0x7f)
-#define is_kana(c) ((0xa0 <= ((unsigned char) (c)) && ((unsigned char) (c)) <= 0xdf))
-
-/* case conversion */
-#define is_sj_upper2(c) \
- ((0x60 <= (unsigned char) (c)) && ((unsigned char) (c) <= 0x79))
-#define is_sj_lower2(c) \
- ((0x81 <= (unsigned char) (c)) && ((unsigned char) (c) <= 0x9A))
-#define sjis_alph 0x82
-#define is_sj_alph(c) (sjis_alph == (unsigned char) (c))
-#define is_sj_upper(c1, c2) (is_sj_alph (c1) && is_sj_upper2 (c2))
-#define is_sj_lower(c1, c2) (is_sj_alph (c1) && is_sj_lower2 (c2))
-#define sj_toupper2(c) \
- (is_sj_lower2 (c) ? ((int) ((unsigned char) (c) - 0x81 + 0x60)) : \
- ((int) (unsigned char) (c)))
-#define sj_tolower2(c) \
- (is_sj_upper2 (c) ? ((int) ((unsigned char) (c) - 0x60 + 0x81)) : \
- ((int) (unsigned char) (c)))
-
-#ifdef _KANJI_C_
-/* FOR EUC CODE */
-#define euc_kana (0x8e)
-#define is_euc_kana(c) (((unsigned char) (c)) == euc_kana)
-#define is_euc(c) (0xa0 < ((unsigned char) (c)) && ((unsigned char) (c)) < 0xff)
-
-/* FOR JIS CODE */
-/* default jis third shift code, use for output */
-#ifndef JIS_KSO
-#define JIS_KSO 'B'
-#endif
-#ifndef JIS_KSI
-#define JIS_KSI 'J'
-#endif
-/* in: \E$B or \E$@ */
-/* out: \E(J or \E(B or \E(H */
-#define jis_esc (0x1b)
-#define jis_so (0x0e)
-#define jis_so1 ('$')
-#define jis_so2 ('B')
-#define jis_si (0x0f)
-#define jis_si1 ('(')
-#define jis_si2 ('J')
-#define is_esc(c) (((unsigned char) (c)) == jis_esc)
-#define is_so1(c) (((unsigned char) (c)) == jis_so1)
-#define is_so2(c) (((unsigned char) (c)) == jis_so2 || ((unsigned char) (c)) == '@')
-#define is_si1(c) (((unsigned char) (c)) == jis_si1)
-#define is_si2(c) (((unsigned char) (c)) == jis_si2 || ((unsigned char) (c)) == 'B' \
- || ((unsigned char) (c)) == 'H')
-#define is_so(c) (((unsigned char) (c)) == jis_so)
-#define is_si(c) (((unsigned char) (c)) == jis_si)
-#define junet_kana1 ('(')
-#define junet_kana2 ('I')
-#define is_juk1(c) (((unsigned char) (c)) == junet_kana1)
-#define is_juk2(c) (((unsigned char) (c)) == junet_kana2)
-
-#define _KJ_ROMAN (0)
-#define _KJ_KANJI (1)
-#define _KJ_KANA (2)
-
-/* FOR HEX */
-#define HEXTAG ':'
-#define hex2bin(x) \
- ( ((int) '0' <= ((int) (x)) && ((int) (x)) <= (int)'9')? \
- (((int) (x))-(int)'0'): \
- ((int) 'a'<= ((int) (x)) && ((int) (x))<= (int) 'f')? \
- (((int) (x)) - (int)'a'+10): \
- (((int) (x)) - (int)'A'+10) )
-#define bin2hex(x) \
- ( (((int) (x)) >= 10)? (((int) (x))-10 + (int) 'a'): (((int) (x)) + (int) '0') )
-
-#else /* not _KANJI_C_ */
-
-extern char *(*_dos_to_unix)(char *str, BOOL overwrite);
-extern char *(*_unix_to_dos)(char *str, BOOL overwrite);
-
-#define strchr sj_strchr
-#define strrchr sj_strrchr
-#define strstr sj_strstr
-#define strtok sj_strtok
-
-#endif /* _KANJI_C_ */
-
-#define UNKNOWN_CODE (-1)
-#define SJIS_CODE (0)
-#define EUC_CODE (1)
-#define JIS7_CODE (2)
-#define JIS8_CODE (3)
-#define JUNET_CODE (4)
-#define HEX_CODE (5)
-#define CAP_CODE (6)
-#define DOSV_CODE SJIS_CODE
-
-int interpret_coding_system (char *str, int def);
-
-#define unix_to_dos(x,y) unix2dos_format(x,y)
-#define dos_to_unix(x,y) dos2unix_format(x,y)
-
-#endif /* _KANJI_H_ */
diff --git a/source/include/local.h b/source/include/local.h
deleted file mode 100644
index 97857727c74..00000000000
--- a/source/include/local.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/* local definitions for file server */
-#ifndef _LOCAL_H
-#define _LOCAL_H
-
-/* This defines the section name in the configuration file that will contain */
-/* global parameters - that is, parameters relating to the whole server, not */
-/* just services. This name is then reserved, and may not be used as a */
-/* a service name. It will default to "global" if not defined here. */
-#define GLOBAL_NAME "global"
-#define GLOBAL_NAME2 "globals"
-
-/* This defines the section name in the configuration file that will
- refer to the special "homes" service */
-#define HOMES_NAME "homes"
-
-/* This defines the section name in the configuration file that will
- refer to the special "printers" service */
-#define PRINTERS_NAME "printers"
-
-/* This defines the name of the printcap file. It is MOST UNLIKELY that
- this will change BUT! Specifying a file with the format of a printcap
- file but containing only a subset of the printers actually in your real
- printcap file is a quick-n-dirty way to allow dynamic access to a subset
- of available printers.
-*/
-#define PRINTCAP_NAME "/etc/printcap"
-
-/* set these to define the limits of the server. NOTE These are on a
- per-client basis. Thus any one machine can't connect to more than
- MAX_CONNECTIONS services, but any number of machines may connect at
- one time. */
-#define MAX_CONNECTIONS 127
-#define MAX_OPEN_FILES 100
-
-/* the max number of connections that the smbstatus program will show */
-#define MAXSTATUS 1000
-
-/* max number of directories open at once */
-/* note that with the new directory code this no longer requires a
- file handle per directory, but large numbers do use more memory */
-#define MAXDIR 64
-
-#define WORDMAX 0xFFFF
-
-/* the maximum password length before we declare a likely attack */
-#define MAX_PASS_LEN 200
-
-/* separators for lists */
-#define LIST_SEP " \t,;:\n\r"
-
-#ifndef LOCKDIR
-/* this should have been set in the Makefile */
-#define LOCKDIR "/tmp/samba"
-#endif
-
-/* this is where browse lists are kept in the lock dir */
-#define SERVER_LIST "browse.dat"
-
-/* shall guest entries in printer queues get changed to user entries,
- so they can be deleted using the windows print manager? */
-#define LPQ_GUEST_TO_USER
-
-/* shall filenames with illegal chars in them get mangled in long
- filename listings? */
-#define MANGLE_LONG_FILENAMES
-
-/* define this if you want to stop spoofing with .. and soft links
- NOTE: This also slows down the server considerably */
-#define REDUCE_PATHS
-
-/* the size of the directory cache */
-#define DIRCACHESIZE 20
-
-/* what type of filesystem do we want this to show up as in a NT file
- manager window? */
-#define FSTYPE_STRING "Samba"
-
-/* do you want smbd to send a 1 byte packet to nmbd to trigger it to start
- when smbd starts? */
-#ifndef PRIME_NMBD
-#define PRIME_NMBD 1
-#endif
-
-/* do you want session setups at user level security with a invalid
- password to be rejected or allowed in as guest? WinNT rejects them
- but it can be a pain as it means "net view" needs to use a password
-
- You have 3 choices:
-
- GUEST_SESSSETUP = 0 means session setups with an invalid password
- are rejected.
-
- GUEST_SESSSETUP = 1 means session setups with an invalid password
- are rejected, unless the username does not exist, in which case it
- is treated as a guest login
-
- GUEST_SESSSETUP = 2 means session setups with an invalid password
- are treated as a guest login
-
- Note that GUEST_SESSSETUP only has an effect in user or server
- level security.
- */
-#ifndef GUEST_SESSSETUP
-#define GUEST_SESSSETUP 0
-#endif
-
-/* the default pager to use for the client "more" command. Users can
- override this with the PAGER environment variable */
-#ifndef PAGER
-#define PAGER "more"
-#endif
-
-/* the size of the uid cache used to reduce valid user checks */
-#define UID_CACHE_SIZE 4
-
-/* the following control timings of various actions. Don't change
- them unless you know what you are doing. These are all in seconds */
-#define DEFAULT_SMBD_TIMEOUT (60*60*24*7)
-#define SMBD_RELOAD_CHECK (60)
-#define IDLE_CLOSED_TIMEOUT (60)
-#define DPTR_IDLE_TIMEOUT (120)
-#define SMBD_SELECT_LOOP (10)
-#define NMBD_SELECT_LOOP (10)
-#define BROWSE_INTERVAL (60)
-#define REGISTRATION_INTERVAL (10*60)
-#define NMBD_INETD_TIMEOUT (120)
-#define NMBD_MAX_TTL (24*60*60)
-#define LPQ_LOCK_TIMEOUT (5)
-
-/* the following are in milliseconds */
-#define LOCK_RETRY_TIMEOUT (100)
-
-/* do you want to dump core (carefully!) when an internal error is
- encountered? Samba will be careful to make the core file only
- accessible to root */
-#define DUMP_CORE 1
-
-/* what is the longest significant password available on your system?
- Knowing this speeds up password searches a lot */
-#ifndef PASSWORD_LENGTH
-#define PASSWORD_LENGTH 8
-#endif
-
-#define SMB_ALIGNMENT 1
-
-
-/* shall we support browse requests via a FIFO to nmbd? */
-#define ENABLE_FIFO 1
-
-/* keep the password server open, this uses up a aocket, but is needed
- by many apps */
-#define KEEP_PASSWORD_SERVER_OPEN 1
-
-/* how long to wait for a socket connect to happen */
-#define LONG_CONNECT_TIMEOUT 30
-#define SHORT_CONNECT_TIMEOUT 5
-
-
-/* the directory to sit in when idle */
-/* #define IDLE_DIR "/" */
-
-/* Timout (in seconds) to wait for an oplock break
- message to return. */
-
-#define OPLOCK_BREAK_TIMEOUT 30
-
-#endif
diff --git a/source/include/nameserv.h b/source/include/nameserv.h
deleted file mode 100644
index 83f3a3c5246..00000000000
--- a/source/include/nameserv.h
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios header - version 2
- Copyright (C) Andrew Tridgell 1994-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.
-
-*/
-
-#define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
-
-/* NTAS uses 2, NT uses 1, WfWg uses 0 */
-#define MAINTAIN_LIST 2
-#define ELECTION_VERSION 1
-
-#define MAX_DGRAM_SIZE (576) /* tcp/ip datagram limit is 576 bytes */
-#define MIN_DGRAM_SIZE 12
-
-#define NMB_QUERY 0x20
-#define NMB_STATUS 0x21
-
-#define NMB_REG 0x05 /* see rfc1002.txt 4.2.2,3,5,6,7,8 */
-#define NMB_REG_REFRESH 0x09 /* see rfc1002.txt 4.2.4 */
-#define NMB_REL 0x06 /* see rfc1002.txt 4.2.9,10,11 */
-#define NMB_WAIT_ACK 0x07 /* see rfc1002.txt 4.2.16 */
-/* XXXX what about all the other types?? 0x1, 0x2, 0x3, 0x4, 0x8? */
-
-#define FIND_SELF 0x01
-#define FIND_WINS 0x02
-#define FIND_LOCAL 0x04
-
-/* NetBIOS flags */
-#define NB_GROUP 0x80
-#define NB_PERM 0x02
-#define NB_ACTIVE 0x04
-#define NB_CONFL 0x08
-#define NB_DEREG 0x10
-#define NB_BFLAG 0x00 /* broadcast node type */
-#define NB_PFLAG 0x20 /* point-to-point node type */
-#define NB_MFLAG 0x40 /* mixed bcast & p-p node type */
-#define NB_HFLAG 0x60 /* microsoft 'hybrid' node type */
-#define NB_FLGMSK 0x60
-
-#define REFRESH_TIME (15*60)
-#define NAME_POLL_REFRESH_TIME (5*60)
-#define NAME_POLL_INTERVAL 15
-
-/* NetBIOS flag identifier */
-#define NAME_PERMANENT(p) ((p) & NB_PERM)
-#define NAME_ACTIVE(p) ((p) & NB_ACTIVE)
-#define NAME_CONFLICT(p) ((p) & NB_CONFL)
-#define NAME_DEREG(p) ((p) & NB_DEREG)
-#define NAME_GROUP(p) ((p) & NB_GROUP)
-
-#define NAME_BFLAG(p) (((p) & NB_FLGMSK) == NB_BFLAG)
-#define NAME_PFLAG(p) (((p) & NB_FLGMSK) == NB_PFLAG)
-#define NAME_MFLAG(p) (((p) & NB_FLGMSK) == NB_MFLAG)
-#define NAME_HFLAG(p) (((p) & NB_FLGMSK) == NB_HFLAG)
-
-/* server type identifiers */
-#define AM_MASTER(work) (work->ServerType & SV_TYPE_MASTER_BROWSER)
-#define AM_BACKUP(work) (work->ServerType & SV_TYPE_BACKUP_BROWSER)
-#define AM_DOMMST(work) (work->ServerType & SV_TYPE_DOMAIN_MASTER)
-#define AM_DOMMEM(work) (work->ServerType & SV_TYPE_DOMAIN_MEMBER)
-
-/* microsoft browser NetBIOS name */
-#define MSBROWSE "\001\002__MSBROWSE__\002"
-
-/* mail slots */
-#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE"
-#define NET_LOGON_MAILSLOT "\\MAILSLOT\\NET\\NETLOGON"
-
-enum name_source {STATUS_QUERY, LMHOSTS, REGISTER, SELF, DNS, DNSFAIL};
-enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3};
-enum packet_type {NMB_PACKET, DGRAM_PACKET};
-
-enum master_state
-{
- MST_POTENTIAL,
- MST_BACK,
- MST_MSB,
- MST_BROWSER
-};
-
-enum domain_state
-{
- DOMAIN_NONE,
- DOMAIN_WAIT,
- DOMAIN_MST
-};
-
-enum logon_state
-{
- LOGON_NONE,
- LOGON_WAIT,
- LOGON_SRV
-};
-
-enum state_type
-{
- NAME_STATUS_DOM_SRV_CHK,
- NAME_STATUS_SRV_CHK,
- NAME_REGISTER_CHALLENGE,
- NAME_REGISTER,
- NAME_RELEASE,
- NAME_QUERY_CONFIRM,
- NAME_QUERY_SYNC_LOCAL,
- NAME_QUERY_SYNC_REMOTE,
- NAME_QUERY_DOM_SRV_CHK,
- NAME_QUERY_SRV_CHK,
- NAME_QUERY_FIND_MST,
- NAME_QUERY_MST_CHK,
- NAME_QUERY_DOMAIN
-};
-
-/* a netbios name structure */
-struct nmb_name {
- char name[17];
- char scope[64];
- int name_type;
-};
-
-/* a netbios flags + ip address structure */
-/* this is used for multi-homed systems and for internet group names */
-struct nmb_ip
-{
- struct in_addr ip; /* ip address of host that owns this name */
- uint16 nb_flags; /* netbios flags */
-};
-
-/* this is the structure used for the local netbios name list */
-struct name_record
-{
- struct name_record *next;
- struct name_record *prev;
-
- struct nmb_name name; /* the netbios name */
- struct nmb_ip *ip_flgs; /* the ip + flags */
- int num_ips; /* number of ip+flags entries */
-
- enum name_source source; /* where the name came from */
-
- time_t death_time; /* time record must be removed (do not remove if 0) */
- time_t refresh_time; /* time record should be refreshed */
-};
-
-struct subnet_record;
-
-/* browse and backup server cache for synchronising browse list */
-struct browse_cache_record
-{
- struct browse_cache_record *next;
- struct browse_cache_record *prev;
-
- pstring name;
- int type;
- pstring group;
- struct in_addr ip;
- time_t sync_time;
- BOOL synced;
- BOOL local;
- struct subnet_record *subnet;
-};
-
-/* this is used to hold the list of servers in my domain, and is */
-/* contained within lists of domains */
-struct server_record
-{
- struct server_record *next;
- struct server_record *prev;
-
- struct server_info_struct serv;
- time_t death_time;
-};
-
-/* a workgroup structure. it contains a list of servers */
-struct work_record
-{
- struct work_record *next;
- struct work_record *prev;
-
- struct server_record *serverlist;
-
- /* stage of development from non-local-master up to local-master browser */
- enum master_state mst_state;
-
- /* stage of development from non-domain-master to domain master browser */
- enum domain_state dom_state;
-
- /* stage of development from non-logon-server to logon server */
- enum logon_state log_state;
-
- /* work group info */
- fstring work_group;
- int token; /* used when communicating with backup browsers */
- int ServerType;
-
- /* announce info */
- time_t lastannounce_time;
- int announce_interval;
- BOOL needannounce;
-
-
- /* election info */
- BOOL RunningElection;
- BOOL needelection;
- int ElectionCount;
- uint32 ElectionCriterion;
-};
-
-/* initiated name queries recorded in this list to track any responses... */
-/* sadly, we need to group everything together. i suppose that if this
- gets unwieldy, then a union ought to be considered. oh for c++... */
-struct response_record
-{
- struct response_record *next;
- struct response_record *prev;
-
- uint16 response_id;
- enum state_type state;
-
- int fd;
- int quest_type;
- struct nmb_name name;
- int nb_flags;
- time_t ttl;
-
- int server_type;
- fstring my_name;
- fstring my_comment;
-
- BOOL bcast;
- BOOL recurse;
- struct in_addr send_ip;
- struct in_addr reply_to_ip;
-
- int num_msgs;
-
- time_t repeat_time;
- time_t repeat_interval;
- int repeat_count;
-};
-
-/* a subnet structure. it contains a list of workgroups and netbios names*/
-
-/* note that a subnet of 255.255.255.255 contains all the WINS netbios names.
- all communication from such nodes are on a non-broadcast basis: they
- are point-to-point (P nodes) or mixed point-to-point and broadcast
- (M nodes). M nodes use point-to-point as a preference, and will use
- broadcasting for certain activities, or will resort to broadcasting as a
- last resort, if the WINS server fails (users of wfwg will notice that their
- machine often freezes for 30 seconds at a time intermittently, if the WINS
- server is down).
-
- B nodes will have their own, totally separate subnet record, with their
- own netbios name set. these do NOT interact with other subnet records'
- netbios names, INCLUDING the WINS one (with an ip "address", so called,
- of 255.255.255.255)
-
- there is a separate response list for each subnet record. in the case of
- the 255.255.255.255 subnet record (WINS), the WINS server will be able to
- use this to poll (infrequently!) each of its entries, to ensure that the
- names are still in use.
- XXXX this polling is a planned feature for a really over-cautious WINS server
-*/
-
-struct subnet_record
-{
- struct subnet_record *next;
- struct subnet_record *prev;
-
- struct work_record *workgrouplist; /* list of workgroups */
- struct name_record *namelist; /* list of netbios names */
- struct response_record *responselist; /* list of responses expected */
-
- struct in_addr bcast_ip;
- struct in_addr mask_ip;
- struct in_addr myip;
-};
-
-/* a resource record */
-struct res_rec {
- struct nmb_name rr_name;
- int rr_type;
- int rr_class;
- int ttl;
- int rdlength;
- char rdata[MAX_DGRAM_SIZE];
-};
-
-/* define a nmb packet. */
-struct nmb_packet
-{
- struct {
- int name_trn_id;
- int opcode;
- BOOL response;
- struct {
- BOOL bcast;
- BOOL recursion_available;
- BOOL recursion_desired;
- BOOL trunc;
- BOOL authoritative;
- } nm_flags;
- int rcode;
- int qdcount;
- int ancount;
- int nscount;
- int arcount;
- } header;
-
- struct {
- struct nmb_name question_name;
- int question_type;
- int question_class;
- } question;
-
- struct res_rec *answers;
- struct res_rec *nsrecs;
- struct res_rec *additional;
-};
-
-
-/* a datagram - this normally contains SMB data in the data[] array */
-struct dgram_packet {
- struct {
- int msg_type;
- struct {
- enum node_type node_type;
- BOOL first;
- BOOL more;
- } flags;
- int dgm_id;
- struct in_addr source_ip;
- int source_port;
- int dgm_length;
- int packet_offset;
- } header;
- struct nmb_name source_name;
- struct nmb_name dest_name;
- int datasize;
- char data[MAX_DGRAM_SIZE];
-};
-
-/* define a structure used to queue packets. this will be a linked
- list of nmb packets */
-struct packet_struct
-{
- struct packet_struct *next;
- struct packet_struct *prev;
- struct in_addr ip;
- int port;
- int fd;
- time_t timestamp;
- enum packet_type packet_type;
- union {
- struct nmb_packet nmb;
- struct dgram_packet dgram;
- } packet;
-};
-
-
-/* ids for netbios packet types */
-#define ANN_HostAnnouncement 1
-#define ANN_AnnouncementRequest 2
-#define ANN_Election 8
-#define ANN_GetBackupListReq 9
-#define ANN_GetBackupListResp 10
-#define ANN_BecomeBackup 11
-#define ANN_DomainAnnouncement 12
-#define ANN_MasterAnnouncement 13
-#define ANN_ResetBrowserState 14
-#define ANN_LocalMasterAnnouncement 15
-
-
-/* broadcast packet announcement intervals, in minutes */
-
-/* attempt to add domain logon and domain master names */
-#define CHECK_TIME_ADD_DOM_NAMES 5
-
-/* search for master browsers of workgroups samba knows about,
- except default */
-#define CHECK_TIME_MST_BROWSE 5
-
-/* request backup browser announcements from other servers */
-#define CHECK_TIME_ANNOUNCE_BACKUP 15
-
-/* request host announcements from other servers: min and max of interval */
-#define CHECK_TIME_MIN_HOST_ANNCE 3
-#define CHECK_TIME_MAX_HOST_ANNCE 12
-
-/* announce as master to WINS server and any Primary Domain Controllers */
-#define CHECK_TIME_MST_ANNOUNCE 15
-
-/* do all remote announcements this often */
-#define REMOTE_ANNOUNCE_INTERVAL 180
-
-/* Types of machine we can announce as */
-#define ANNOUNCE_AS_NT 1
-#define ANNOUNCE_AS_WIN95 2
-#define ANNOUNCE_AS_WFW 3
-
-/* Macro's to enumerate subnets either with or without
- the WINS subnet. */
-
-extern struct subnet_record *subnetlist;
-extern struct subnet_record *wins_subnet;
-
-#define FIRST_SUBNET subnetlist
-#define NEXT_SUBNET_EXCLUDING_WINS(x) ((x)->next)
-#define NEXT_SUBNET_INCLUDING_WINS(x) ( ((x) == wins_subnet) ? NULL : \
- (((x)->next == NULL) ? wins_subnet : \
- (x)->next))
-
diff --git a/source/include/nterr.h b/source/include/nterr.h
deleted file mode 100644
index 92f02612dbc..00000000000
--- a/source/include/nterr.h
+++ /dev/null
@@ -1,505 +0,0 @@
-/* these are the NT error codes less than 1000. They are here for when
- we start supporting NT error codes in Samba. They were extracted
- using a loop in smbclient then printing a netmon sniff to a file */
-
-#define NT_STATUS_UNSUCCESSFUL (1)
-#define NT_STATUS_NOT_IMPLEMENTED (2)
-#define NT_STATUS_INVALID_INFO_CLASS (3)
-#define NT_STATUS_INFO_LENGTH_MISMATCH (4)
-#define NT_STATUS_ACCESS_VIOLATION (5)
-#define NT_STATUS_IN_PAGE_ERROR (6)
-#define NT_STATUS_PAGEFILE_QUOTA (7)
-#define NT_STATUS_INVALID_HANDLE (8)
-#define NT_STATUS_BAD_INITIAL_STACK (9)
-#define NT_STATUS_BAD_INITIAL_PC (10)
-#define NT_STATUS_INVALID_CID (11)
-#define NT_STATUS_TIMER_NOT_CANCELED (12)
-#define NT_STATUS_INVALID_PARAMETER (13)
-#define NT_STATUS_NO_SUCH_DEVICE (14)
-#define NT_STATUS_NO_SUCH_FILE (15)
-#define NT_STATUS_INVALID_DEVICE_REQUEST (16)
-#define NT_STATUS_END_OF_FILE (17)
-#define NT_STATUS_WRONG_VOLUME (18)
-#define NT_STATUS_NO_MEDIA_IN_DEVICE (19)
-#define NT_STATUS_UNRECOGNIZED_MEDIA (20)
-#define NT_STATUS_NONEXISTENT_SECTOR (21)
-#define NT_STATUS_MORE_PROCESSING_REQUIRED (22)
-#define NT_STATUS_NO_MEMORY (23)
-#define NT_STATUS_CONFLICTING_ADDRESSES (24)
-#define NT_STATUS_NOT_MAPPED_VIEW (25)
-#define NT_STATUS_UNABLE_TO_FREE_VM (26)
-#define NT_STATUS_UNABLE_TO_DELETE_SECTION (27)
-#define NT_STATUS_INVALID_SYSTEM_SERVICE (28)
-#define NT_STATUS_ILLEGAL_INSTRUCTION (29)
-#define NT_STATUS_INVALID_LOCK_SEQUENCE (30)
-#define NT_STATUS_INVALID_VIEW_SIZE (31)
-#define NT_STATUS_INVALID_FILE_FOR_SECTION (32)
-#define NT_STATUS_ALREADY_COMMITTED (33)
-#define NT_STATUS_ACCESS_DENIED (34)
-#define NT_STATUS_BUFFER_TOO_SMALL (35)
-#define NT_STATUS_OBJECT_TYPE_MISMATCH (36)
-#define NT_STATUS_NONCONTINUABLE_EXCEPTION (37)
-#define NT_STATUS_INVALID_DISPOSITION (38)
-#define NT_STATUS_UNWIND (39)
-#define NT_STATUS_BAD_STACK (40)
-#define NT_STATUS_INVALID_UNWIND_TARGET (41)
-#define NT_STATUS_NOT_LOCKED (42)
-#define NT_STATUS_PARITY_ERROR (43)
-#define NT_STATUS_UNABLE_TO_DECOMMIT_VM (44)
-#define NT_STATUS_NOT_COMMITTED (45)
-#define NT_STATUS_INVALID_PORT_ATTRIBUTES (46)
-#define NT_STATUS_PORT_MESSAGE_TOO_LONG (47)
-#define NT_STATUS_INVALID_PARAMETER_MIX (48)
-#define NT_STATUS_INVALID_QUOTA_LOWER (49)
-#define NT_STATUS_DISK_CORRUPT_ERROR (50)
-#define NT_STATUS_OBJECT_NAME_INVALID (51)
-#define NT_STATUS_OBJECT_NAME_NOT_FOUND (52)
-#define NT_STATUS_OBJECT_NAME_COLLISION (53)
-#define NT_STATUS_HANDLE_NOT_WAITABLE (54)
-#define NT_STATUS_PORT_DISCONNECTED (55)
-#define NT_STATUS_DEVICE_ALREADY_ATTACHED (56)
-#define NT_STATUS_OBJECT_PATH_INVALID (57)
-#define NT_STATUS_OBJECT_PATH_NOT_FOUND (58)
-#define NT_STATUS_OBJECT_PATH_SYNTAX_BAD (59)
-#define NT_STATUS_DATA_OVERRUN (60)
-#define NT_STATUS_DATA_LATE_ERROR (61)
-#define NT_STATUS_DATA_ERROR (62)
-#define NT_STATUS_CRC_ERROR (63)
-#define NT_STATUS_SECTION_TOO_BIG (64)
-#define NT_STATUS_PORT_CONNECTION_REFUSED (65)
-#define NT_STATUS_INVALID_PORT_HANDLE (66)
-#define NT_STATUS_SHARING_VIOLATION (67)
-#define NT_STATUS_QUOTA_EXCEEDED (68)
-#define NT_STATUS_INVALID_PAGE_PROTECTION (69)
-#define NT_STATUS_MUTANT_NOT_OWNED (70)
-#define NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED (71)
-#define NT_STATUS_PORT_ALREADY_SET (72)
-#define NT_STATUS_SECTION_NOT_IMAGE (73)
-#define NT_STATUS_SUSPEND_COUNT_EXCEEDED (74)
-#define NT_STATUS_THREAD_IS_TERMINATING (75)
-#define NT_STATUS_BAD_WORKING_SET_LIMIT (76)
-#define NT_STATUS_INCOMPATIBLE_FILE_MAP (77)
-#define NT_STATUS_SECTION_PROTECTION (78)
-#define NT_STATUS_EAS_NOT_SUPPORTED (79)
-#define NT_STATUS_EA_TOO_LARGE (80)
-#define NT_STATUS_NONEXISTENT_EA_ENTRY (81)
-#define NT_STATUS_NO_EAS_ON_FILE (82)
-#define NT_STATUS_EA_CORRUPT_ERROR (83)
-#define NT_STATUS_FILE_LOCK_CONFLICT (84)
-#define NT_STATUS_LOCK_NOT_GRANTED (85)
-#define NT_STATUS_DELETE_PENDING (86)
-#define NT_STATUS_CTL_FILE_NOT_SUPPORTED (87)
-#define NT_STATUS_UNKNOWN_REVISION (88)
-#define NT_STATUS_REVISION_MISMATCH (89)
-#define NT_STATUS_INVALID_OWNER (90)
-#define NT_STATUS_INVALID_PRIMARY_GROUP (91)
-#define NT_STATUS_NO_IMPERSONATION_TOKEN (92)
-#define NT_STATUS_CANT_DISABLE_MANDATORY (93)
-#define NT_STATUS_NO_LOGON_SERVERS (94)
-#define NT_STATUS_NO_SUCH_LOGON_SESSION (95)
-#define NT_STATUS_NO_SUCH_PRIVILEGE (96)
-#define NT_STATUS_PRIVILEGE_NOT_HELD (97)
-#define NT_STATUS_INVALID_ACCOUNT_NAME (98)
-#define NT_STATUS_USER_EXISTS (99)
-#define NT_STATUS_NO_SUCH_USER (100)
-#define NT_STATUS_GROUP_EXISTS (101)
-#define NT_STATUS_NO_SUCH_GROUP (102)
-#define NT_STATUS_MEMBER_IN_GROUP (103)
-#define NT_STATUS_MEMBER_NOT_IN_GROUP (104)
-#define NT_STATUS_LAST_ADMIN (105)
-#define NT_STATUS_WRONG_PASSWORD (106)
-#define NT_STATUS_ILL_FORMED_PASSWORD (107)
-#define NT_STATUS_PASSWORD_RESTRICTION (108)
-#define NT_STATUS_LOGON_FAILURE (109)
-#define NT_STATUS_ACCOUNT_RESTRICTION (110)
-#define NT_STATUS_INVALID_LOGON_HOURS (111)
-#define NT_STATUS_INVALID_WORKSTATION (112)
-#define NT_STATUS_PASSWORD_EXPIRED (113)
-#define NT_STATUS_ACCOUNT_DISABLED (114)
-#define NT_STATUS_NONE_MAPPED (115)
-#define NT_STATUS_TOO_MANY_LUIDS_REQUESTED (116)
-#define NT_STATUS_LUIDS_EXHAUSTED (117)
-#define NT_STATUS_INVALID_SUB_AUTHORITY (118)
-#define NT_STATUS_INVALID_ACL (119)
-#define NT_STATUS_INVALID_SID (120)
-#define NT_STATUS_INVALID_SECURITY_DESCR (121)
-#define NT_STATUS_PROCEDURE_NOT_FOUND (122)
-#define NT_STATUS_INVALID_IMAGE_FORMAT (123)
-#define NT_STATUS_NO_TOKEN (124)
-#define NT_STATUS_BAD_INHERITANCE_ACL (125)
-#define NT_STATUS_RANGE_NOT_LOCKED (126)
-#define NT_STATUS_DISK_FULL (127)
-#define NT_STATUS_SERVER_DISABLED (128)
-#define NT_STATUS_SERVER_NOT_DISABLED (129)
-#define NT_STATUS_TOO_MANY_GUIDS_REQUESTED (130)
-#define NT_STATUS_GUIDS_EXHAUSTED (131)
-#define NT_STATUS_INVALID_ID_AUTHORITY (132)
-#define NT_STATUS_AGENTS_EXHAUSTED (133)
-#define NT_STATUS_INVALID_VOLUME_LABEL (134)
-#define NT_STATUS_SECTION_NOT_EXTENDED (135)
-#define NT_STATUS_NOT_MAPPED_DATA (136)
-#define NT_STATUS_RESOURCE_DATA_NOT_FOUND (137)
-#define NT_STATUS_RESOURCE_TYPE_NOT_FOUND (138)
-#define NT_STATUS_RESOURCE_NAME_NOT_FOUND (139)
-#define NT_STATUS_ARRAY_BOUNDS_EXCEEDED (140)
-#define NT_STATUS_FLOAT_DENORMAL_OPERAND (141)
-#define NT_STATUS_FLOAT_DIVIDE_BY_ZERO (142)
-#define NT_STATUS_FLOAT_INEXACT_RESULT (143)
-#define NT_STATUS_FLOAT_INVALID_OPERATION (144)
-#define NT_STATUS_FLOAT_OVERFLOW (145)
-#define NT_STATUS_FLOAT_STACK_CHECK (146)
-#define NT_STATUS_FLOAT_UNDERFLOW (147)
-#define NT_STATUS_INTEGER_DIVIDE_BY_ZERO (148)
-#define NT_STATUS_INTEGER_OVERFLOW (149)
-#define NT_STATUS_PRIVILEGED_INSTRUCTION (150)
-#define NT_STATUS_TOO_MANY_PAGING_FILES (151)
-#define NT_STATUS_FILE_INVALID (152)
-#define NT_STATUS_ALLOTTED_SPACE_EXCEEDED (153)
-#define NT_STATUS_INSUFFICIENT_RESOURCES (154)
-#define NT_STATUS_DFS_EXIT_PATH_FOUND (155)
-#define NT_STATUS_DEVICE_DATA_ERROR (156)
-#define NT_STATUS_DEVICE_NOT_CONNECTED (157)
-#define NT_STATUS_DEVICE_POWER_FAILURE (158)
-#define NT_STATUS_FREE_VM_NOT_AT_BASE (159)
-#define NT_STATUS_MEMORY_NOT_ALLOCATED (160)
-#define NT_STATUS_WORKING_SET_QUOTA (161)
-#define NT_STATUS_MEDIA_WRITE_PROTECTED (162)
-#define NT_STATUS_DEVICE_NOT_READY (163)
-#define NT_STATUS_INVALID_GROUP_ATTRIBUTES (164)
-#define NT_STATUS_BAD_IMPERSONATION_LEVEL (165)
-#define NT_STATUS_CANT_OPEN_ANONYMOUS (166)
-#define NT_STATUS_BAD_VALIDATION_CLASS (167)
-#define NT_STATUS_BAD_TOKEN_TYPE (168)
-#define NT_STATUS_BAD_MASTER_BOOT_RECORD (169)
-#define NT_STATUS_INSTRUCTION_MISALIGNMENT (170)
-#define NT_STATUS_INSTANCE_NOT_AVAILABLE (171)
-#define NT_STATUS_PIPE_NOT_AVAILABLE (172)
-#define NT_STATUS_INVALID_PIPE_STATE (173)
-#define NT_STATUS_PIPE_BUSY (174)
-#define NT_STATUS_ILLEGAL_FUNCTION (175)
-#define NT_STATUS_PIPE_DISCONNECTED (176)
-#define NT_STATUS_PIPE_CLOSING (177)
-#define NT_STATUS_PIPE_CONNECTED (178)
-#define NT_STATUS_PIPE_LISTENING (179)
-#define NT_STATUS_INVALID_READ_MODE (180)
-#define NT_STATUS_IO_TIMEOUT (181)
-#define NT_STATUS_FILE_FORCED_CLOSED (182)
-#define NT_STATUS_PROFILING_NOT_STARTED (183)
-#define NT_STATUS_PROFILING_NOT_STOPPED (184)
-#define NT_STATUS_COULD_NOT_INTERPRET (185)
-#define NT_STATUS_FILE_IS_A_DIRECTORY (186)
-#define NT_STATUS_NOT_SUPPORTED (187)
-#define NT_STATUS_REMOTE_NOT_LISTENING (188)
-#define NT_STATUS_DUPLICATE_NAME (189)
-#define NT_STATUS_BAD_NETWORK_PATH (190)
-#define NT_STATUS_NETWORK_BUSY (191)
-#define NT_STATUS_DEVICE_DOES_NOT_EXIST (192)
-#define NT_STATUS_TOO_MANY_COMMANDS (193)
-#define NT_STATUS_ADAPTER_HARDWARE_ERROR (194)
-#define NT_STATUS_INVALID_NETWORK_RESPONSE (195)
-#define NT_STATUS_UNEXPECTED_NETWORK_ERROR (196)
-#define NT_STATUS_BAD_REMOTE_ADAPTER (197)
-#define NT_STATUS_PRINT_QUEUE_FULL (198)
-#define NT_STATUS_NO_SPOOL_SPACE (199)
-#define NT_STATUS_PRINT_CANCELLED (200)
-#define NT_STATUS_NETWORK_NAME_DELETED (201)
-#define NT_STATUS_NETWORK_ACCESS_DENIED (202)
-#define NT_STATUS_BAD_DEVICE_TYPE (203)
-#define NT_STATUS_BAD_NETWORK_NAME (204)
-#define NT_STATUS_TOO_MANY_NAMES (205)
-#define NT_STATUS_TOO_MANY_SESSIONS (206)
-#define NT_STATUS_SHARING_PAUSED (207)
-#define NT_STATUS_REQUEST_NOT_ACCEPTED (208)
-#define NT_STATUS_REDIRECTOR_PAUSED (209)
-#define NT_STATUS_NET_WRITE_FAULT (210)
-#define NT_STATUS_PROFILING_AT_LIMIT (211)
-#define NT_STATUS_NOT_SAME_DEVICE (212)
-#define NT_STATUS_FILE_RENAMED (213)
-#define NT_STATUS_VIRTUAL_CIRCUIT_CLOSED (214)
-#define NT_STATUS_NO_SECURITY_ON_OBJECT (215)
-#define NT_STATUS_CANT_WAIT (216)
-#define NT_STATUS_PIPE_EMPTY (217)
-#define NT_STATUS_CANT_ACCESS_DOMAIN_INFO (218)
-#define NT_STATUS_CANT_TERMINATE_SELF (219)
-#define NT_STATUS_INVALID_SERVER_STATE (220)
-#define NT_STATUS_INVALID_DOMAIN_STATE (221)
-#define NT_STATUS_INVALID_DOMAIN_ROLE (222)
-#define NT_STATUS_NO_SUCH_DOMAIN (223)
-#define NT_STATUS_DOMAIN_EXISTS (224)
-#define NT_STATUS_DOMAIN_LIMIT_EXCEEDED (225)
-#define NT_STATUS_OPLOCK_NOT_GRANTED (226)
-#define NT_STATUS_INVALID_OPLOCK_PROTOCOL (227)
-#define NT_STATUS_INTERNAL_DB_CORRUPTION (228)
-#define NT_STATUS_INTERNAL_ERROR (229)
-#define NT_STATUS_GENERIC_NOT_MAPPED (230)
-#define NT_STATUS_BAD_DESCRIPTOR_FORMAT (231)
-#define NT_STATUS_INVALID_USER_BUFFER (232)
-#define NT_STATUS_UNEXPECTED_IO_ERROR (233)
-#define NT_STATUS_UNEXPECTED_MM_CREATE_ERR (234)
-#define NT_STATUS_UNEXPECTED_MM_MAP_ERROR (235)
-#define NT_STATUS_UNEXPECTED_MM_EXTEND_ERR (236)
-#define NT_STATUS_NOT_LOGON_PROCESS (237)
-#define NT_STATUS_LOGON_SESSION_EXISTS (238)
-#define NT_STATUS_INVALID_PARAMETER_1 (239)
-#define NT_STATUS_INVALID_PARAMETER_2 (240)
-#define NT_STATUS_INVALID_PARAMETER_3 (241)
-#define NT_STATUS_INVALID_PARAMETER_4 (242)
-#define NT_STATUS_INVALID_PARAMETER_5 (243)
-#define NT_STATUS_INVALID_PARAMETER_6 (244)
-#define NT_STATUS_INVALID_PARAMETER_7 (245)
-#define NT_STATUS_INVALID_PARAMETER_8 (246)
-#define NT_STATUS_INVALID_PARAMETER_9 (247)
-#define NT_STATUS_INVALID_PARAMETER_10 (248)
-#define NT_STATUS_INVALID_PARAMETER_11 (249)
-#define NT_STATUS_INVALID_PARAMETER_12 (250)
-#define NT_STATUS_REDIRECTOR_NOT_STARTED (251)
-#define NT_STATUS_REDIRECTOR_STARTED (252)
-#define NT_STATUS_STACK_OVERFLOW (253)
-#define NT_STATUS_NO_SUCH_PACKAGE (254)
-#define NT_STATUS_BAD_FUNCTION_TABLE (255)
-#define NT_STATUS_DIRECTORY_NOT_EMPTY (257)
-#define NT_STATUS_FILE_CORRUPT_ERROR (258)
-#define NT_STATUS_NOT_A_DIRECTORY (259)
-#define NT_STATUS_BAD_LOGON_SESSION_STATE (260)
-#define NT_STATUS_LOGON_SESSION_COLLISION (261)
-#define NT_STATUS_NAME_TOO_LONG (262)
-#define NT_STATUS_FILES_OPEN (263)
-#define NT_STATUS_CONNECTION_IN_USE (264)
-#define NT_STATUS_MESSAGE_NOT_FOUND (265)
-#define NT_STATUS_PROCESS_IS_TERMINATING (266)
-#define NT_STATUS_INVALID_LOGON_TYPE (267)
-#define NT_STATUS_NO_GUID_TRANSLATION (268)
-#define NT_STATUS_CANNOT_IMPERSONATE (269)
-#define NT_STATUS_IMAGE_ALREADY_LOADED (270)
-#define NT_STATUS_ABIOS_NOT_PRESENT (271)
-#define NT_STATUS_ABIOS_LID_NOT_EXIST (272)
-#define NT_STATUS_ABIOS_LID_ALREADY_OWNED (273)
-#define NT_STATUS_ABIOS_NOT_LID_OWNER (274)
-#define NT_STATUS_ABIOS_INVALID_COMMAND (275)
-#define NT_STATUS_ABIOS_INVALID_LID (276)
-#define NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE (277)
-#define NT_STATUS_ABIOS_INVALID_SELECTOR (278)
-#define NT_STATUS_NO_LDT (279)
-#define NT_STATUS_INVALID_LDT_SIZE (280)
-#define NT_STATUS_INVALID_LDT_OFFSET (281)
-#define NT_STATUS_INVALID_LDT_DESCRIPTOR (282)
-#define NT_STATUS_INVALID_IMAGE_NE_FORMAT (283)
-#define NT_STATUS_RXACT_INVALID_STATE (284)
-#define NT_STATUS_RXACT_COMMIT_FAILURE (285)
-#define NT_STATUS_MAPPED_FILE_SIZE_ZERO (286)
-#define NT_STATUS_TOO_MANY_OPENED_FILES (287)
-#define NT_STATUS_CANCELLED (288)
-#define NT_STATUS_CANNOT_DELETE (289)
-#define NT_STATUS_INVALID_COMPUTER_NAME (290)
-#define NT_STATUS_FILE_DELETED (291)
-#define NT_STATUS_SPECIAL_ACCOUNT (292)
-#define NT_STATUS_SPECIAL_GROUP (293)
-#define NT_STATUS_SPECIAL_USER (294)
-#define NT_STATUS_MEMBERS_PRIMARY_GROUP (295)
-#define NT_STATUS_FILE_CLOSED (296)
-#define NT_STATUS_TOO_MANY_THREADS (297)
-#define NT_STATUS_THREAD_NOT_IN_PROCESS (298)
-#define NT_STATUS_TOKEN_ALREADY_IN_USE (299)
-#define NT_STATUS_PAGEFILE_QUOTA_EXCEEDED (300)
-#define NT_STATUS_COMMITMENT_LIMIT (301)
-#define NT_STATUS_INVALID_IMAGE_LE_FORMAT (302)
-#define NT_STATUS_INVALID_IMAGE_NOT_MZ (303)
-#define NT_STATUS_INVALID_IMAGE_PROTECT (304)
-#define NT_STATUS_INVALID_IMAGE_WIN_16 (305)
-#define NT_STATUS_LOGON_SERVER_CONFLICT (306)
-#define NT_STATUS_TIME_DIFFERENCE_AT_DC (307)
-#define NT_STATUS_SYNCHRONIZATION_REQUIRED (308)
-#define NT_STATUS_DLL_NOT_FOUND (309)
-#define NT_STATUS_OPEN_FAILED (310)
-#define NT_STATUS_IO_PRIVILEGE_FAILED (311)
-#define NT_STATUS_ORDINAL_NOT_FOUND (312)
-#define NT_STATUS_ENTRYPOINT_NOT_FOUND (313)
-#define NT_STATUS_CONTROL_C_EXIT (314)
-#define NT_STATUS_LOCAL_DISCONNECT (315)
-#define NT_STATUS_REMOTE_DISCONNECT (316)
-#define NT_STATUS_REMOTE_RESOURCES (317)
-#define NT_STATUS_LINK_FAILED (318)
-#define NT_STATUS_LINK_TIMEOUT (319)
-#define NT_STATUS_INVALID_CONNECTION (320)
-#define NT_STATUS_INVALID_ADDRESS (321)
-#define NT_STATUS_DLL_INIT_FAILED (322)
-#define NT_STATUS_MISSING_SYSTEMFILE (323)
-#define NT_STATUS_UNHANDLED_EXCEPTION (324)
-#define NT_STATUS_APP_INIT_FAILURE (325)
-#define NT_STATUS_PAGEFILE_CREATE_FAILED (326)
-#define NT_STATUS_NO_PAGEFILE (327)
-#define NT_STATUS_INVALID_LEVEL (328)
-#define NT_STATUS_WRONG_PASSWORD_CORE (329)
-#define NT_STATUS_ILLEGAL_FLOAT_CONTEXT (330)
-#define NT_STATUS_PIPE_BROKEN (331)
-#define NT_STATUS_REGISTRY_CORRUPT (332)
-#define NT_STATUS_REGISTRY_IO_FAILED (333)
-#define NT_STATUS_NO_EVENT_PAIR (334)
-#define NT_STATUS_UNRECOGNIZED_VOLUME (335)
-#define NT_STATUS_SERIAL_NO_DEVICE_INITED (336)
-#define NT_STATUS_NO_SUCH_ALIAS (337)
-#define NT_STATUS_MEMBER_NOT_IN_ALIAS (338)
-#define NT_STATUS_MEMBER_IN_ALIAS (339)
-#define NT_STATUS_ALIAS_EXISTS (340)
-#define NT_STATUS_LOGON_NOT_GRANTED (341)
-#define NT_STATUS_TOO_MANY_SECRETS (342)
-#define NT_STATUS_SECRET_TOO_LONG (343)
-#define NT_STATUS_INTERNAL_DB_ERROR (344)
-#define NT_STATUS_FULLSCREEN_MODE (345)
-#define NT_STATUS_TOO_MANY_CONTEXT_IDS (346)
-#define NT_STATUS_LOGON_TYPE_NOT_GRANTED (347)
-#define NT_STATUS_NOT_REGISTRY_FILE (348)
-#define NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED (349)
-#define NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR (350)
-#define NT_STATUS_FT_MISSING_MEMBER (351)
-#define NT_STATUS_ILL_FORMED_SERVICE_ENTRY (352)
-#define NT_STATUS_ILLEGAL_CHARACTER (353)
-#define NT_STATUS_UNMAPPABLE_CHARACTER (354)
-#define NT_STATUS_UNDEFINED_CHARACTER (355)
-#define NT_STATUS_FLOPPY_VOLUME (356)
-#define NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND (357)
-#define NT_STATUS_FLOPPY_WRONG_CYLINDER (358)
-#define NT_STATUS_FLOPPY_UNKNOWN_ERROR (359)
-#define NT_STATUS_FLOPPY_BAD_REGISTERS (360)
-#define NT_STATUS_DISK_RECALIBRATE_FAILED (361)
-#define NT_STATUS_DISK_OPERATION_FAILED (362)
-#define NT_STATUS_DISK_RESET_FAILED (363)
-#define NT_STATUS_SHARED_IRQ_BUSY (364)
-#define NT_STATUS_FT_ORPHANING (365)
-#define NT_STATUS_PARTITION_FAILURE (370)
-#define NT_STATUS_INVALID_BLOCK_LENGTH (371)
-#define NT_STATUS_DEVICE_NOT_PARTITIONED (372)
-#define NT_STATUS_UNABLE_TO_LOCK_MEDIA (373)
-#define NT_STATUS_UNABLE_TO_UNLOAD_MEDIA (374)
-#define NT_STATUS_EOM_OVERFLOW (375)
-#define NT_STATUS_NO_MEDIA (376)
-#define NT_STATUS_NO_SUCH_MEMBER (378)
-#define NT_STATUS_INVALID_MEMBER (379)
-#define NT_STATUS_KEY_DELETED (380)
-#define NT_STATUS_NO_LOG_SPACE (381)
-#define NT_STATUS_TOO_MANY_SIDS (382)
-#define NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED (383)
-#define NT_STATUS_KEY_HAS_CHILDREN (384)
-#define NT_STATUS_CHILD_MUST_BE_VOLATILE (385)
-#define NT_STATUS_DEVICE_CONFIGURATION_ERROR (386)
-#define NT_STATUS_DRIVER_INTERNAL_ERROR (387)
-#define NT_STATUS_INVALID_DEVICE_STATE (388)
-#define NT_STATUS_IO_DEVICE_ERROR (389)
-#define NT_STATUS_DEVICE_PROTOCOL_ERROR (390)
-#define NT_STATUS_BACKUP_CONTROLLER (391)
-#define NT_STATUS_LOG_FILE_FULL (392)
-#define NT_STATUS_TOO_LATE (393)
-#define NT_STATUS_NO_TRUST_LSA_SECRET (394)
-#define NT_STATUS_NO_TRUST_SAM_ACCOUNT (395)
-#define NT_STATUS_TRUSTED_DOMAIN_FAILURE (396)
-#define NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE (397)
-#define NT_STATUS_EVENTLOG_FILE_CORRUPT (398)
-#define NT_STATUS_EVENTLOG_CANT_START (399)
-#define NT_STATUS_TRUST_FAILURE (400)
-#define NT_STATUS_MUTANT_LIMIT_EXCEEDED (401)
-#define NT_STATUS_NETLOGON_NOT_STARTED (402)
-#define NT_STATUS_ACCOUNT_EXPIRED (403)
-#define NT_STATUS_POSSIBLE_DEADLOCK (404)
-#define NT_STATUS_NETWORK_CREDENTIAL_CONFLICT (405)
-#define NT_STATUS_REMOTE_SESSION_LIMIT (406)
-#define NT_STATUS_EVENTLOG_FILE_CHANGED (407)
-#define NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT (408)
-#define NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT (409)
-#define NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT (410)
-#define NT_STATUS_DOMAIN_TRUST_INCONSISTENT (411)
-#define NT_STATUS_FS_DRIVER_REQUIRED (412)
-#define NT_STATUS_NO_USER_SESSION_KEY (514)
-#define NT_STATUS_USER_SESSION_DELETED (515)
-#define NT_STATUS_RESOURCE_LANG_NOT_FOUND (516)
-#define NT_STATUS_INSUFF_SERVER_RESOURCES (517)
-#define NT_STATUS_INVALID_BUFFER_SIZE (518)
-#define NT_STATUS_INVALID_ADDRESS_COMPONENT (519)
-#define NT_STATUS_INVALID_ADDRESS_WILDCARD (520)
-#define NT_STATUS_TOO_MANY_ADDRESSES (521)
-#define NT_STATUS_ADDRESS_ALREADY_EXISTS (522)
-#define NT_STATUS_ADDRESS_CLOSED (523)
-#define NT_STATUS_CONNECTION_DISCONNECTED (524)
-#define NT_STATUS_CONNECTION_RESET (525)
-#define NT_STATUS_TOO_MANY_NODES (526)
-#define NT_STATUS_TRANSACTION_ABORTED (527)
-#define NT_STATUS_TRANSACTION_TIMED_OUT (528)
-#define NT_STATUS_TRANSACTION_NO_RELEASE (529)
-#define NT_STATUS_TRANSACTION_NO_MATCH (530)
-#define NT_STATUS_TRANSACTION_RESPONDED (531)
-#define NT_STATUS_TRANSACTION_INVALID_ID (532)
-#define NT_STATUS_TRANSACTION_INVALID_TYPE (533)
-#define NT_STATUS_NOT_SERVER_SESSION (534)
-#define NT_STATUS_NOT_CLIENT_SESSION (535)
-#define NT_STATUS_CANNOT_LOAD_REGISTRY_FILE (536)
-#define NT_STATUS_DEBUG_ATTACH_FAILED (537)
-#define NT_STATUS_SYSTEM_PROCESS_TERMINATED (538)
-#define NT_STATUS_DATA_NOT_ACCEPTED (539)
-#define NT_STATUS_NO_BROWSER_SERVERS_FOUND (540)
-#define NT_STATUS_VDM_HARD_ERROR (541)
-#define NT_STATUS_DRIVER_CANCEL_TIMEOUT (542)
-#define NT_STATUS_REPLY_MESSAGE_MISMATCH (543)
-#define NT_STATUS_MAPPED_ALIGNMENT (544)
-#define NT_STATUS_IMAGE_CHECKSUM_MISMATCH (545)
-#define NT_STATUS_LOST_WRITEBEHIND_DATA (546)
-#define NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID (547)
-#define NT_STATUS_PASSWORD_MUST_CHANGE (548)
-#define NT_STATUS_NOT_FOUND (549)
-#define NT_STATUS_NOT_TINY_STREAM (550)
-#define NT_STATUS_RECOVERY_FAILURE (551)
-#define NT_STATUS_STACK_OVERFLOW_READ (552)
-#define NT_STATUS_FAIL_CHECK (553)
-#define NT_STATUS_DUPLICATE_OBJECTID (554)
-#define NT_STATUS_OBJECTID_EXISTS (555)
-#define NT_STATUS_CONVERT_TO_LARGE (556)
-#define NT_STATUS_RETRY (557)
-#define NT_STATUS_FOUND_OUT_OF_SCOPE (558)
-#define NT_STATUS_ALLOCATE_BUCKET (559)
-#define NT_STATUS_PROPSET_NOT_FOUND (560)
-#define NT_STATUS_MARSHALL_OVERFLOW (561)
-#define NT_STATUS_INVALID_VARIANT (562)
-#define NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND (563)
-#define NT_STATUS_ACCOUNT_LOCKED_OUT (564)
-#define NT_STATUS_HANDLE_NOT_CLOSABLE (565)
-#define NT_STATUS_CONNECTION_REFUSED (566)
-#define NT_STATUS_GRACEFUL_DISCONNECT (567)
-#define NT_STATUS_ADDRESS_ALREADY_ASSOCIATED (568)
-#define NT_STATUS_ADDRESS_NOT_ASSOCIATED (569)
-#define NT_STATUS_CONNECTION_INVALID (570)
-#define NT_STATUS_CONNECTION_ACTIVE (571)
-#define NT_STATUS_NETWORK_UNREACHABLE (572)
-#define NT_STATUS_HOST_UNREACHABLE (573)
-#define NT_STATUS_PROTOCOL_UNREACHABLE (574)
-#define NT_STATUS_PORT_UNREACHABLE (575)
-#define NT_STATUS_REQUEST_ABORTED (576)
-#define NT_STATUS_CONNECTION_ABORTED (577)
-#define NT_STATUS_BAD_COMPRESSION_BUFFER (578)
-#define NT_STATUS_USER_MAPPED_FILE (579)
-#define NT_STATUS_AUDIT_FAILED (580)
-#define NT_STATUS_TIMER_RESOLUTION_NOT_SET (581)
-#define NT_STATUS_CONNECTION_COUNT_LIMIT (582)
-#define NT_STATUS_LOGIN_TIME_RESTRICTION (583)
-#define NT_STATUS_LOGIN_WKSTA_RESTRICTION (584)
-#define NT_STATUS_IMAGE_MP_UP_MISMATCH (585)
-#define NT_STATUS_INSUFFICIENT_LOGON_INFO (592)
-#define NT_STATUS_BAD_DLL_ENTRYPOINT (593)
-#define NT_STATUS_BAD_SERVICE_ENTRYPOINT (594)
-#define NT_STATUS_LPC_REPLY_LOST (595)
-#define NT_STATUS_IP_ADDRESS_CONFLICT1 (596)
-#define NT_STATUS_IP_ADDRESS_CONFLICT2 (597)
-#define NT_STATUS_REGISTRY_QUOTA_LIMIT (598)
-#define NT_STATUS_PATH_NOT_COVERED (599)
-#define NT_STATUS_NO_CALLBACK_ACTIVE (600)
-#define NT_STATUS_LICENSE_QUOTA_EXCEEDED (601)
-#define NT_STATUS_PWD_TOO_SHORT (602)
-#define NT_STATUS_PWD_TOO_RECENT (603)
-#define NT_STATUS_PWD_HISTORY_CONFLICT (604)
-#define NT_STATUS_PLUGPLAY_NO_DEVICE (606)
-#define NT_STATUS_UNSUPPORTED_COMPRESSION (607)
-#define NT_STATUS_INVALID_HW_PROFILE (608)
-#define NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH (609)
-#define NT_STATUS_DRIVER_ORDINAL_NOT_FOUND (610)
-#define NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND (611)
-#define NT_STATUS_RESOURCE_NOT_OWNED (612)
-#define NT_STATUS_TOO_MANY_LINKS (613)
-#define NT_STATUS_QUOTA_LIST_INCONSISTENT (614)
-#define NT_STATUS_FILE_IS_OFFLINE (615)
diff --git a/source/include/proto.h b/source/include/proto.h
deleted file mode 100644
index 009d83db5c2..00000000000
--- a/source/include/proto.h
+++ /dev/null
@@ -1,1057 +0,0 @@
-/* This file is automatically generated with "make proto". DO NOT EDIT */
-
-
-/*The following definitions come from access.c */
-
-BOOL check_access(int snum);
-BOOL allow_access(char *deny_list,char *allow_list,char *cname,char *caddr);
-
-/*The following definitions come from charcnv.c */
-
-char *unix2dos_format(char *str,BOOL overwrite);
-char *dos2unix_format(char *str, BOOL overwrite);
-int interpret_character_set(char *str, int def);
-
-/*The following definitions come from charset.c */
-
-void charset_initialise();
-void codepage_initialise(int client_codepage);
-void add_char_string(char *s);
-
-/*The following definitions come from chgpasswd.c */
-
-BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequence);
-BOOL chgpasswd(char *name,char *oldpass,char *newpass);
-BOOL chgpasswd(char *name,char *oldpass,char *newpass);
-
-/*The following definitions come from client.c */
-
-void setup_pkt(char *outbuf);
-void do_dir(char *inbuf,char *outbuf,char *Mask,int attribute,void (*fn)(),BOOL recurse_dir);
-void cmd_help(void);
-BOOL reopen_connection(char *inbuf,char *outbuf);
-char *smb_errstr(char *inbuf);
-
-/*The following definitions come from clientutil.c */
-
-void cli_setup_pkt(char *outbuf);
-BOOL cli_receive_trans_response(char *inbuf,int trans,int *data_len,
- int *param_len, char **data,char **param);
-BOOL cli_send_session_request(char *inbuf, char *outbuf);
-BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setup);
-void cli_send_logout(void);
-BOOL cli_call_api(int prcnt,int drcnt,int mprcnt,int mdrcnt,int *rprcnt,
- int *rdrcnt, char *param,char *data, char **rparam,char **rdata);
-BOOL cli_send_trans_request(char *outbuf, int trans, char *name, int fid, int flags,
- char *data,char *param,uint16 *setup, int ldata,int lparam,
- int lsetup,int mdata,int mparam,int msetup);
-BOOL cli_open_sockets(int port);
-BOOL cli_reopen_connection(char *inbuf,char *outbuf);
-char *smb_errstr(char *inbuf);
-
-/*The following definitions come from clitar.c */
-
-int padit(char *buf, int bufsize, int padsize);
-void cmd_block(void);
-void cmd_tarmode(void);
-void cmd_setmode(void);
-void cmd_tar(char *inbuf, char *outbuf);
-int process_tar(char *inbuf, char *outbuf);
-int clipfind(char **aret, int ret, char *tok);
-int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind);
-
-/*The following definitions come from dir.c */
-
-void init_dptrs(void);
-char *dptr_path(int key);
-char *dptr_wcard(int key);
-BOOL dptr_set_wcard(int key, char *wcard);
-BOOL dptr_set_attr(int key, uint16 attr);
-uint16 dptr_attr(int key);
-void dptr_close(int key);
-void dptr_closecnum(int cnum);
-void dptr_idlecnum(int cnum);
-void dptr_closepath(char *path,int pid);
-int dptr_create(int cnum,char *path, BOOL expect_close,int pid);
-BOOL dptr_fill(char *buf1,unsigned int key);
-BOOL dptr_zero(char *buf);
-void *dptr_fetch(char *buf,int *num);
-void *dptr_fetch_lanman2(char *params,int dptr_num);
-BOOL dir_check_ftype(int cnum,int mode,struct stat *st,int dirtype);
-BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mode,time_t *date,BOOL check_descend);
-void *OpenDir(int cnum, char *name, BOOL use_veto);
-void CloseDir(void *p);
-char *ReadDirName(void *p);
-BOOL SeekDir(void *p,int pos);
-int TellDir(void *p);
-void DirCacheAdd(char *path,char *name,char *dname,int snum);
-char *DirCacheCheck(char *path,char *name,int snum);
-void DirCacheFlush(int snum);
-
-/*The following definitions come from fault.c */
-
-void fault_setup(void (*fn)());
-
-/*The following definitions come from getsmbpass.c */
-
-char *getsmbpass(char *prompt) ;
-
-/*The following definitions come from interface.c */
-
-void load_interfaces(void);
-void iface_set_default(char *ip,char *bcast,char *nmask);
-BOOL ismyip(struct in_addr ip);
-BOOL ismybcast(struct in_addr bcast);
-int iface_count(void);
-struct in_addr *iface_n_ip(int n);
-struct in_addr *iface_bcast(struct in_addr ip);
-struct in_addr *iface_nmask(struct in_addr ip);
-struct in_addr *iface_ip(struct in_addr ip);
-
-/*The following definitions come from ipc.c */
-
-int reply_trans(char *inbuf,char *outbuf);
-
-/*The following definitions come from kanji.c */
-
-char *sj_strtok(char *s1, char *s2);
-char *sj_strstr(char *s1, char *s2);
-char *sj_strchr (char *s, int c);
-char *sj_strrchr(char *s, int c);
-int interpret_coding_system(char *str, int def);
-
-/*The following definitions come from loadparm.c */
-
-char *lp_string(char *s);
-char *lp_logfile(void);
-char *lp_smbrun(void);
-char *lp_configfile(void);
-char *lp_smb_passwd_file(void);
-char *lp_serverstring(void);
-char *lp_printcapname(void);
-char *lp_lockdir(void);
-char *lp_rootdir(void);
-char *lp_defaultservice(void);
-char *lp_msg_command(void);
-char *lp_dfree_command(void);
-char *lp_hosts_equiv(void);
-char *lp_auto_services(void);
-char *lp_passwd_program(void);
-char *lp_passwd_chat(void);
-char *lp_passwordserver(void);
-char *lp_workgroup(void);
-char *lp_domain_controller(void);
-char *lp_username_map(void);
-char *lp_character_set(void);
-char *lp_logon_script(void);
-char *lp_logon_path(void);
-char *lp_remote_announce(void);
-char *lp_wins_server(void);
-char *lp_interfaces(void);
-char *lp_socket_address(void);
-char *lp_nis_home_map_name(void);
-char *lp_announce_version(void);
-char *lp_netbios_aliases(void);
-char *lp_domainsid(void);
-BOOL lp_dns_proxy(void);
-BOOL lp_wins_support(void);
-BOOL lp_wins_proxy(void);
-BOOL lp_local_master(void);
-BOOL lp_domain_master(void);
-BOOL lp_domain_logons(void);
-BOOL lp_preferred_master(void);
-BOOL lp_load_printers(void);
-BOOL lp_use_rhosts(void);
-BOOL lp_getwdcache(void);
-BOOL lp_readprediction(void);
-BOOL lp_readbmpx(void);
-BOOL lp_readraw(void);
-BOOL lp_writeraw(void);
-BOOL lp_null_passwords(void);
-BOOL lp_strip_dot(void);
-BOOL lp_encrypted_passwords(void);
-BOOL lp_syslog_only(void);
-BOOL lp_browse_list(void);
-BOOL lp_unix_realname(void);
-BOOL lp_nis_home_map(void);
-BOOL lp_time_server(void);
-int lp_os_level(void);
-int lp_max_ttl(void);
-int lp_max_log_size(void);
-int lp_mangledstack(void);
-int lp_maxxmit(void);
-int lp_maxmux(void);
-int lp_maxpacket(void);
-int lp_keepalive(void);
-int lp_passwordlevel(void);
-int lp_usernamelevel(void);
-int lp_readsize(void);
-int lp_shmem_size(void);
-int lp_shmem_hash_size(void);
-int lp_deadtime(void);
-int lp_maxprotocol(void);
-int lp_security(void);
-int lp_printing(void);
-int lp_maxdisksize(void);
-int lp_lpqcachetime(void);
-int lp_syslog(void);
-int lp_client_code_page(void);
-int lp_announce_as(void);
-char *lp_preexec(int );
-char *lp_postexec(int );
-char *lp_rootpreexec(int );
-char *lp_rootpostexec(int );
-char *lp_servicename(int );
-char *lp_pathname(int );
-char *lp_dontdescend(int );
-char *lp_username(int );
-char *lp_guestaccount(int );
-char *lp_invalid_users(int );
-char *lp_valid_users(int );
-char *lp_admin_users(int );
-char *lp_printcommand(int );
-char *lp_lpqcommand(int );
-char *lp_lprmcommand(int );
-char *lp_lppausecommand(int );
-char *lp_lpresumecommand(int );
-char *lp_printername(int );
-char *lp_printerdriver(int );
-char *lp_hostsallow(int );
-char *lp_hostsdeny(int );
-char *lp_magicscript(int );
-char *lp_magicoutput(int );
-char *lp_comment(int );
-char *lp_force_user(int );
-char *lp_force_group(int );
-char *lp_readlist(int );
-char *lp_writelist(int );
-char *lp_volume(int );
-char *lp_mangled_map(int );
-char *lp_veto_files(int );
-char *lp_hide_files(int );
-BOOL lp_alternate_permissions(int );
-BOOL lp_revalidate(int );
-BOOL lp_casesensitive(int );
-BOOL lp_preservecase(int );
-BOOL lp_shortpreservecase(int );
-BOOL lp_casemangle(int );
-BOOL lp_status(int );
-BOOL lp_hide_dot_files(int );
-BOOL lp_browseable(int );
-BOOL lp_readonly(int );
-BOOL lp_no_set_dir(int );
-BOOL lp_guest_ok(int );
-BOOL lp_guest_only(int );
-BOOL lp_print_ok(int );
-BOOL lp_postscript(int );
-BOOL lp_map_hidden(int );
-BOOL lp_map_archive(int );
-BOOL lp_locking(int );
-BOOL lp_strict_locking(int );
-BOOL lp_share_modes(int );
-BOOL lp_oplocks(int );
-BOOL lp_onlyuser(int );
-BOOL lp_manglednames(int );
-BOOL lp_widelinks(int );
-BOOL lp_symlinks(int );
-BOOL lp_syncalways(int );
-BOOL lp_map_system(int );
-BOOL lp_delete_readonly(int );
-BOOL lp_fake_oplocks(int );
-BOOL lp_recursive_veto_delete(int );
-int lp_create_mode(int );
-int lp_force_create_mode(int );
-int lp_dir_mode(int );
-int lp_force_dir_mode(int );
-int lp_max_connections(int );
-int lp_defaultcase(int );
-int lp_minprintspace(int );
-char lp_magicchar(int );
-BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir);
-int lp_add_service(char *pszService, int iDefaultService);
-BOOL lp_add_printer(char *pszPrintername, int iDefaultService);
-BOOL lp_file_list_changed(void);
-BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue);
-int lp_next_parameter(int snum, int *i, char *label,
- char *value, int allparameters);
-BOOL lp_snum_ok(int iService);
-BOOL lp_loaded(void);
-void lp_killunused(BOOL (*snumused)(int ));
-BOOL lp_load(char *pszFname,BOOL global_only);
-int lp_numservices(void);
-void lp_dump(FILE *f);
-int lp_servicenumber(char *pszServiceName);
-char *volume_label(int snum);
-void lp_rename_service(int snum, char *new_name);
-void lp_remove_service(int snum);
-void lp_copy_service(int snum, char *new_name);
-int lp_default_server_announce(void);
-int lp_major_announce_version(void);
-int lp_minor_announce_version(void);
-
-/*The following definitions come from locking.c */
-
-BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset);
-BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode);
-BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode);
-BOOL start_share_mode_mgmt(void);
-BOOL stop_share_mode_mgmt(void);
-BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok);
-BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token token);
-int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode,
- min_share_mode_entry **old_shares);
-void del_share_mode(share_lock_token token, int fnum);
-BOOL set_share_mode(share_lock_token token, int fnum, uint16 port, uint16 op_type);
-BOOL remove_share_oplock(int fnum, share_lock_token token);
-BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok);
-BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token token);
-int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode,
- min_share_mode_entry **old_shares);
-void del_share_mode(share_lock_token token, int fnum);
-BOOL set_share_mode(share_lock_token token,int fnum, uint16 port, uint16 op_type);
-BOOL remove_share_oplock(int fnum, share_lock_token token);
-
-/*The following definitions come from lsaparse.c */
-
-char* lsa_io_r_open_pol(BOOL io, LSA_R_OPEN_POL *r_p, char *q, char *base, int align);
-char* lsa_io_q_query(BOOL io, LSA_Q_QUERY_INFO *q_q, char *q, char *base, int align);
-char* lsa_io_r_query(BOOL io, LSA_R_QUERY_INFO *r_q, char *q, char *base, int align);
-char* lsa_io_q_lookup_sids(BOOL io, LSA_Q_LOOKUP_SIDS *q_s, char *q, char *base, int align);
-char* lsa_io_r_lookup_sids(BOOL io, LSA_R_LOOKUP_SIDS *r_s, char *q, char *base, int align);
-char* lsa_io_q_lookup_rids(BOOL io, LSA_Q_LOOKUP_RIDS *q_r, char *q, char *base, int align);
-char* lsa_io_r_lookup_rids(BOOL io, LSA_R_LOOKUP_RIDS *r_r, char *q, char *base, int align);
-char* lsa_io_q_req_chal(BOOL io, LSA_Q_REQ_CHAL *q_c, char *q, char *base, int align);
-char* lsa_io_r_req_chal(BOOL io, LSA_R_REQ_CHAL *r_c, char *q, char *base, int align);
-char* lsa_io_q_auth2(BOOL io, LSA_Q_AUTH_2 *q_a, char *q, char *base, int align);
-char* lsa_io_r_auth_2(BOOL io, LSA_R_AUTH_2 *r_a, char *q, char *base, int align);
-char* lsa_io_q_srv_pwset(BOOL io, LSA_Q_SRV_PWSET *q_s, char *q, char *base, int align);
-char* lsa_io_r_srv_pwset(BOOL io, LSA_R_SRV_PWSET *r_s, char *q, char *base, int align);
-char* lsa_io_user_info(BOOL io, LSA_USER_INFO *usr, char *q, char *base, int align);
-char* lsa_io_q_sam_logon(BOOL io, LSA_Q_SAM_LOGON *q_l, char *q, char *base, int align);
-char* lsa_io_r_sam_logon(BOOL io, LSA_R_SAM_LOGON *r_l, char *q, char *base, int align);
-char* lsa_io_q_sam_logoff(BOOL io, LSA_Q_SAM_LOGOFF *q_l, char *q, char *base, int align);
-char* lsa_io_r_sam_logoff(BOOL io, LSA_R_SAM_LOGOFF *r_l, char *q, char *base, int align);
-
-/*The following definitions come from mangle.c */
-
-int str_checksum(char *s);
-BOOL is_8_3(char *fname, BOOL check_case);
-void create_mangled_stack(int size);
-BOOL check_mangled_stack(char *s);
-BOOL is_mangled(char *s);
-void mangle_name_83(char *s);
-BOOL name_map_mangle(char *OutName,BOOL need83,int snum);
-
-/*The following definitions come from md4.c */
-
-void mdfour(unsigned char *out, unsigned char *in, int n);
-
-/*The following definitions come from message.c */
-
-int reply_sends(char *inbuf,char *outbuf);
-int reply_sendstrt(char *inbuf,char *outbuf);
-int reply_sendtxt(char *inbuf,char *outbuf);
-int reply_sendend(char *inbuf,char *outbuf);
-
-/*The following definitions come from nameannounce.c */
-
-void announce_request(struct work_record *work, struct in_addr ip);
-void do_announce_request(char *info, char *to_name, int announce_type,
- int from,
- int to, struct in_addr dest_ip);
-void sync_server(enum state_type state, char *serv_name, char *work_name,
- int name_type,
- struct subnet_record *d,
- struct in_addr ip);
-void do_announce_host(int command,
- char *from_name, int from_type, struct in_addr from_ip,
- char *to_name , int to_type , struct in_addr to_ip,
- time_t announce_interval,
- char *server_name, int server_type, char *server_comment);
-void announce_my_servers_removed(void);
-void announce_server(struct subnet_record *d, struct work_record *work,
- char *name, char *comment, time_t ttl, int server_type);
-void announce_host(time_t t);
-void reset_announce_timer();
-void announce_master(time_t t);
-void announce_remote(time_t t);
-
-/*The following definitions come from namebrowse.c */
-
-void expire_browse_cache(time_t t);
-struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
- time_t ttl, struct subnet_record *d,
- struct in_addr ip, BOOL local);
-void do_browser_lists(time_t t);
-
-/*The following definitions come from namedbname.c */
-
-void set_samba_nb_type(void);
-BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2);
-BOOL ms_browser_name(char *name, int type);
-void remove_name(struct subnet_record *d, struct name_record *n);
-struct name_record *find_name(struct name_record *n,
- struct nmb_name *name, int search);
-struct name_record *find_name_search(struct subnet_record **d,
- struct nmb_name *name,
- int search, struct in_addr ip);
-void dump_names(void);
-void load_netbios_names(void);
-void remove_netbios_name(struct subnet_record *d,
- char *name,int type, enum name_source source,
- struct in_addr ip);
-struct name_record *add_netbios_entry(struct subnet_record *d,
- char *name, int type, int nb_flags,
- int ttl, enum name_source source, struct in_addr ip,
- BOOL new_only,BOOL wins);
-void expire_names(time_t t);
-struct name_record *dns_name_search(struct nmb_name *question, int Time);
-
-/*The following definitions come from namedbresp.c */
-
-void add_response_record(struct subnet_record *d,
- struct response_record *n);
-void remove_response_record(struct subnet_record *d,
- struct response_record *n);
-struct response_record *make_response_queue_record(enum state_type state,
- int id,uint16 fd,
- int quest_type, char *name,int type, int nb_flags, time_t ttl,
- int server_type, char *my_name, char *my_comment,
- BOOL bcast,BOOL recurse,
- struct in_addr send_ip, struct in_addr reply_to_ip);
-struct response_record *find_response_record(struct subnet_record **d,
- uint16 id);
-
-/*The following definitions come from namedbserver.c */
-
-void remove_old_servers(struct work_record *work, time_t t,
- BOOL remove_all);
-struct server_record *find_server(struct work_record *work, char *name);
-struct server_record *add_server_entry(struct subnet_record *d,
- struct work_record *work,
- char *name,int servertype,
- int ttl,char *comment,
- BOOL replace);
-void expire_servers(time_t t);
-
-/*The following definitions come from namedbsubnet.c */
-
-struct subnet_record *find_subnet(struct in_addr bcast_ip);
-struct subnet_record *find_req_subnet(struct in_addr ip, BOOL bcast);
-struct subnet_record *find_subnet_all(struct in_addr bcast_ip);
-void add_workgroup_to_subnet( struct subnet_record *d, char *group);
-void add_my_subnets(char *group);
-void write_browse_list(time_t t);
-
-/*The following definitions come from namedbwork.c */
-
-struct work_record *remove_workgroup(struct subnet_record *d,
- struct work_record *work,
- BOOL remove_all_servers);
-struct work_record *find_workgroupstruct(struct subnet_record *d,
- fstring name, BOOL add);
-void dump_workgroups(void);
-
-/*The following definitions come from nameelect.c */
-
-void check_master_browser(time_t t);
-void browser_gone(char *work_name, struct in_addr ip);
-void send_election(struct subnet_record *d, char *group,uint32 criterion,
- int timeup,char *name);
-void name_unregister_work(struct subnet_record *d, char *name, int name_type);
-void name_register_work(struct subnet_record *d, char *name, int name_type,
- int nb_flags, time_t ttl, struct in_addr ip, BOOL bcast);
-void become_local_master(struct subnet_record *d, struct work_record *work);
-void become_domain_master(struct subnet_record *d, struct work_record *work);
-void become_logon_server(struct subnet_record *d, struct work_record *work);
-void unbecome_local_master(struct subnet_record *d, struct work_record *work,
- int remove_type);
-void unbecome_domain_master(struct subnet_record *d, struct work_record *work,
- int remove_type);
-void unbecome_logon_server(struct subnet_record *d, struct work_record *work,
- int remove_type);
-void run_elections(time_t t);
-void process_election(struct packet_struct *p,char *buf);
-BOOL check_elections(void);
-
-/*The following definitions come from namelogon.c */
-
-void process_logon_packet(struct packet_struct *p,char *buf,int len);
-
-/*The following definitions come from namepacket.c */
-
-void debug_browse_data(char *outbuf, int len);
-void initiate_netbios_packet(uint16 *id,
- int fd,int quest_type,char *name,int name_type,
- int nb_flags,BOOL bcast,BOOL recurse,
- struct in_addr to_ip);
-void reply_netbios_packet(struct packet_struct *p1,int trn_id,
- int rcode, int rcv_code, int opcode,
- BOOL recursion_available,
- BOOL recursion_desired,
- struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
- char *data,int len);
-void queue_packet(struct packet_struct *packet);
-void run_packet_queue();
-void listen_for_packets(BOOL run_election);
-BOOL send_mailslot_reply(BOOL unique, char *mailslot,int fd,char *buf,int len,char *srcname,
- char *dstname,int src_type,int dest_type,
- struct in_addr dest_ip,struct in_addr src_ip);
-
-/*The following definitions come from namequery.c */
-
-BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
- struct in_addr to_ip,char *master,char *rname,
- void (*fn)());
-BOOL name_query(int fd,char *name,int name_type,
- BOOL bcast,BOOL recurse,
- struct in_addr to_ip, struct in_addr *ip,void (*fn)());
-
-/*The following definitions come from nameresp.c */
-
-void expire_netbios_response_entries(time_t t);
-struct response_record *queue_netbios_pkt_wins(
- int fd,int quest_type,enum state_type state,
- char *name,int name_type,int nb_flags, time_t ttl,
- int server_type, char *my_name, char *my_comment,
- struct in_addr send_ip, struct in_addr reply_to_ip);
-struct response_record *queue_netbios_packet(struct subnet_record *d,
- int fd,int quest_type,enum state_type state,char *name,
- int name_type,int nb_flags, time_t ttl,
- int server_type, char *my_name, char *my_comment,
- BOOL bcast,BOOL recurse,
- struct in_addr send_ip, struct in_addr reply_to_ip);
-
-/*The following definitions come from nameserv.c */
-
-void remove_name_entry(struct subnet_record *d, char *name,int type);
-void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags);
-void add_domain_logon_names(void);
-void add_domain_master_bcast(void);
-void add_domain_master_wins(void);
-void add_domain_names(time_t t);
-void add_my_names(void);
-void remove_my_names();
-void refresh_my_names(time_t t);
-void query_refresh_names(time_t t);
-
-/*The following definitions come from nameservreply.c */
-
-void add_name_respond(struct subnet_record *d, int fd, struct in_addr from_ip,
- uint16 response_id,
- struct nmb_name *name,
- int nb_flags, int ttl, struct in_addr register_ip,
- BOOL new_owner, struct in_addr reply_to_ip);
-void reply_name_release(struct packet_struct *p);
-void reply_name_reg(struct packet_struct *p);
-void reply_name_status(struct packet_struct *p);
-void reply_name_query(struct packet_struct *p);
-
-/*The following definitions come from nameservresp.c */
-
-void debug_state_type(int state);
-void response_netbios_packet(struct packet_struct *p);
-
-/*The following definitions come from namework.c */
-
-void reset_server(char *name, int state, struct in_addr ip);
-void tell_become_backup(void);
-BOOL same_context(struct dgram_packet *dgram);
-void process_browse_packet(struct packet_struct *p,char *buf,int len);
-
-/*The following definitions come from nmbd.c */
-
-BOOL reload_services(BOOL test);
-
-/*The following definitions come from nmblib.c */
-
-char *lookup_opcode_name( int opcode );
-void debug_nmb_packet(struct packet_struct *p);
-char *namestr(struct nmb_name *n);
-void free_nmb_packet(struct nmb_packet *nmb);
-void free_packet(struct packet_struct *packet);
-struct packet_struct *read_packet(int fd,enum packet_type packet_type);
-void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope);
-BOOL send_packet(struct packet_struct *p);
-struct packet_struct *receive_packet(int fd,enum packet_type type,int t);
-
-/*The following definitions come from nmblookup.c */
-
-int main(int argc,char *argv[]);
-
-/*The following definitions come from nmbsync.c */
-
-char *getsmbpass(char *pass);
-void sync_browse_lists(struct subnet_record *d, struct work_record *work,
- char *name, int nm_type, struct in_addr ip, BOOL local);
-
-/*The following definitions come from params.c */
-
-BOOL pm_process( char *FileName,
- BOOL (*sfunc)(char *),
- BOOL (*pfunc)(char *, char *) );
-
-/*The following definitions come from password.c */
-
-void generate_next_challenge(char *challenge);
-BOOL set_challenge(char *challenge);
-BOOL last_challenge(char *challenge);
-user_struct *get_valid_user_struct(uint16 vuid);
-void invalidate_vuid(uint16 vuid);
-char *validated_username(uint16 vuid);
-uint16 register_vuid(int uid,int gid, char *name,BOOL guest);
-void add_session_user(char *user);
-void dfs_unlogin(void);
-BOOL password_check(char *password);
-BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8);
-BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd);
-BOOL user_ok(char *user,int snum);
-BOOL authorise_login(int snum,char *user,char *password, int pwlen,
- BOOL *guest,BOOL *force,uint16 vuid);
-BOOL check_hosts_equiv(char *user);
-BOOL server_cryptkey(char *buf);
-BOOL server_validate(char *buf);
-
-/*The following definitions come from pcap.c */
-
-BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname);
-void pcap_printer_fn(void (*fn)());
-
-/*The following definitions come from pipes.c */
-
-int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize);
-BOOL api_LsarpcSNPHS(int cnum,int uid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len);
-BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len);
-char *dom_sid_to_string(DOM_SID *sid);
-BOOL api_ntlsarpcTNP(int cnum,int uid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len);
-
-/*The following definitions come from predict.c */
-
-int read_predict(int fd,int offset,char *buf,char **ptr,int num);
-void do_read_prediction();
-void invalidate_read_prediction(int fd);
-
-/*The following definitions come from printing.c */
-
-void lpq_reset(int snum);
-void print_file(int fnum);
-int get_printqueue(int snum,int cnum,print_queue_struct **queue,
- print_status_struct *status);
-void del_printqueue(int cnum,int snum,int jobid);
-void status_printjob(int cnum,int snum,int jobid,int status);
-int printjob_encode(int snum, int job);
-void printjob_decode(int jobid, int *snum, int *job);
-
-/*The following definitions come from quotas.c */
-
-BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
-BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
-BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
-BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
-BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
-BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize);
-
-/*The following definitions come from replace.c */
-
-char *Strstr(char *s, char *p);
-time_t Mktime(struct tm *t);
-int InNetGr(char *group,char *host,char *user,char *dom);
-void *malloc_wrapped(int size,char *file,int line);
-void *realloc_wrapped(void *ptr,int size,char *file,int line);
-void free_wrapped(void *ptr,char *file,int line);
-void *memcpy_wrapped(void *d,void *s,int l,char *fname,int line);
-
-/*The following definitions come from reply.c */
-
-int reply_special(char *inbuf,char *outbuf);
-int reply_tcon(char *inbuf,char *outbuf);
-int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize);
-int reply_unknown(char *inbuf,char *outbuf);
-int reply_ioctl(char *inbuf,char *outbuf);
-int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize);
-int reply_chkpth(char *inbuf,char *outbuf);
-int reply_getatr(char *inbuf,char *outbuf);
-int reply_setatr(char *inbuf,char *outbuf);
-int reply_dskattr(char *inbuf,char *outbuf);
-int reply_search(char *inbuf,char *outbuf);
-int reply_fclose(char *inbuf,char *outbuf);
-int reply_open(char *inbuf,char *outbuf);
-int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize);
-int reply_ulogoffX(char *inbuf,char *outbuf,int length,int bufsize);
-int reply_mknew(char *inbuf,char *outbuf);
-int reply_ctemp(char *inbuf,char *outbuf);
-int reply_unlink(char *inbuf,char *outbuf);
-int reply_readbraw(char *inbuf, char *outbuf);
-int reply_lockread(char *inbuf,char *outbuf);
-int reply_read(char *inbuf,char *outbuf);
-int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize);
-int reply_writebraw(char *inbuf,char *outbuf);
-int reply_writeunlock(char *inbuf,char *outbuf);
-int reply_write(char *inbuf,char *outbuf,int dum1,int dum2);
-int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize);
-int reply_lseek(char *inbuf,char *outbuf);
-int reply_flush(char *inbuf,char *outbuf);
-int reply_exit(char *inbuf,char *outbuf);
-int reply_close(char *inbuf,char *outbuf);
-int reply_writeclose(char *inbuf,char *outbuf);
-int reply_lock(char *inbuf,char *outbuf);
-int reply_unlock(char *inbuf,char *outbuf);
-int reply_tdis(char *inbuf,char *outbuf);
-int reply_echo(char *inbuf,char *outbuf);
-int reply_printopen(char *inbuf,char *outbuf);
-int reply_printclose(char *inbuf,char *outbuf);
-int reply_printqueue(char *inbuf,char *outbuf);
-int reply_printwrite(char *inbuf,char *outbuf);
-int reply_mkdir(char *inbuf,char *outbuf);
-int reply_rmdir(char *inbuf,char *outbuf);
-int reply_mv(char *inbuf,char *outbuf);
-int reply_copy(char *inbuf,char *outbuf);
-int reply_setdir(char *inbuf,char *outbuf);
-int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize);
-int reply_readbmpx(char *inbuf,char *outbuf,int length,int bufsize);
-int reply_writebmpx(char *inbuf,char *outbuf);
-int reply_writebs(char *inbuf,char *outbuf);
-int reply_setattrE(char *inbuf,char *outbuf);
-int reply_getattrE(char *inbuf,char *outbuf);
-
-/*The following definitions come from server.c */
-
-void *dflt_sig(void);
-void killkids(void);
-mode_t unix_mode(int cnum,int dosmode);
-int dos_mode(int cnum,char *path,struct stat *sbuf);
-int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st);
-BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_path);
-int disk_free(char *path,int *bsize,int *dfree,int *dsize);
-int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize);
-BOOL check_name(char *name,int cnum);
-void sync_file(int fnum);
-void close_file(int fnum);
-BOOL check_file_sharing(int cnum,char *fname);
-int check_share_mode( min_share_mode_entry *share, int deny_mode, char *fname,
- BOOL fcbopen, int *flags);
-void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
- int mode,int oplock_request, int *Access,int *action);
-int seek_file(int fnum,uint32 pos);
-int read_file(int fnum,char *data,uint32 pos,int n);
-int write_file(int fnum,char *data,int n);
-BOOL become_service(int cnum,BOOL do_chdir);
-int find_service(char *service);
-int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line);
-int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line);
-int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line);
-BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval);
-BOOL request_oplock_break(min_share_mode_entry *share_entry,
- uint32 dev, uint32 inode);
-BOOL snum_used(int snum);
-BOOL reload_services(BOOL test);
-int setup_groups(char *user, int uid, int gid, int *p_ngroups,
- int **p_igroups, gid_t **p_groups);
-int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid);
-int find_free_file(void );
-int reply_corep(char *outbuf);
-int reply_coreplus(char *outbuf);
-int reply_lanman1(char *outbuf);
-int reply_lanman2(char *outbuf);
-int reply_nt1(char *outbuf);
-void close_cnum(int cnum, uint16 vuid);
-BOOL yield_connection(int cnum,char *name,int max_connections);
-BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear);
-void exit_server(char *reason);
-void standard_sub(int cnum,char *str);
-char *smb_fn_name(int type);
-int chain_reply(char *inbuf,char *outbuf,int size,int bufsize);
-int construct_reply(char *inbuf,char *outbuf,int size,int bufsize);
-
-/*The following definitions come from shmem.c */
-
-BOOL smb_shm_create_hash_table( unsigned int size );
-BOOL smb_shm_open( char *file_name, int size);
-BOOL smb_shm_close( void );
-smb_shm_offset_t smb_shm_alloc(int size);
-BOOL smb_shm_free(smb_shm_offset_t offset);
-smb_shm_offset_t smb_shm_get_userdef_off(void);
-BOOL smb_shm_set_userdef_off(smb_shm_offset_t userdef_off);
-void *smb_shm_offset2addr(smb_shm_offset_t offset);
-smb_shm_offset_t smb_shm_addr2offset(void *addr);
-BOOL smb_shm_lock_hash_entry( unsigned int entry);
-BOOL smb_shm_unlock_hash_entry( unsigned int entry );
-BOOL smb_shm_get_usage(int *bytes_free,
- int *bytes_used,
- int *bytes_overhead);
-
-/*The following definitions come from smbdes.c */
-
-void E_P16(unsigned char *p14,unsigned char *p16);
-void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24);
-
-/*The following definitions come from smbencrypt.c */
-
-void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24);
-void E_md4hash(uchar *passwd, uchar *p16);
-void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24);
-
-/*The following definitions come from smbparse.c */
-
-char* smb_io_utime(BOOL io, UTIME *t, char *q, char *base, int align);
-char* smb_io_time(BOOL io, NTTIME *nttime, char *q, char *base, int align);
-char* smb_io_dom_sid(BOOL io, DOM_SID *sid, char *q, char *base, int align);
-char* smb_io_unihdr(BOOL io, UNIHDR *hdr, char *q, char *base, int align);
-char* smb_io_unihdr2(BOOL io, UNIHDR2 *hdr2, char *q, char *base, int align);
-char* smb_io_unistr(BOOL io, UNISTR *uni, char *q, char *base, int align);
-char* smb_io_unistr2(BOOL io, UNISTR2 *uni2, char *q, char *base, int align);
-char* smb_io_dom_sid2(BOOL io, DOM_SID2 *sid2, char *q, char *base, int align);
-char* smb_io_dom_rid2(BOOL io, DOM_RID2 *rid2, char *q, char *base, int align);
-char* smb_io_log_info(BOOL io, DOM_LOG_INFO *log, char *q, char *base, int align);
-char* smb_io_chal(BOOL io, DOM_CHAL *chal, char *q, char *base, int align);
-char* smb_io_cred(BOOL io, DOM_CRED *cred, char *q, char *base, int align);
-char* smb_io_clnt_info(BOOL io, DOM_CLNT_INFO *clnt, char *q, char *base, int align);
-char* smb_io_logon_id(BOOL io, DOM_LOGON_ID *log, char *q, char *base, int align);
-char* smb_io_arc4_owf(BOOL io, ARC4_OWF *hash, char *q, char *base, int align);
-char* smb_io_id_info1(BOOL io, DOM_ID_INFO_1 *id, char *q, char *base, int align);
-char* smb_io_sam_info(BOOL io, DOM_SAM_INFO *sam, char *q, char *base, int align);
-char* smb_io_gid(BOOL io, DOM_GID *gid, char *q, char *base, int align);
-char* smb_io_rpc_hdr(BOOL io, RPC_HDR *rpc, char *q, char *base, int align);
-char* smb_io_pol_hnd(BOOL io, LSA_POL_HND *pol, char *q, char *base, int align);
-char* smb_io_dom_query_3(BOOL io, DOM_QUERY_3 *d_q, char *q, char *base, int align);
-char* smb_io_dom_query_5(BOOL io, DOM_QUERY_3 *d_q, char *q, char *base, int align);
-char* smb_io_dom_query(BOOL io, DOM_QUERY *d_q, char *q, char *base, int align);
-char* smb_io_dom_r_ref(BOOL io, DOM_R_REF *r_r, char *q, char *base, int align);
-char* smb_io_dom_name(BOOL io, DOM_NAME *name, char *q, char *base, int align);
-char* smb_io_neg_flags(BOOL io, NEG_FLAGS *neg, char *q, char *base, int align);
-
-/*The following definitions come from smbpass.c */
-
-int pw_file_lock(char *name, int type, int secs);
-int pw_file_unlock(int fd);
-struct smb_passwd *get_smbpwnam(char *name);
-
-/*The following definitions come from smbpasswd.c */
-
-
-/*The following definitions come from smbrun.c */
-
-
-/*The following definitions come from status.c */
-
-void Ucrit_addUsername(pstring username);
-unsigned int Ucrit_checkUsername(pstring username);
-void Ucrit_addPid(int pid);
-unsigned int Ucrit_checkPid(int pid);
-
-/*The following definitions come from system.c */
-
-int sys_select(fd_set *fds,struct timeval *tval);
-int sys_select(fd_set *fds,struct timeval *tval);
-int sys_unlink(char *fname);
-int sys_open(char *fname,int flags,int mode);
-DIR *sys_opendir(char *dname);
-int sys_stat(char *fname,struct stat *sbuf);
-int sys_waitpid(pid_t pid,int *status,int options);
-int sys_lstat(char *fname,struct stat *sbuf);
-int sys_mkdir(char *dname,int mode);
-int sys_rmdir(char *dname);
-int sys_chdir(char *dname);
-int sys_utime(char *fname,struct utimbuf *times);
-int sys_rename(char *from, char *to);
-int sys_chmod(char *fname,int mode);
-char *sys_getwd(char *s);
-int sys_chown(char *fname,int uid,int gid);
-int sys_chroot(char *dname);
-struct hostent *sys_gethostbyname(char *name);
-
-/*The following definitions come from testparm.c */
-
-
-/*The following definitions come from testprns.c */
-
-int main(int argc, char *argv[]);
-
-/*The following definitions come from time.c */
-
-void GetTimeOfDay(struct timeval *tval);
-void TimeInit(void);
-int TimeDiff(time_t t);
-struct tm *LocalTime(time_t *t);
-time_t interpret_long_date(char *p);
-void put_long_date(char *p,time_t t);
-void put_dos_date(char *buf,int offset,time_t unixdate);
-void put_dos_date2(char *buf,int offset,time_t unixdate);
-void put_dos_date3(char *buf,int offset,time_t unixdate);
-time_t make_unix_date(void *date_ptr);
-time_t make_unix_date2(void *date_ptr);
-time_t make_unix_date3(void *date_ptr);
-BOOL set_filetime(char *fname,time_t mtime);
-char *timestring(void );
-
-/*The following definitions come from trans2.c */
-
-int reply_findclose(char *inbuf,char *outbuf,int length,int bufsize);
-int reply_findnclose(char *inbuf,char *outbuf,int length,int bufsize);
-int reply_transs2(char *inbuf,char *outbuf,int length,int bufsize);
-int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize);
-
-/*The following definitions come from ufc.c */
-
-char *ufc_crypt(char *key,char *salt);
-
-/*The following definitions come from uid.c */
-
-void init_uid(void);
-BOOL become_guest(void);
-BOOL become_user(int cnum, uint16 vuid);
-BOOL unbecome_user(void );
-int smbrun(char *cmd,char *outfile,BOOL shared);
-
-/*The following definitions come from username.c */
-
-char *get_home_dir(char *user);
-void map_username(char *user);
-struct passwd *Get_Pwnam(char *user,BOOL allow_change);
-BOOL user_in_list(char *user,char *list);
-
-/*The following definitions come from util.c */
-
-void setup_logging(char *pname,BOOL interactive);
-void reopen_logs(void);
-char *tmpdir(void);
-BOOL is_a_socket(int fd);
-BOOL next_token(char **ptr,char *buff,char *sep);
-char **toktocliplist(int *ctok, char *sep);
-void *MemMove(void *dest,void *src,int size);
-void array_promote(char *array,int elsize,int element);
-void set_socket_options(int fd, char *options);
-void close_sockets(void );
-BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups);
-char *StrCpy(char *dest,char *src);
-char *StrnCpy(char *dest,char *src,int n);
-void putip(void *dest,void *src);
-int name_mangle( char *In, char *Out, char name_type );
-BOOL file_exist(char *fname,struct stat *sbuf);
-time_t file_modtime(char *fname);
-BOOL directory_exist(char *dname,struct stat *st);
-uint32 file_size(char *file_name);
-char *attrib_string(int mode);
-int StrCaseCmp(char *s, char *t);
-int StrnCaseCmp(char *s, char *t, int n);
-BOOL strequal(char *s1, char *s2);
-BOOL strnequal(char *s1,char *s2,int n);
-BOOL strcsequal(char *s1,char *s2);
-void strlower(char *s);
-void strupper(char *s);
-void strnorm(char *s);
-BOOL strisnormal(char *s);
-void string_replace(char *s,char oldc,char newc);
-void unix_format(char *fname);
-void dos_format(char *fname);
-void show_msg(char *buf);
-int smb_len(char *buf);
-void _smb_setlen(char *buf,int len);
-void smb_setlen(char *buf,int len);
-int set_message(char *buf,int num_words,int num_bytes,BOOL zero);
-int smb_numwords(char *buf);
-int smb_buflen(char *buf);
-int smb_buf_ofs(char *buf);
-char *smb_buf(char *buf);
-int smb_offset(char *p,char *buf);
-char *skip_string(char *buf,int n);
-BOOL trim_string(char *s,char *front,char *back);
-void dos_clean_name(char *s);
-void unix_clean_name(char *s);
-int ChDir(char *path);
-char *GetWd(char *str);
-BOOL reduce_name(char *s,char *dir,BOOL widelinks);
-void expand_mask(char *Mask,BOOL doext);
-BOOL strhasupper(char *s);
-BOOL strhaslower(char *s);
-int count_chars(char *s,char c);
-void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date);
-void close_low_fds(void);
-int set_blocking(int fd, BOOL set);
-int write_socket(int fd,char *buf,int len);
-int read_udp_socket(int fd,char *buf,int len);
-int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out);
-int read_max_udp(int fd,char *buffer,int bufsize,int maxtime);
-int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew);
-BOOL send_keepalive(int client);
-int read_data(int fd,char *buffer,int N);
-int write_data(int fd,char *buffer,int N);
-int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align);
-int read_smb_length(int fd,char *inbuf,int timeout);
-BOOL receive_smb(int fd,char *buffer, int timeout);
-BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout);
-BOOL push_local_message(char *buf, int msg_len);
-BOOL receive_message_or_smb(int smbfd, int oplock_fd,
- char *buffer, int buffer_len,
- int timeout, BOOL *got_smb);
-BOOL send_smb(int fd,char *buffer);
-char *name_ptr(char *buf,int ofs);
-int name_extract(char *buf,int ofs,char *name);
-int name_len( char *s );
-BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type);
-void msleep(int t);
-BOOL in_list(char *s,char *list,BOOL casesensitive);
-BOOL string_init(char **dest,char *src);
-void string_free(char **s);
-BOOL string_set(char **dest,char *src);
-BOOL string_sub(char *s,char *pattern,char *insert);
-BOOL do_match(char *str, char *regexp, int case_sig);
-BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2);
-void become_daemon(void);
-BOOL yesno(char *p);
-char *fgets_slash(char *s2,int maxlen,FILE *f);
-int set_filelen(int fd, long len);
-int byte_checksum(char *buf,int len);
-char *dirname_dos(char *path,char *buf);
-void *Realloc(void *p,int size);
-void Abort(void );
-BOOL get_myname(char *my_name,struct in_addr *ip);
-BOOL ip_equal(struct in_addr ip1,struct in_addr ip2);
-int open_socket_in(int type, int port, int dlevel,uint32 socket_addr);
-int open_socket_out(int type, struct in_addr *addr, int port ,int timeout);
-int interpret_protocol(char *str,int def);
-int interpret_security(char *str,int def);
-uint32 interpret_addr(char *str);
-struct in_addr *interpret_addr2(char *str);
-BOOL zero_ip(struct in_addr ip);
-void reset_globals_after_fork();
-char *client_name(void);
-char *client_addr(void);
-void standard_sub_basic(char *str);
-BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask);
-int PutUniCode(char *dst,char *src);
-struct hostent *Get_Hostbyname(char *name);
-BOOL process_exists(int pid);
-char *uidtoname(int uid);
-char *gidtoname(int gid);
-void BlockSignals(BOOL block,int signum);
-void ajt_panic(void);
-char *readdirname(void *p);
-BOOL is_in_path(char *name, name_compare_entry *namelist);
-void set_namearray(name_compare_entry **ppname_array, char *namelist);
-void free_namearray(name_compare_entry *name_array);
-BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type);
-int file_lock(char *name,int timeout);
-void file_unlock(int fd);
-BOOL is_myname(char *s);
-void set_remote_arch(enum remote_arch_types type);
-enum remote_arch_types get_remote_arch();
-char *skip_unicode_string(char *buf,int n);
-char *unistr2(uint16 *buf);
-char *unistr(char *buf);
-int unistrncpy(char *dst, char *src, int len);
-int unistrcpy(char *dst, char *src);
-void fstrcpy(char *dest, char *src);
-void pstrcpy(char *dest, char *src);
-char *align4(char *q, char *base);
-char *align2(char *q, char *base);
-char *align_offset(char *q, char *base, int align_offset_len);
diff --git a/source/include/smb.h b/source/include/smb.h
deleted file mode 100644
index 54ce9e88e88..00000000000
--- a/source/include/smb.h
+++ /dev/null
@@ -1,1694 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- SMB parameters and setup
- Copyright (C) Andrew Tridgell 1992-1997
- Copyright (C) John H Terpstra 1996-1997
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997
- Copyright (C) Paul Ashton 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.
-*/
-#ifndef _SMB_H
-#define _SMB_H
-
-#ifndef MAX_CONNECTIONS
-#define MAX_CONNECTIONS 127
-#endif
-
-#ifndef MAX_OPEN_FILES
-#define MAX_OPEN_FILES 50
-#endif
-
-#ifndef GUEST_ACCOUNT
-#define GUEST_ACCOUNT "nobody"
-#endif
-
-#define BUFFER_SIZE (0xFFFF)
-#define SAFETY_MARGIN 1024
-
-/* Default size of shared memory used for share mode locking */
-#ifndef SHMEM_SIZE
-#define SHMEM_SIZE 102400
-#endif
-
-/* Default number of hash buckets used in shared memory share mode */
-#ifndef SHMEM_HASH_SIZE
-#define SHMEM_HASH_SIZE 113
-#endif
-
-#define NMB_PORT 137
-#define DGRAM_PORT 138
-#define SMB_PORT 139
-
-#define False (0)
-#define True (1)
-#define BOOLSTR(b) ((b) ? "Yes" : "No")
-#define BITSETB(ptr,bit) ((((char *)ptr)[0] & (1<<(bit)))!=0)
-#define BITSETW(ptr,bit) ((SVAL(ptr,0) & (1<<(bit)))!=0)
-#define PTR_DIFF(p1,p2) ((ptrdiff_t)(((char *)(p1)) - (char *)(p2)))
-
-typedef int BOOL;
-
-/* offset in shared memory */
-typedef int smb_shm_offset_t;
-#define NULL_OFFSET (smb_shm_offset_t)(0)
-
-
-/*
- Samba needs type definitions for int16, int32, uint16 and uint32.
-
- Normally these are signed and unsigned 16 and 32 bit integers, but
- they actually only need to be at least 16 and 32 bits
- respectively. Thus if your word size is 8 bytes just defining them
- as signed and unsigned int will work.
-*/
-
-/* afs/stds.h defines int16 and int32 */
-#ifndef AFS_AUTH
-typedef short int16;
-typedef int int32;
-#endif
-
-#ifndef uint8
-typedef unsigned char uint8;
-#endif
-
-#ifndef uint16
-typedef unsigned short uint16;
-#endif
-
-#ifndef uint32
-typedef unsigned int uint32;
-#endif
-
-#ifndef uchar
-#define uchar unsigned char
-#endif
-#ifndef int16
-#define int16 short
-#endif
-#ifndef uint16
-#define uint16 unsigned short
-#endif
-#ifndef uint32
-#define uint32 unsigned int
-#endif
-
-#define SIZEOFWORD 2
-
-#ifndef DEF_CREATE_MASK
-#define DEF_CREATE_MASK (0755)
-#endif
-
-/* how long to wait for secondary SMB packets (milli-seconds) */
-#define SMB_SECONDARY_WAIT (60*1000)
-
-/* debugging code */
-#ifndef SYSLOG
-#define DEBUG(level,body) ((DEBUGLEVEL>=(level))?(Debug1 body):0)
-#else
-extern int syslog_level;
-
-#define DEBUG(level,body) ((DEBUGLEVEL>=(level))? (syslog_level = (level), Debug1 body):0)
-#endif
-
-/* this defines the error codes that receive_smb can put in smb_read_error */
-#define READ_TIMEOUT 1
-#define READ_EOF 2
-#define READ_ERROR 3
-
-
-#define DIR_STRUCT_SIZE 43
-
-/* these define all the command types recognised by the server - there
-are lots of gaps so probably there are some rare commands that are not
-implemented */
-
-#define pSETDIR '\377'
-
-/* these define the attribute byte as seen by DOS */
-#define aRONLY (1L<<0)
-#define aHIDDEN (1L<<1)
-#define aSYSTEM (1L<<2)
-#define aVOLID (1L<<3)
-#define aDIR (1L<<4)
-#define aARCH (1L<<5)
-
-/* deny modes */
-#define DENY_DOS 0
-#define DENY_ALL 1
-#define DENY_WRITE 2
-#define DENY_READ 3
-#define DENY_NONE 4
-#define DENY_FCB 7
-
-/* share types */
-#define STYPE_DISKTREE 0 /* Disk drive */
-#define STYPE_PRINTQ 1 /* Spooler queue */
-#define STYPE_DEVICE 2 /* Serial device */
-#define STYPE_IPC 3 /* Interprocess communication (IPC) */
-
-/* SMB X/Open error codes for the ERRdos error class */
-#define ERRbadfunc 1 /* Invalid function (or system call) */
-#define ERRbadfile 2 /* File not found (pathname error) */
-#define ERRbadpath 3 /* Directory not found */
-#define ERRnofids 4 /* Too many open files */
-#define ERRnoaccess 5 /* Access denied */
-#define ERRbadfid 6 /* Invalid fid */
-#define ERRnomem 8 /* Out of memory */
-#define ERRbadmem 9 /* Invalid memory block address */
-#define ERRbadenv 10 /* Invalid environment */
-#define ERRbadaccess 12 /* Invalid open mode */
-#define ERRbaddata 13 /* Invalid data (only from ioctl call) */
-#define ERRres 14 /* reserved */
-#define ERRbaddrive 15 /* Invalid drive */
-#define ERRremcd 16 /* Attempt to delete current directory */
-#define ERRdiffdevice 17 /* rename/move across different filesystems */
-#define ERRnofiles 18 /* no more files found in file search */
-#define ERRbadshare 32 /* Share mode on file conflict with open mode */
-#define ERRlock 33 /* Lock request conflicts with existing lock */
-#define ERRfilexists 80 /* File in operation already exists */
-#define ERRcannotopen 110 /* Cannot open the file specified */
-#define ERRunknownlevel 124
-#define ERRbadpipe 230 /* Named pipe invalid */
-#define ERRpipebusy 231 /* All instances of pipe are busy */
-#define ERRpipeclosing 232 /* named pipe close in progress */
-#define ERRnotconnected 233 /* No process on other end of named pipe */
-#define ERRmoredata 234 /* More data to be returned */
-#define ERRbaddirectory 267 /* Invalid directory name in a path. */
-#define ERROR_EAS_DIDNT_FIT 275 /* Extended attributes didn't fit */
-#define ERROR_EAS_NOT_SUPPORTED 282 /* Extended attributes not supported */
-#define ERRunknownipc 2142
-
-
-/* here's a special one from observing NT */
-#define ERRnoipc 66 /* don't support ipc */
-
-/* Error codes for the ERRSRV class */
-
-#define ERRerror 1 /* Non specific error code */
-#define ERRbadpw 2 /* Bad password */
-#define ERRbadtype 3 /* reserved */
-#define ERRaccess 4 /* No permissions to do the requested operation */
-#define ERRinvnid 5 /* tid invalid */
-#define ERRinvnetname 6 /* Invalid servername */
-#define ERRinvdevice 7 /* Invalid device */
-#define ERRqfull 49 /* Print queue full */
-#define ERRqtoobig 50 /* Queued item too big */
-#define ERRinvpfid 52 /* Invalid print file in smb_fid */
-#define ERRsmbcmd 64 /* Unrecognised command */
-#define ERRsrverror 65 /* smb server internal error */
-#define ERRfilespecs 67 /* fid and pathname invalid combination */
-#define ERRbadlink 68 /* reserved */
-#define ERRbadpermits 69 /* Access specified for a file is not valid */
-#define ERRbadpid 70 /* reserved */
-#define ERRsetattrmode 71 /* attribute mode invalid */
-#define ERRpaused 81 /* Message server paused */
-#define ERRmsgoff 82 /* Not receiving messages */
-#define ERRnoroom 83 /* No room for message */
-#define ERRrmuns 87 /* too many remote usernames */
-#define ERRtimeout 88 /* operation timed out */
-#define ERRnoresource 89 /* No resources currently available for request. */
-#define ERRtoomanyuids 90 /* too many userids */
-#define ERRbaduid 91 /* bad userid */
-#define ERRuseMPX 250 /* temporarily unable to use raw mode, use MPX mode */
-#define ERRuseSTD 251 /* temporarily unable to use raw mode, use standard mode */
-#define ERRcontMPX 252 /* resume MPX mode */
-#define ERRbadPW /* reserved */
-#define ERRnosupport 0xFFFF
-#define ERRunknownsmb 22 /* from NT 3.5 response */
-
-
-/* Error codes for the ERRHRD class */
-
-#define ERRnowrite 19 /* read only media */
-#define ERRbadunit 20 /* Unknown device */
-#define ERRnotready 21 /* Drive not ready */
-#define ERRbadcmd 22 /* Unknown command */
-#define ERRdata 23 /* Data (CRC) error */
-#define ERRbadreq 24 /* Bad request structure length */
-#define ERRseek 25
-#define ERRbadmedia 26
-#define ERRbadsector 27
-#define ERRnopaper 28
-#define ERRwrite 29 /* write fault */
-#define ERRread 30 /* read fault */
-#define ERRgeneral 31 /* General hardware failure */
-#define ERRwrongdisk 34
-#define ERRFCBunavail 35
-#define ERRsharebufexc 36 /* share buffer exceeded */
-#define ERRdiskfull 39
-
-
-typedef char pstring[1024];
-typedef char fstring[128];
-typedef fstring string;
-
-
-/* NETLOGON opcodes and data structures */
-
-#define NET_QUERYFORPDC 7 /* Query for PDC */
-#define NET_QUERYFORPDC_R 12 /* Response to Query for PDC */
-#define NET_SAMLOGON 18
-#define NET_SAMLOGON_R 19
-
-/* Allowable account control bits */
-#define ACB_DISABLED 1 /* 1 = User account disabled */
-#define ACB_HOMDIRREQ 2 /* 1 = Home directory required */
-#define ACB_PWNOTREQ 4 /* 1 = User password not required */
-#define ACB_TEMPDUP /* 1 = Temporary duplicate account */
-#define ACB_NORMAL /* 1 = Normal user account */
-#define ACB_MNS /* 1 = MNS logon user account */
-#define ACB_DOMTRUST /* 1 = Interdomain trust account */
-#define ACB_WSTRUST /* 1 = Workstation trust account */
-#define ACB_SVRTRUST /* 1 = Server trust account */
-#define ACB_PWNOEXP /* 1 = User password does not expire */
-#define ACB_AUTOLOCK /* 1 = Account auto locked */
-
-#define LSA_OPENPOLICY 0x2c
-#define LSA_QUERYINFOPOLICY 0x07
-#define LSA_ENUMTRUSTDOM 0x0d
-#define LSA_REQCHAL 0x04
-#define LSA_SVRPWSET 0x06
-#define LSA_SAMLOGON 0x02
-#define LSA_AUTH2 0x0f
-#define LSA_CLOSE 0x00
-
-/* unknown .... */
-#define LSA_OPENSECRET 0xFF
-#define LSA_LOOKUPSIDS 0xFE
-#define LSA_LOOKUPNAMES 0xFD
-#define LSA_SAMLOGOFF 0xFC
-
-
-/* 32 bit time (sec) since 01jan1970 - cifs6.txt, section 3.5, page 30 */
-typedef struct time_info
-{
- uint32 time;
-
-} UTIME;
-
-/* 64 bit time (100usec) since ????? - cifs6.txt, section 3.5, page 30 */
-typedef struct nttime_info
-{
- uint32 low;
- uint32 high;
-
-} NTTIME;
-
-
-#define MAXSUBAUTHS 10 /* max sub authorities in a SID */
-
-/* DOM_SID - security id */
-typedef struct sid_info
-{
- uint8 sid_no; /* SID revision number */
- uint8 num_auths; /* number of sub-authorities */
- uint8 id_auth[6]; /* Identifier Authority */
- uint16 sub_auths[MAXSUBAUTHS]; /* pointer to sub-authorities. */
-
-} DOM_SID;
-
-/* UNIHDR - unicode string header */
-typedef struct unihdr_info
-{
- uint16 uni_max_len;
- uint16 uni_str_len;
- uint32 undoc; /* usually has a value of 4 */
-
-} UNIHDR;
-
-/* UNIHDR2 - unicode string header and undocumented buffer */
-typedef struct unihdr2_info
-{
- UNIHDR unihdr;
- uint32 undoc_buffer; /* undocumented 32 bit buffer pointer */
-
-} UNIHDR2;
-
-/* clueless as to what maximum length should be */
-#define MAX_UNISTRLEN 1024
-
-/* UNISTR - unicode string size and buffer */
-typedef struct unistr_info
-{
- uint16 buffer[MAX_UNISTRLEN]; /* unicode characters. ***MUST*** be null-terminated */
-
-} UNISTR;
-
-/* UNISTR2 - unicode string size and buffer */
-typedef struct unistr2_info
-{
- uint32 uni_max_len;
- uint32 undoc;
- uint32 uni_str_len;
- uint16 buffer[MAX_UNISTRLEN]; /* unicode characters. **NOT** necessarily null-terminated */
-
-} UNISTR2;
-
-/* DOM_SID2 - domain SID structure - SIDs stored in unicode */
-typedef struct domsid2_info
-{
- uint32 type; /* value is 5 */
- uint32 undoc; /* value is 0 */
-
- UNIHDR2 hdr; /* XXXX conflict between hdr and str for length */
- UNISTR str; /* XXXX conflict between hdr and str for length */
-
-} DOM_SID2;
-
-/* DOM_RID2 - domain RID structure */
-typedef struct domrid2_info
-{
- uint32 type; /* value is 5 */
- uint32 undoc; /* value is 5 */
- uint32 rid;
- uint32 rid_idx; /* don't know what this is */
-
-} DOM_RID2;
-
-/* DOM_LOG_INFO - login info */
-typedef struct log_info
-{
- uint32 undoc_buffer; /* undocumented 32 bit buffer pointer */
- UNISTR2 uni_logon_srv; /* logon server name */
- UNISTR2 uni_acct_name; /* account name */
- uint16 sec_chan; /* secure channel type */
- UNISTR2 uni_comp_name; /* client machine name */
-
-} DOM_LOG_INFO;
-
-/* DOM_CHAL - challenge info */
-typedef struct chal_info
-{
- uint8 data[8]; /* credentials */
-
-} DOM_CHAL;
-
-/* DOM_CREDs - timestamped client or server credentials */
-typedef struct cred_info
-{
- DOM_CHAL challenge; /* credentials */
- UTIME timestamp; /* credential time-stamp */
-
-} DOM_CRED;
-
-/* DOM_CLNT_INFO - client info */
-typedef struct clnt_info
-{
- DOM_LOG_INFO login;
- DOM_CRED cred;
-
-} DOM_CLNT_INFO;
-
-/* DOM_LOGON_ID - logon id */
-typedef struct logon_info
-{
- uint32 low;
- uint32 high;
-
-} DOM_LOGON_ID;
-
-/* ARC4_OWF */
-typedef struct arc4_owf_info
-{
- uint8 data[16];
-
-} ARC4_OWF;
-
-
-/* DOM_ID_INFO_1 */
-typedef struct id_info_1
-{
- UNIHDR hdr_domain_name; /* domain name unicode header */
- uint32 param; /* param control */
- DOM_LOGON_ID logon_id; /* logon ID */
- UNIHDR hdr_user_name; /* user name unicode header */
- UNIHDR hdr_workgroup_name; /* workgroup name unicode header */
- ARC4_OWF arc4_lm_owf; /* arc4 LM OWF Password */
- ARC4_OWF arc4_nt_owf; /* arc4 NT OWF Password */
- UNISTR2 uni_domain_name; /* domain name unicode string */
- UNISTR2 uni_user_name; /* user name unicode string */
- UNISTR2 uni_workgroup_name; /* workgroup name unicode string */
-
-} DOM_ID_INFO_1;
-
-/* SAM_INFO - sam logon/off id structure */
-typedef struct sam_info
-{
- DOM_CLNT_INFO client;
- DOM_CRED rtn_cred; /* return credentials */
- uint16 logon_level;
- uint32 auth_level; /* undocumented */
-
- union
- {
- DOM_ID_INFO_1 id1; /* auth-level 1 */
-
- } auth;
-
-} DOM_SAM_INFO;
-
-/* DOM_GID - group id + user attributes */
-typedef struct gid_info
-{
- uint32 gid; /* group id */
- uint32 attr;
-
-} DOM_GID;
-
-/* RPC_HDR - ms rpc header */
-typedef struct rpc_hdr_info
-{
- uint8 major; /* 5 - RPC major version */
- uint8 minor; /* 0 - RPC minor version */
- uint8 pkt_type; /* 2 - RPC response packet */
- uint8 frag; /* 3 - first frag + last frag */
- uint32 pack_type; /* 0x0000 0010 - packed data representation */
- uint16 frag_len; /* fragment length - data size (bytes) inc header and tail. */
- uint16 auth_len; /* 0 - authentication length */
- uint32 call_id; /* call identifier. matches 12th uint32 of incoming RPC data. */
- uint32 alloc_hint; /* allocation hint - data size (bytes) minus header and tail. */
- uint16 context_id; /* 0 - presentation context identifier */
- uint8 cancel_count; /* 0 - cancel count */
- uint8 reserved; /* 0 - reserved */
-
-} RPC_HDR;
-
-/* DOM_QUERY - info class 3 and 5 LSA Query response */
-typedef struct dom_query_info
-{
- uint16 uni_dom_max_len; /* domain name string length * 2 */
- uint16 padding; /* 2 padding bytes? */
- uint16 uni_dom_str_len; /* domain name string length * 2 */
- uint32 buffer_dom_name; /* undocumented domain name string buffer pointer */
- uint32 buffer_dom_sid; /* undocumented domain SID string buffer pointer */
- UNISTR2 uni_domain_name; /* domain name (unicode string) */
- DOM_SID dom_sid; /* domain SID */
-
-} DOM_QUERY;
-
-/* level 5 is same as level 3. we hope. */
-typedef DOM_QUERY DOM_QUERY_3;
-typedef DOM_QUERY DOM_QUERY_5;
-
-#define POL_HND_SIZE 20
-
-/* LSA_POL_HND */
-typedef struct lsa_policy_info
-{
- uint8 data[POL_HND_SIZE]; /* policy handle */
-
-} LSA_POL_HND;
-
-
-/* LSA_R_OPEN_POL - response to LSA Open Policy */
-typedef struct lsa_r_open_pol_info
-{
- LSA_POL_HND pol; /* policy handle */
-
- uint32 status; /* return code */
-
-} LSA_R_OPEN_POL;
-
-/* LSA_Q_QUERY_INFO - LSA query info policy */
-typedef struct lsa_query_info
-{
- LSA_POL_HND pol; /* policy handle */
- uint16 info_class; /* info class */
-
-} LSA_Q_QUERY_INFO;
-
-/* LSA_R_QUERY_INFO - response to LSA query info policy */
-typedef struct lsa_r_query_info
-{
- uint32 undoc_buffer; /* undocumented buffer pointer */
- uint16 info_class; /* info class (same as info class in request) */
-
- union
- {
- DOM_QUERY_3 id3;
- DOM_QUERY_5 id5;
- } dom;
-
- uint32 status; /* return code */
-
-} LSA_R_QUERY_INFO;
-
-#define MAX_REF_DOMAINS 10
-
-/* DOM_R_REF */
-typedef struct dom_ref_info
-{
- uint32 undoc_buffer; /* undocumented buffer pointer. */
- uint32 num_ref_doms_1; /* num referenced domains? */
- uint32 buffer_dom_name; /* undocumented domain name buffer pointer. */
- uint32 max_entries; /* 32 - max number of entries */
- uint32 num_ref_doms_2; /* 4 - num referenced domains? */
-
- UNIHDR2 hdr_dom_name; /* domain name unicode string header */
- UNIHDR2 hdr_ref_dom[MAX_REF_DOMAINS]; /* referenced domain unicode string headers */
-
- UNISTR uni_dom_name; /* domain name unicode string */
- DOM_SID ref_dom[MAX_REF_DOMAINS]; /* referenced domain SIDs */
-
-} DOM_R_REF;
-
-#define MAX_LOOKUP_SIDS 10
-
-/* LSA_Q_LOOKUP_SIDS - LSA Lookup SIDs */
-typedef struct lsa_q_lookup_sids
-{
- LSA_POL_HND pol_hnd; /* policy handle */
- uint32 num_entries;
- uint32 buffer_dom_sid; /* undocumented domain SID buffer pointer */
- uint32 buffer_dom_name; /* undocumented domain name buffer pointer */
- uint32 buffer_lookup_sids[MAX_LOOKUP_SIDS]; /* undocumented domain SID pointers to be looked up. */
- DOM_SID dom_sids[MAX_LOOKUP_SIDS]; /* domain SIDs to be looked up. */
- uint8 undoc[16]; /* completely undocumented 16 bytes */
-
-} LSA_Q_LOOKUP_SIDS;
-
-/* LSA_R_LOOKUP_SIDS - response to LSA Lookup SIDs */
-typedef struct lsa_r_lookup_sids
-{
- DOM_R_REF dom_ref; /* domain reference info */
-
- uint32 num_entries;
- uint32 undoc_buffer; /* undocumented buffer pointer */
- uint32 num_entries2;
-
- DOM_SID2 dom_sid[MAX_LOOKUP_SIDS]; /* domain SIDs being looked up */
-
- uint32 num_entries3;
-
- uint32 status; /* return code */
-
-} LSA_R_LOOKUP_SIDS;
-
-/* DOM_NAME - XXXX not sure about this structure */
-typedef struct dom_name_info
-{
- uint32 uni_str_len;
- UNISTR str;
-
-} DOM_NAME;
-
-
-#define UNKNOWN_LEN 1
-
-/* LSA_Q_LOOKUP_RIDS - LSA Lookup RIDs */
-typedef struct lsa_q_lookup_rids
-{
-
- LSA_POL_HND pol_hnd; /* policy handle */
- uint32 num_entries;
- uint32 num_entries2;
- uint32 buffer_dom_sid; /* undocumented domain SID buffer pointer */
- uint32 buffer_dom_name; /* undocumented domain name buffer pointer */
- DOM_NAME lookup_name[MAX_LOOKUP_SIDS]; /* names to be looked up */
- uint8 undoc[UNKNOWN_LEN]; /* completely undocumented bytes of unknown length */
-
-} LSA_Q_LOOKUP_RIDS;
-
-/* LSA_R_LOOKUP_RIDS - response to LSA Lookup Names */
-typedef struct lsa_r_lookup_rids
-{
- DOM_R_REF dom_ref; /* domain reference info */
-
- uint32 num_entries;
- uint32 undoc_buffer; /* undocumented buffer pointer */
-
- uint32 num_entries2;
- DOM_RID2 dom_rid[MAX_LOOKUP_SIDS]; /* domain RIDs being looked up */
-
- uint32 num_entries3;
-
- uint32 status; /* return code */
-
-} LSA_R_LOOKUP_RIDS;
-
-
-
-/* NEG_FLAGS */
-typedef struct lsa_neg_flags_info
-{
- uint32 neg_flags; /* negotiated flags */
-
-} NEG_FLAGS;
-
-
-/* LSA_Q_REQ_CHAL */
-typedef struct lsa_q_req_chal_info
-{
- uint32 undoc_buffer; /* undocumented buffer pointer */
- UNISTR2 uni_logon_srv; /* logon server unicode string */
- UNISTR2 uni_logon_clnt; /* logon client unicode string */
- DOM_CHAL clnt_chal; /* client challenge */
-
-} LSA_Q_REQ_CHAL;
-
-
-/* LSA_R_REQ_CHAL */
-typedef struct lsa_r_req_chal_info
-{
- DOM_CHAL srv_chal; /* server challenge */
-
- uint32 status; /* return code */
-
-} LSA_R_REQ_CHAL;
-
-
-
-/* LSA_Q_AUTH_2 */
-typedef struct lsa_q_auth2_info
-{
- DOM_LOG_INFO clnt_id; /* client identification info */
- DOM_CHAL clnt_chal; /* client-calculated credentials */
-
- NEG_FLAGS clnt_flgs; /* usually 0x0000 01ff */
-
-} LSA_Q_AUTH_2;
-
-
-/* LSA_R_AUTH_2 */
-typedef struct lsa_r_auth2_info
-{
- DOM_CHAL srv_chal; /* server-calculated credentials */
- NEG_FLAGS srv_flgs; /* usually 0x0000 01ff */
-
- uint32 status; /* return code */
-
-} LSA_R_AUTH_2;
-
-
-/* LSA_Q_SRV_PWSET */
-typedef struct lsa_q_srv_pwset_info
-{
- DOM_CLNT_INFO clnt_id; /* client identification/authentication info */
- char pwd[16]; /* new password - undocumented. */
-
-} LSA_Q_SRV_PWSET;
-
-/* LSA_R_SRV_PWSET */
-typedef struct lsa_r_srv_pwset_info
-{
- DOM_CRED srv_cred; /* server-calculated credentials */
-
- uint32 status; /* return code */
-
-} LSA_R_SRV_PWSET;
-
-#define LSA_MAX_GROUPS 32
-#define LSA_MAX_SIDS 32
-
-/* LSA_USER_INFO */
-typedef struct lsa_q_user_info
-{
- uint32 undoc_buffer;
-
- NTTIME logon_time; /* logon time */
- NTTIME logoff_time; /* logoff time */
- NTTIME kickoff_time; /* kickoff time */
- NTTIME pass_last_set_time; /* password last set time */
- NTTIME pass_can_change_time; /* password can change time */
- NTTIME pass_must_change_time; /* password must change time */
-
- UNIHDR hdr_user_name; /* username unicode string header */
- UNIHDR hdr_full_name; /* user's full name unicode string header */
- UNIHDR hdr_logon_script; /* logon script unicode string header */
- UNIHDR hdr_profile_path; /* profile path unicode string header */
- UNIHDR hdr_home_dir; /* home directory unicode string header */
- UNIHDR hdr_dir_drive; /* home directory drive unicode string header */
-
- uint16 logon_count; /* logon count */
- uint16 bad_pw_count; /* bad password count */
-
- uint32 user_id; /* User ID */
- uint32 group_id; /* Group ID */
- uint32 num_groups; /* num groups */
- uint32 buffer_groups; /* undocumented buffer pointer to groups. */
- uint32 user_flgs; /* user flags */
-
- char sess_key[16]; /* unused user session key */
-
- UNIHDR hdr_logon_srv; /* logon server unicode string header */
- UNIHDR hdr_logon_dom; /* logon domain unicode string header */
-
- uint32 buffer_dom_id; /* undocumented logon domain id pointer */
- char padding[40]; /* unused padding bytes? */
-
- uint32 num_other_sids; /* 0 - num_sids */
- uint32 buffer_other_sids; /* NULL - undocumented pointer to SIDs. */
-
- UNISTR2 uni_user_name; /* username unicode string */
- UNISTR2 uni_full_name; /* user's full name unicode string */
- UNISTR2 uni_logon_script; /* logon script unicode string */
- UNISTR2 uni_profile_path; /* profile path unicode string */
- UNISTR2 uni_home_dir; /* home directory unicode string */
- UNISTR2 uni_dir_drive; /* home directory drive unicode string */
-
- uint32 num_groups2; /* num groups */
- DOM_GID gids[LSA_MAX_GROUPS]; /* group info */
-
- UNISTR2 uni_logon_srv; /* logon server unicode string */
- UNISTR2 uni_logon_dom; /* logon domain unicode string */
-
- DOM_SID dom_sid; /* domain SID */
- DOM_SID other_sids[LSA_MAX_SIDS]; /* undocumented - domain SIDs */
-
-} LSA_USER_INFO;
-
-
-/* LSA_Q_SAM_LOGON */
-typedef struct lsa_q_sam_logon_info
-{
- DOM_SAM_INFO sam_id;
-
-} LSA_Q_SAM_LOGON;
-
-/* LSA_R_SAM_LOGON */
-typedef struct lsa_r_sam_logon_info
-{
- uint32 buffer_creds; /* undocumented buffer pointer */
- DOM_CRED srv_creds; /* server credentials. server time stamp appears to be ignored. */
-
- uint32 buffer_user;
- LSA_USER_INFO *user;
-
- uint32 auth_resp; /* 1 - Authoritative response; 0 - Non-Auth? */
-
- uint32 status; /* return code */
-
-} LSA_R_SAM_LOGON;
-
-
-/* LSA_Q_SAM_LOGOFF */
-typedef struct lsa_q_sam_logoff_info
-{
- DOM_SAM_INFO sam_id;
-
-} LSA_Q_SAM_LOGOFF;
-
-/* LSA_R_SAM_LOGOFF */
-typedef struct lsa_r_sam_logoff_info
-{
- uint32 buffer_creds; /* undocumented buffer pointer */
- DOM_CRED srv_creds; /* server credentials. server time stamp appears to be ignored. */
-
- uint32 status; /* return code */
-
-} LSA_R_SAM_LOGOFF;
-
-/*
-
-Yet to be turned into structures:
-
-6) \\MAILSLOT\NET\NTLOGON
--------------------------
-
-6.1) Query for PDC
-------------------
-
-Request:
-
- uint16 0x0007 - Query for PDC
- STR machine name
- STR response mailslot
- uint8[] padding to 2-byte align with start of mailslot.
- UNISTR machine name
- uint32 NTversion
- uint16 LMNTtoken
- uint16 LM20token
-
-Response:
-
- uint16 0x000A - Respose to Query for PDC
- STR machine name (in uppercase)
- uint8[] padding to 2-byte align with start of mailslot.
- UNISTR machine name
- UNISTR domain name
- uint32 NTversion (same as received in request)
- uint16 LMNTtoken (same as received in request)
- uint16 LM20token (same as received in request)
-
-
-6.2) SAM Logon
---------------
-
-Request:
-
- uint16 0x0012 - SAM Logon
- uint16 request count
- UNISTR machine name
- UNISTR user name
- STR response mailslot
- uint32 alloweable account
- uint32 domain SID size
- char[sid_size] domain SID, of sid_size bytes.
- uint8[] ???? padding to 4? 2? -byte align with start of mailslot.
- uint32 NTversion
- uint16 LMNTtoken
- uint16 LM20token
-
-Response:
-
- uint16 0x0013 - Response to SAM Logon
- UNISTR machine name
- UNISTR user name - workstation trust account
- UNISTR domain name
- uint32 NTversion
- uint16 LMNTtoken
- uint16 LM20token
-
-*/
-
-
-struct smb_passwd {
- int smb_userid;
- char *smb_name;
- unsigned char *smb_passwd; /* Null if no password */
- unsigned char *smb_nt_passwd; /* Null if no password */
- /* Other fields / flags may be added later */
-};
-
-
-struct current_user {
- int cnum, id;
- int uid, gid;
- int ngroups;
- gid_t *groups;
- int *igroups;
-};
-
-typedef struct
-{
- int size;
- int mode;
- int uid;
- int gid;
- /* these times are normally kept in GMT */
- time_t mtime;
- time_t atime;
- time_t ctime;
- pstring name;
-} file_info;
-
-
-/* Structure used when SMBwritebmpx is active */
-typedef struct
- {
- int wr_total_written; /* So we know when to discard this */
- int32 wr_timeout;
- int32 wr_errclass;
- int32 wr_error; /* Cached errors */
- BOOL wr_mode; /* write through mode) */
- BOOL wr_discard; /* discard all further data */
- } write_bmpx_struct;
-
-/*
- * Structure used to indirect fd's from the files_struct.
- * Needed as POSIX locking is based on file and process, not
- * file descriptor and process.
- */
-
-typedef struct
-{
- uint16 ref_count;
- uint32 dev;
- uint32 inode;
- int fd;
- int fd_readonly;
- int fd_writeonly;
- int real_open_flags;
-} file_fd_struct;
-
-typedef struct
-{
- int cnum;
- file_fd_struct *fd_ptr;
- int pos;
- uint32 size;
- int mode;
- int uid;
- char *mmap_ptr;
- uint32 mmap_size;
- write_bmpx_struct *wbmpx_ptr;
- struct timeval open_time;
- BOOL open;
- BOOL can_lock;
- BOOL can_read;
- BOOL can_write;
- BOOL share_mode;
- BOOL print_file;
- BOOL modified;
- BOOL granted_oplock;
- char *name;
-} files_struct;
-
-
-struct uid_cache {
- int entries;
- int list[UID_CACHE_SIZE];
-};
-
-typedef struct
-{
- char *name;
- BOOL is_wild;
-} name_compare_entry;
-
-typedef struct
-{
- int service;
- BOOL force_user;
- struct uid_cache uid_cache;
- void *dirptr;
- BOOL open;
- BOOL printer;
- BOOL ipc;
- BOOL read_only;
- BOOL admin_user;
- char *dirpath;
- char *connectpath;
- char *origpath;
- char *user; /* name of user who *opened* this connection */
- int uid; /* uid of user who *opened* this connection */
- int gid; /* gid of user who *opened* this connection */
- uint16 vuid; /* vuid of user who *opened* this connection, or UID_FIELD_INVALID */
- /* following groups stuff added by ih */
- /* This groups info is valid for the user that *opened* the connection */
- int ngroups;
- gid_t *groups;
- int *igroups; /* an integer version - some OSes are broken :-( */
- time_t lastused;
- BOOL used;
- int num_files_open;
- name_compare_entry *hide_list; /* Per-share list of files to return as hidden. */
- name_compare_entry *veto_list; /* Per-share list of files to veto (never show). */
-} connection_struct;
-
-
-typedef struct
-{
- int uid; /* uid of a validated user */
- int gid; /* gid of a validated user */
- fstring name; /* name of a validated user */
- BOOL guest;
- /* following groups stuff added by ih */
- /* This groups info is needed for when we become_user() for this uid */
- int user_ngroups;
- gid_t *user_groups;
- int *user_igroups; /* an integer version - some OSes are broken :-( */
-#if (defined(NETGROUP) && defined(AUTOMOUNT))
- char *home_share; /* to store NIS home of a user - simeon */
-#endif
- char *real_name; /* to store real name from password file - simeon */
-} user_struct;
-
-
-enum {LPQ_QUEUED,LPQ_PAUSED,LPQ_SPOOLING,LPQ_PRINTING};
-
-typedef struct
-{
- int job;
- int size;
- int status;
- int priority;
- time_t time;
- char user[30];
- char file[100];
-} print_queue_struct;
-
-enum {LPSTAT_OK, LPSTAT_STOPPED, LPSTAT_ERROR};
-
-typedef struct
-{
- fstring message;
- int status;
-} print_status_struct;
-
-/* used for server information: client, nameserv and ipc */
-struct server_info_struct
-{
- fstring name;
- uint32 type;
- fstring comment;
- fstring domain; /* used ONLY in ipc.c NOT namework.c */
- BOOL server_added; /* used ONLY in ipc.c NOT namework.c */
-};
-
-
-/* used for network interfaces */
-struct interface
-{
- struct interface *next;
- struct in_addr ip;
- struct in_addr bcast;
- struct in_addr nmask;
-};
-
-/* share mode record pointed to in shared memory hash bucket */
-typedef struct
-{
- smb_shm_offset_t next_offset; /* offset of next record in chain from hash bucket */
- int locking_version;
- int32 st_dev;
- int32 st_ino;
- int num_share_mode_entries;
- smb_shm_offset_t share_mode_entries; /* Chain of share mode entries for this file */
- char file_name[1];
-} share_mode_record;
-
-/* share mode entry pointed to by share_mode_record struct */
-typedef struct
-{
- smb_shm_offset_t next_share_mode_entry;
- int pid;
- uint16 op_port;
- uint16 op_type;
- int share_mode;
- struct timeval time;
-} share_mode_entry;
-
-/* struct returned by get_share_modes */
-typedef struct
-{
- int pid;
- uint16 op_port;
- uint16 op_type;
- int share_mode;
- struct timeval time;
-} min_share_mode_entry;
-
-/* Token returned by lock_share_entry (actually ignored by FAST_SHARE_MODES code) */
-typedef int share_lock_token;
-
-/* Conversion to hash entry index from device and inode numbers. */
-#define HASH_ENTRY(dev,ino) ((( (uint32)(dev) )* ( (uint32)(ino) )) % lp_shmem_hash_size())
-
-/* this is used for smbstatus */
-struct connect_record
-{
- int magic;
- int pid;
- int cnum;
- int uid;
- int gid;
- char name[24];
- char addr[24];
- char machine[128];
- time_t start;
-};
-
-#ifndef LOCKING_VERSION
-#define LOCKING_VERSION 4
-#endif /* LOCKING_VERSION */
-
-#if !defined(FAST_SHARE_MODES)
-/*
- * Defines for slow share modes.
- */
-
-/*
- * Locking file header lengths & offsets.
- */
-#define SMF_VERSION_OFFSET 0
-#define SMF_NUM_ENTRIES_OFFSET 4
-#define SMF_FILENAME_LEN_OFFSET 8
-#define SMF_HEADER_LENGTH 10
-
-#define SMF_ENTRY_LENGTH 20
-
-/*
- * Share mode record offsets.
- */
-
-#define SME_SEC_OFFSET 0
-#define SME_USEC_OFFSET 4
-#define SME_SHAREMODE_OFFSET 8
-#define SME_PID_OFFSET 12
-#define SME_PORT_OFFSET 16
-#define SME_OPLOCK_TYPE_OFFSET 18
-
-#endif /* FAST_SHARE_MODES */
-
-/* these are useful macros for checking validity of handles */
-#define VALID_FNUM(fnum) (((fnum) >= 0) && ((fnum) < MAX_OPEN_FILES))
-#define OPEN_FNUM(fnum) (VALID_FNUM(fnum) && Files[fnum].open)
-#define VALID_CNUM(cnum) (((cnum) >= 0) && ((cnum) < MAX_CONNECTIONS))
-#define OPEN_CNUM(cnum) (VALID_CNUM(cnum) && Connections[cnum].open)
-#define IS_IPC(cnum) (VALID_CNUM(cnum) && Connections[cnum].ipc)
-#define IS_PRINT(cnum) (VALID_CNUM(cnum) && Connections[cnum].printer)
-#define FNUM_OK(fnum,c) (OPEN_FNUM(fnum) && (c)==Files[fnum].cnum)
-
-#define CHECK_FNUM(fnum,c) if (!FNUM_OK(fnum,c)) \
- return(ERROR(ERRDOS,ERRbadfid))
-#define CHECK_READ(fnum) if (!Files[fnum].can_read) \
- return(ERROR(ERRDOS,ERRbadaccess))
-#define CHECK_WRITE(fnum) if (!Files[fnum].can_write) \
- return(ERROR(ERRDOS,ERRbadaccess))
-#define CHECK_ERROR(fnum) if (HAS_CACHED_ERROR(fnum)) \
- return(CACHED_ERROR(fnum))
-
-/* translates a connection number into a service number */
-#define SNUM(cnum) (Connections[cnum].service)
-
-/* access various service details */
-#define SERVICE(snum) (lp_servicename(snum))
-#define PRINTCAP (lp_printcapname())
-#define PRINTCOMMAND(snum) (lp_printcommand(snum))
-#define PRINTERNAME(snum) (lp_printername(snum))
-#define CAN_WRITE(cnum) (OPEN_CNUM(cnum) && !Connections[cnum].read_only)
-#define VALID_SNUM(snum) (lp_snum_ok(snum))
-#define GUEST_OK(snum) (VALID_SNUM(snum) && lp_guest_ok(snum))
-#define GUEST_ONLY(snum) (VALID_SNUM(snum) && lp_guest_only(snum))
-#define CAN_SETDIR(snum) (!lp_no_set_dir(snum))
-#define CAN_PRINT(cnum) (OPEN_CNUM(cnum) && lp_print_ok(SNUM(cnum)))
-#define POSTSCRIPT(cnum) (OPEN_CNUM(cnum) && lp_postscript(SNUM(cnum)))
-#define MAP_HIDDEN(cnum) (OPEN_CNUM(cnum) && lp_map_hidden(SNUM(cnum)))
-#define MAP_SYSTEM(cnum) (OPEN_CNUM(cnum) && lp_map_system(SNUM(cnum)))
-#define MAP_ARCHIVE(cnum) (OPEN_CNUM(cnum) && lp_map_archive(SNUM(cnum)))
-#define IS_HIDDEN_PATH(cnum,path) (is_in_path((path),Connections[(cnum)].hide_list))
-#define IS_VETO_PATH(cnum,path) (is_in_path((path),Connections[(cnum)].veto_list))
-
-#define SMBENCRYPT() (lp_encrypted_passwords())
-
-/* the basic packet size, assuming no words or bytes */
-#define smb_size 39
-
-/* offsets into message for common items */
-#define smb_com 8
-#define smb_rcls 9
-#define smb_reh 10
-#define smb_err 11
-#define smb_flg 13
-#define smb_flg2 14
-#define smb_reb 13
-#define smb_tid 28
-#define smb_pid 30
-#define smb_uid 32
-#define smb_mid 34
-#define smb_wct 36
-#define smb_vwv 37
-#define smb_vwv0 37
-#define smb_vwv1 39
-#define smb_vwv2 41
-#define smb_vwv3 43
-#define smb_vwv4 45
-#define smb_vwv5 47
-#define smb_vwv6 49
-#define smb_vwv7 51
-#define smb_vwv8 53
-#define smb_vwv9 55
-#define smb_vwv10 57
-#define smb_vwv11 59
-#define smb_vwv12 61
-#define smb_vwv13 63
-#define smb_vwv14 65
-#define smb_vwv15 67
-#define smb_vwv16 69
-#define smb_vwv17 71
-
-
-/* the complete */
-#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 SMBtconX 0x75 /* tree connect and X*/
-#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 */
-
-/* Core+ protocol */
-#define SMBlockread 0x13 /* Lock a range and read */
-#define SMBwriteunlock 0x14 /* Unlock a range then write */
-#define SMBreadbraw 0x1a /* read a block of data with no smb header */
-#define SMBwritebraw 0x1d /* write a block of data with no smb header */
-#define SMBwritec 0x20 /* secondary write request */
-#define SMBwriteclose 0x2c /* write a file 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 SMBffirst 0x82 /* find first */
-#define SMBfunique 0x83 /* find unique */
-#define SMBfclose 0x84 /* find close */
-#define SMBinvalid 0xFE /* invalid command */
-
-/* Extended 2.0 protocol */
-#define SMBtrans2 0x32 /* TRANS2 protocol set */
-#define SMBtranss2 0x33 /* TRANS2 protocol set, secondary command */
-#define SMBfindclose 0x34 /* Terminate a TRANSACT2_FINDFIRST */
-#define SMBfindnclose 0x35 /* Terminate a TRANSACT2_FINDNOTIFYFIRST */
-#define SMBulogoffX 0x74 /* user logoff */
-
-/* NT SMB extensions. */
-#define SMBnttrans 0xA0 /* NT transact */
-#define SMBnttranss 0xA1 /* NT transact secondary */
-#define SMBntcreateX 0xA2 /* NT create and X */
-#define SMBntcancel 0xA4 /* NT cancel */
-
-/* These are the TRANS2 sub commands */
-#define TRANSACT2_OPEN 0
-#define TRANSACT2_FINDFIRST 1
-#define TRANSACT2_FINDNEXT 2
-#define TRANSACT2_QFSINFO 3
-#define TRANSACT2_SETFSINFO 4
-#define TRANSACT2_QPATHINFO 5
-#define TRANSACT2_SETPATHINFO 6
-#define TRANSACT2_QFILEINFO 7
-#define TRANSACT2_SETFILEINFO 8
-#define TRANSACT2_FSCTL 9
-#define TRANSACT2_IOCTL 0xA
-#define TRANSACT2_FINDNOTIFYFIRST 0xB
-#define TRANSACT2_FINDNOTIFYNEXT 0xC
-#define TRANSACT2_MKDIR 0xD
-#define TRANSACT2_SESSION_SETUP 0xE
-#define TRANSACT2_GET_DFS_REFERRAL 0x10
-#define TRANSACT2_REPORT_DFS_INCONSISTANCY 0x11
-
-/* These are the NT transact sub commands. */
-#define NT_TRANSACT_CREATE 1
-#define NT_TRANSACT_IOCTL 2
-#define NT_TRANSACT_SET_SECURITY_DESC 3
-#define NT_TRANSACT_NOTIFY_CHANGE 4
-#define NT_TRANSACT_RENAME 5
-#define NT_TRANSACT_QUERY_SECURITY_DESC 6
-
-/* these are the trans2 sub fields for primary requests */
-#define smb_tpscnt smb_vwv0
-#define smb_tdscnt smb_vwv1
-#define smb_mprcnt smb_vwv2
-#define smb_mdrcnt smb_vwv3
-#define smb_msrcnt smb_vwv4
-#define smb_flags smb_vwv5
-#define smb_timeout smb_vwv6
-#define smb_pscnt smb_vwv9
-#define smb_psoff smb_vwv10
-#define smb_dscnt smb_vwv11
-#define smb_dsoff smb_vwv12
-#define smb_suwcnt smb_vwv13
-#define smb_setup smb_vwv14
-#define smb_setup0 smb_setup
-#define smb_setup1 (smb_setup+2)
-#define smb_setup2 (smb_setup+4)
-
-/* these are for the secondary requests */
-#define smb_spscnt smb_vwv2
-#define smb_spsoff smb_vwv3
-#define smb_spsdisp smb_vwv4
-#define smb_sdscnt smb_vwv5
-#define smb_sdsoff smb_vwv6
-#define smb_sdsdisp smb_vwv7
-#define smb_sfid smb_vwv8
-
-/* and these for responses */
-#define smb_tprcnt smb_vwv0
-#define smb_tdrcnt smb_vwv1
-#define smb_prcnt smb_vwv3
-#define smb_proff smb_vwv4
-#define smb_prdisp smb_vwv5
-#define smb_drcnt smb_vwv6
-#define smb_droff smb_vwv7
-#define smb_drdisp smb_vwv8
-
-/* where to find the base of the SMB packet proper */
-#define smb_base(buf) (((char *)(buf))+4)
-
-
-#define SUCCESS 0 /* The request was successful. */
-#define ERRDOS 0x01 /* Error is from the core DOS operating system set. */
-#define ERRSRV 0x02 /* Error is generated by the server network file manager.*/
-#define ERRHRD 0x03 /* Error is an hardware error. */
-#define ERRCMD 0xFF /* Command was not in the "SMB" format. */
-
-#ifdef __STDC__
-int Debug1(char *, ...);
-#else
-int Debug1();
-#endif
-
-#ifdef DFS_AUTH
-void dfs_unlogin(void);
-extern int dcelogin_atmost_once;
-#endif
-
-#if AJT
-void ajt_panic(void);
-#endif
-
-#ifdef NOSTRDUP
-char *strdup(char *s);
-#endif
-
-#ifdef REPLACE_STRLEN
-int Strlen(char *);
-#endif
-
-#ifdef REPLACE_STRSTR
-char *Strstr(char *s, char *p);
-#endif
-
-#ifndef MIN
-#define MIN(a,b) ((a)<(b)?(a):(b))
-#endif
-#ifndef MAX
-#define MAX(a,b) ((a)>(b)?(a):(b))
-#endif
-
-#ifndef ABS
-#define ABS(a) ((a)>0?(a):(-(a)))
-#endif
-
-#ifndef SIGNAL_CAST
-#define SIGNAL_CAST
-#endif
-
-#ifndef SELECT_CAST
-#define SELECT_CAST
-#endif
-
-
-/* Some POSIX definitions for those without */
-
-#ifndef S_IFDIR
-#define S_IFDIR 0x4000
-#endif
-#ifndef S_ISDIR
-#define S_ISDIR(mode) ((mode & 0xF000) == S_IFDIR)
-#endif
-#ifndef S_IRWXU
-#define S_IRWXU 00700 /* read, write, execute: owner */
-#endif
-#ifndef S_IRUSR
-#define S_IRUSR 00400 /* read permission: owner */
-#endif
-#ifndef S_IWUSR
-#define S_IWUSR 00200 /* write permission: owner */
-#endif
-#ifndef S_IXUSR
-#define S_IXUSR 00100 /* execute permission: owner */
-#endif
-#ifndef S_IRWXG
-#define S_IRWXG 00070 /* read, write, execute: group */
-#endif
-#ifndef S_IRGRP
-#define S_IRGRP 00040 /* read permission: group */
-#endif
-#ifndef S_IWGRP
-#define S_IWGRP 00020 /* write permission: group */
-#endif
-#ifndef S_IXGRP
-#define S_IXGRP 00010 /* execute permission: group */
-#endif
-#ifndef S_IRWXO
-#define S_IRWXO 00007 /* read, write, execute: other */
-#endif
-#ifndef S_IROTH
-#define S_IROTH 00004 /* read permission: other */
-#endif
-#ifndef S_IWOTH
-#define S_IWOTH 00002 /* write permission: other */
-#endif
-#ifndef S_IXOTH
-#define S_IXOTH 00001 /* execute permission: other */
-#endif
-
-
-/* these are used in NetServerEnum to choose what to receive */
-#define SV_TYPE_WORKSTATION 0x00000001
-#define SV_TYPE_SERVER 0x00000002
-#define SV_TYPE_SQLSERVER 0x00000004
-#define SV_TYPE_DOMAIN_CTRL 0x00000008
-#define SV_TYPE_DOMAIN_BAKCTRL 0x00000010
-#define SV_TYPE_TIME_SOURCE 0x00000020
-#define SV_TYPE_AFP 0x00000040
-#define SV_TYPE_NOVELL 0x00000080
-#define SV_TYPE_DOMAIN_MEMBER 0x00000100
-#define SV_TYPE_PRINTQ_SERVER 0x00000200
-#define SV_TYPE_DIALIN_SERVER 0x00000400
-#define SV_TYPE_SERVER_UNIX 0x00000800
-#define SV_TYPE_NT 0x00001000
-#define SV_TYPE_WFW 0x00002000
-#define SV_TYPE_SERVER_MFPN 0x00004000
-#define SV_TYPE_SERVER_NT 0x00008000
-#define SV_TYPE_POTENTIAL_BROWSER 0x00010000
-#define SV_TYPE_BACKUP_BROWSER 0x00020000
-#define SV_TYPE_MASTER_BROWSER 0x00040000
-#define SV_TYPE_DOMAIN_MASTER 0x00080000
-#define SV_TYPE_SERVER_OSF 0x00100000
-#define SV_TYPE_SERVER_VMS 0x00200000
-#define SV_TYPE_WIN95_PLUS 0x00400000
-#define SV_TYPE_ALTERNATE_XPORT 0x20000000
-#define SV_TYPE_LOCAL_LIST_ONLY 0x40000000
-#define SV_TYPE_DOMAIN_ENUM 0x80000000
-#define SV_TYPE_ALL 0xFFFFFFFF
-
-/* what server type are we currently - JHT Says we ARE 4.20 */
-/* this was set by JHT in liaison with Jeremy Allison early 1997 */
-/* setting to 4.20 at same time as announcing ourselves as NT Server */
-/* History: */
-/* Version 4.0 - never made public */
-/* Version 4.10 - New to 1.9.16p2, lost in space 1.9.16p3 to 1.9.16p9 */
-/* - Reappeared in 1.9.16p11 with fixed smbd services */
-/* Version 4.20 - To indicate that nmbd and browsing now works better */
-
-#define DEFAULT_MAJOR_VERSION 0x04
-#define DEFAULT_MINOR_VERSION 0x02
-
-/* Browser Election Values */
-#define BROWSER_ELECTION_VERSION 0x010f
-#define BROWSER_CONSTANT 0xaa55
-
-
-/* Capabilities. see ftp.microsoft.com/developr/drg/cifs/cifs/cifs4.txt */
-
-#define CAP_RAW_MODE 0x0001
-#define CAP_MPX_MODE 0x0002
-#define CAP_UNICODE 0x0004
-#define CAP_LARGE_FILES 0x0008
-#define CAP_NT_SMBS 0x0010
-#define CAP_RPC_REMOTE_APIS 0x0020
-#define CAP_STATUS32 0x0040
-#define CAP_LEVEL_II_OPLOCKS 0x0080
-#define CAP_LOCK_AND_READ 0x0100
-#define CAP_NT_FIND 0x0200
-#define CAP_DFS 0x1000
-#define CAP_LARGE_READX 0x4000
-
-/* protocol types. It assumes that higher protocols include lower protocols
- as subsets */
-enum protocol_types {PROTOCOL_NONE,PROTOCOL_CORE,PROTOCOL_COREPLUS,PROTOCOL_LANMAN1,PROTOCOL_LANMAN2,PROTOCOL_NT1};
-
-/* security levels */
-enum security_types {SEC_SHARE,SEC_USER,SEC_SERVER};
-
-/* printing types */
-enum printing_types {PRINT_BSD,PRINT_SYSV,PRINT_AIX,PRINT_HPUX,
- PRINT_QNX,PRINT_PLP,PRINT_LPRNG};
-
-/* Remote architectures we know about. */
-enum remote_arch_types {RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT, RA_SAMBA};
-
-/* case handling */
-enum case_handling {CASE_LOWER,CASE_UPPER};
-
-
-/* Macros to get at offsets within smb_lkrng and smb_unlkrng
- structures. We cannot define these as actual structures
- due to possible differences in structure packing
- on different machines/compilers. */
-
-#define SMB_LPID_OFFSET(indx) (10 * (indx))
-#define SMB_LKOFF_OFFSET(indx) ( 2 + (10 * (indx)))
-#define SMB_LKLEN_OFFSET(indx) ( 6 + (10 * (indx)))
-
-/* Macro to cache an error in a write_bmpx_struct */
-#define CACHE_ERROR(w,c,e) ((w)->wr_errclass = (c), (w)->wr_error = (e), \
- w->wr_discard = True, -1)
-/* Macro to test if an error has been cached for this fnum */
-#define HAS_CACHED_ERROR(fnum) (Files[(fnum)].open && \
- Files[(fnum)].wbmpx_ptr && \
- Files[(fnum)].wbmpx_ptr->wr_discard)
-/* Macro to turn the cached error into an error packet */
-#define CACHED_ERROR(fnum) cached_error_packet(inbuf,outbuf,fnum,__LINE__)
-
-/* these are the datagram types */
-#define DGRAM_DIRECT_UNIQUE 0x10
-
-#define ERROR(class,x) error_packet(inbuf,outbuf,class,x,__LINE__)
-
-/* this is how errors are generated */
-#define UNIXERROR(defclass,deferror) unix_error_packet(inbuf,outbuf,defclass,deferror,__LINE__)
-
-#define ROUNDUP(x,g) (((x)+((g)-1))&~((g)-1))
-
-/*
- * Global value meaing that the smb_uid field should be
- * ingored (in share level security and protocol level == CORE)
- */
-
-#define UID_FIELD_INVALID 0
-#define VUID_OFFSET 100 /* Amount to bias returned vuid numbers */
-
-#endif
-
-/* Defines needed for multi-codepage support. */
-#define KANJI_CODEPAGE 932
-
-#ifdef KANJI
-/*
- * Default client code page - Japanese
- */
-#define DEFAULT_CLIENT_CODE_PAGE KANJI_CODEPAGE
-#else /* KANJI */
-/*
- * Default client code page - 850 - Western European
- */
-#define DEFAULT_CLIENT_CODE_PAGE 850
-#endif /* KANJI */
-
-/*
- * Size of buffer to use when moving files across filesystems.
- */
-#define COPYBUF_SIZE (8*1024)
-
-/*
- * Integers used to override error codes.
- */
-extern int unix_ERR_class;
-extern int unix_ERR_code;
-
-/*
- * Map the Core and Extended Oplock requesst bits down
- * to common bits (EXCLUSIVE_OPLOCK & BATCH_OPLOCK).
- */
-
-/*
- * Core protocol.
- */
-#define CORE_OPLOCK_REQUEST(inbuf) (((CVAL(inbuf,smb_flg)|(1<<5))>>5) | \
- ((CVAL(inbuf,smb_flg)|(1<<6))>>5))
-
-/*
- * Extended protocol.
- */
-#define EXTENDED_OPLOCK_REQUEST(inbuf) (((SVAL(inbuf,smb_vwv2)|(1<<1))>>1) | \
- ((SVAL(inbuf,smb_vwv2)|(1<<2))>>1))
-
-/* Lock types. */
-#define LOCKING_ANDX_SHARED_LOCK 0x1
-#define LOCKING_ANDX_OPLOCK_RELEASE 0x2
-#define LOCKING_ANDX_CHANGE_LOCKTYPE 0x4
-#define LOCKING_ANDX_CANCEL_LOCK 0x8
-#define LOCKING_ANDX_LARGE_FILES 0x10
-
-/* Oplock levels */
-#define OPLOCKLEVEL_NONE 0
-#define OPLOCKLEVEL_II 1
-
-/*
- * Bits we test with.
- */
-#define EXCLUSIVE_OPLOCK 1
-#define BATCH_OPLOCK 2
-
-#define CORE_OPLOCK_GRANTED (1<<5)
-#define EXTENDED_OPLOCK_GRANTED (1<<15)
-
-/*
- * Loopback command offsets.
- */
-
-#define UDP_CMD_LEN_OFFSET 0
-#define UDP_CMD_PORT_OFFSET 4
-#define UDP_CMD_HEADER_LEN 6
-
-#define UDP_MESSAGE_CMD_OFFSET 0
-
-/*
- * Oplock break command code to send over the udp socket.
- *
- * Form of this is :
- *
- * 0 2 6 10 14 18 22
- * +----+--------+--------+--------+-------+--------+
- * | cmd| pid | dev | inode | sec | usec |
- * +----+--------+--------+--------+-------+--------+
- */
-
-#define OPLOCK_BREAK_CMD 0x1
-#define OPLOCK_BREAK_PID_OFFSET 2
-#define OPLOCK_BREAK_DEV_OFFSET 6
-#define OPLOCK_BREAK_INODE_OFFSET 10
-#define OPLOCK_BREAK_SEC_OFFSET 14
-#define OPLOCK_BREAK_USEC_OFFSET 18
-#define OPLOCK_BREAK_MSG_LEN 22
-
-
-#define CMD_REPLY 0x8000
-
-/* _SMB_H */
diff --git a/source/include/trans2.h b/source/include/trans2.h
deleted file mode 100644
index 9a2de631095..00000000000
--- a/source/include/trans2.h
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- SMB transaction2 handling
- Copyright (C) Jeremy Allison 1994-1997
-
- Extensively modified by Andrew Tridgell, 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 _TRANS2_H_
-#define _TRANS2_H_
-
-/* Define the structures needed for the trans2 calls. */
-
-/*******************************************************
- For DosFindFirst/DosFindNext - level 1
-
-MAXFILENAMELEN = 255;
-FDATE == uint16
-FTIME == uint16
-ULONG == uint32
-USHORT == uint16
-
-typedef struct _FILEFINDBUF {
-Byte offset Type name description
--------------+-------+-------------------+--------------
-0 FDATE fdateCreation;
-2 FTIME ftimeCreation;
-4 FDATE fdateLastAccess;
-6 FTIME ftimeLastAccess;
-8 FDATE fdateLastWrite;
-10 FTIME ftimeLastWrite;
-12 ULONG cbFile file length in bytes
-16 ULONG cbFileAlloc size of file allocation unit
-20 USHORT attrFile
-22 UCHAR cchName length of name to follow (not including zero)
-23 UCHAR achName[MAXFILENAMELEN]; Null terminated name
-} FILEFINDBUF;
-*********************************************************/
-
-#define l1_fdateCreation 0
-#define l1_fdateLastAccess 4
-#define l1_fdateLastWrite 8
-#define l1_cbFile 12
-#define l1_cbFileAlloc 16
-#define l1_attrFile 20
-#define l1_cchName 22
-#define l1_achName 23
-
-/**********************************************************
-For DosFindFirst/DosFindNext - level 2
-
-typedef struct _FILEFINDBUF2 {
-Byte offset Type name description
--------------+-------+-------------------+--------------
-0 FDATE fdateCreation;
-2 FTIME ftimeCreation;
-4 FDATE fdateLastAccess;
-6 FTIME ftimeLastAccess;
-8 FDATE fdateLastWrite;
-10 FTIME ftimeLastWrite;
-12 ULONG cbFile file length in bytes
-16 ULONG cbFileAlloc size of file allocation unit
-20 USHORT attrFile
-22 ULONG cbList Extended attribute list (always 0)
-26 UCHAR cchName length of name to follow (not including zero)
-27 UCHAR achName[MAXFILENAMELEN]; Null terminated name
-} FILEFINDBUF2;
-*************************************************************/
-
-#define l2_fdateCreation 0
-#define l2_fdateLastAccess 4
-#define l2_fdateLastWrite 8
-#define l2_cbFile 12
-#define l2_cbFileAlloc 16
-#define l2_attrFile 20
-#define l2_cbList 22
-#define l2_cchName 26
-#define l2_achName 27
-
-
-/**********************************************************
-For DosFindFirst/DosFindNext - level 260
-
-typedef struct _FILEFINDBUF260 {
-Byte offset Type name description
--------------+-------+-------------------+--------------
-0 ULONG NextEntryOffset;
-4 ULONG FileIndex;
-8 LARGE_INTEGER CreationTime;
-16 LARGE_INTEGER LastAccessTime;
-24 LARGE_INTEGER LastWriteTime;
-32 LARGE_INTEGER ChangeTime;
-40 LARGE_INTEGER EndOfFile;
-48 LARGE_INTEGER AllocationSize;
-56 ULONG FileAttributes;
-60 ULONG FileNameLength;
-64 ULONG EaSize;
-68 CHAR ShortNameLength;
-70 UNICODE ShortName[12];
-94 UNICODE FileName[];
-*************************************************************/
-
-#define l260_achName 94
-
-
-/**********************************************************
-For DosQueryPathInfo/DosQueryFileInfo/DosSetPathInfo/
-DosSetFileInfo - level 1
-
-typedef struct _FILESTATUS {
-Byte offset Type name description
--------------+-------+-------------------+--------------
-0 FDATE fdateCreation;
-2 FTIME ftimeCreation;
-4 FDATE fdateLastAccess;
-6 FTIME ftimeLastAccess;
-8 FDATE fdateLastWrite;
-10 FTIME ftimeLastWrite;
-12 ULONG cbFile file length in bytes
-16 ULONG cbFileAlloc size of file allocation unit
-20 USHORT attrFile
-} FILESTATUS;
-*************************************************************/
-
-/* Use the l1_ defines from DosFindFirst */
-
-/**********************************************************
-For DosQueryPathInfo/DosQueryFileInfo/DosSetPathInfo/
-DosSetFileInfo - level 2
-
-typedef struct _FILESTATUS2 {
-Byte offset Type name description
--------------+-------+-------------------+--------------
-0 FDATE fdateCreation;
-2 FTIME ftimeCreation;
-4 FDATE fdateLastAccess;
-6 FTIME ftimeLastAccess;
-8 FDATE fdateLastWrite;
-10 FTIME ftimeLastWrite;
-12 ULONG cbFile file length in bytes
-16 ULONG cbFileAlloc size of file allocation unit
-20 USHORT attrFile
-22 ULONG cbList Length of EA's (0)
-} FILESTATUS2;
-*************************************************************/
-
-/* Use the l2_ #defines from DosFindFirst */
-
-/**********************************************************
-For DosQFSInfo/DosSetFSInfo - level 1
-
-typedef struct _FSALLOCATE {
-Byte offset Type name description
--------------+-------+-------------------+--------------
-0 ULONG idFileSystem id of file system
-4 ULONG cSectorUnit number of sectors per allocation unit
-8 ULONG cUnit number of allocation units
-12 ULONG cUnitAvail Available allocation units
-16 USHORT cbSector bytes per sector
-} FSALLOCATE;
-*************************************************************/
-
-#define l1_idFileSystem 0
-#define l1_cSectorUnit 4
-#define l1_cUnit 8
-#define l1_cUnitAvail 12
-#define l1_cbSector 16
-
-/**********************************************************
-For DosQFSInfo/DosSetFSInfo - level 2
-
-typedef struct _FSINFO {
-Byte offset Type name description
--------------+-------+-------------------+--------------
-0 FDATE vol_fdateCreation
-2 FTIME vol_ftimeCreation
-4 UCHAR vol_cch length of volume name (excluding NULL)
-5 UCHAR vol_szVolLabel[12] volume name
-} FSINFO;
-*************************************************************/
-
-#define SMB_INFO_STANDARD 1
-#define SMB_INFO_QUERY_EA_SIZE 2
-#define SMB_INFO_QUERY_EAS_FROM_LIST 3
-#define SMB_INFO_QUERY_ALL_EAS 4
-#define SMB_INFO_IS_NAME_VALID 6
-#define SMB_QUERY_FS_LABEL_INFO 0x101
-#define SMB_QUERY_FS_VOLUME_INFO 0x102
-#define SMB_QUERY_FS_SIZE_INFO 0x103
-#define SMB_QUERY_FS_DEVICE_INFO 0x104
-#define SMB_QUERY_FS_ATTRIBUTE_INFO 0x105
-
-
-#define l2_vol_fdateCreation 0
-#define l2_vol_cch 4
-#define l2_vol_szVolLabel 5
-
-
-#define SMB_QUERY_FILE_BASIC_INFO 0x101
-#define SMB_QUERY_FILE_STANDARD_INFO 0x102
-#define SMB_QUERY_FILE_EA_INFO 0x103
-#define SMB_QUERY_FILE_NAME_INFO 0x104
-#define SMB_QUERY_FILE_ALLOCATION_INFO 0x105
-#define SMB_QUERY_FILE_END_OF_FILEINFO 0x106
-#define SMB_QUERY_FILE_ALL_INFO 0x107
-#define SMB_QUERY_FILE_ALT_NAME_INFO 0x108
-#define SMB_QUERY_FILE_STREAM_INFO 0x109
-
-#define SMB_FIND_FILE_DIRECTORY_INFO 0x101
-#define SMB_FIND_FILE_FULL_DIRECTORY_INFO 0x102
-#define SMB_FIND_FILE_NAMES_INFO 0x103
-#define SMB_FIND_FILE_BOTH_DIRECTORY_INFO 0x104
-
-#define SMB_SET_FILE_BASIC_INFO 0x101
-#define SMB_SET_FILE_DISPOSITION_INFO 0x102
-#define SMB_SET_FILE_ALLOCATION_INFO 0x103
-#define SMB_SET_FILE_END_OF_FILE_INFO 0x104
-
-#define DIRLEN_GUESS (45+MAX(l1_achName,l2_achName))
-
-/* NT uses a FILE_ATTRIBUTE_NORMAL when no other attributes
- are set. */
-
-#define NT_FILE_ATTRIBUTE_NORMAL 0x80
-
-/* Function prototypes */
-
-
-int reply_findnclose(char *inbuf,char *outbuf,int length,int bufsize);
-
-int reply_findclose(char *inbuf,char *outbuf,int length,int bufsize);
-
-#endif
-
-
-
diff --git a/source/include/version.h b/source/include/version.h
deleted file mode 100644
index 33c9d240baf..00000000000
--- a/source/include/version.h
+++ /dev/null
@@ -1 +0,0 @@
-#define VERSION "1.9.18alpha1"
diff --git a/source/include/vt_mode.h b/source/include/vt_mode.h
deleted file mode 100644
index 85b481122ee..00000000000
--- a/source/include/vt_mode.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* vt_mode.h */
-/*
-support vtp-sessions
-
-written by Christian A. Lademann <cal@zls.com>
-*/
-
-/*
-02.05.95:cal:ported to samba-1.9.13
-*/
-
-#ifndef __vt_mode_h__
-# define __vt_mode_h__
-
-# define VT_CLOSED 0
-# define VT_OPEN 1
-
-# define MS_NONE 0
-# define MS_PTY 1
-# define MS_STREAM 2
-# define MS_VTY 3
-
-# define VT_MAXREAD 32
-
-
-# undef EXTERN
-
-# ifndef __vt_mode_c__
-# define EXTERN extern
-# define DEFAULT(v)
-# else
-# define EXTERN
-# define DEFAULT(v) =(v)
-# endif
-
- EXTERN int VT_Status DEFAULT(VT_CLOSED),
- VT_Fd DEFAULT(-1),
- VT_ChildPID DEFAULT(-1);
-
- EXTERN BOOL VT_Mode DEFAULT(False),
- VT_ChildDied DEFAULT(False);
-
- EXTERN char *VT_Line DEFAULT(NULL);
-
-# undef EXTERN
-
-
-#endif /* __vt_mode_h__ */
diff --git a/source/internals.doc b/source/internals.doc
deleted file mode 100644
index 971f2567388..00000000000
--- a/source/internals.doc
+++ /dev/null
@@ -1,212 +0,0 @@
-internals.txt, 8 May 1996
-Written by David Chappell <David.Chappell@mail.trincoll.edu>.
-
-This document describes some of the internal functions which must be
-understood by anyone wishing to add features to Samba.
-
-
-
-
-
-=============================================================================
-This section describes the macros defined in byteorder.h. These macros
-are used extensively in the Samba code.
-
------------------------------------------------------------------------------
-CVAL(buf,pos)
-
-returns the byte at offset pos within buffer buf as an unsigned character.
-
------------------------------------------------------------------------------
-PVAL(buf,pos)
-
-returns the value of CVAL(buf,pos) cast to type unsigned integer.
-
------------------------------------------------------------------------------
-SCVAL(buf,pos,val)
-
-sets the byte at offset pos within buffer buf to value val.
-
------------------------------------------------------------------------------
-SVAL(buf,pos)
-
-returns the value of the unsigned short (16 bit) little-endian integer at
-offset pos within buffer buf. An integer of this type is sometimes
-refered to as "USHORT".
-
------------------------------------------------------------------------------
-IVAL(buf,pos)
-
-returns the value of the unsigned 32 bit little-endian integer at offset
-pos within buffer buf.
-
------------------------------------------------------------------------------
-SVALS(buf,pos)
-
-returns the value of the signed short (16 bit) little-endian integer at
-offset pos within buffer buf.
-
------------------------------------------------------------------------------
-IVALS(buf,pos)
-
-returns the value of the signed 32 bit little-endian integer at offset pos
-within buffer buf.
-
------------------------------------------------------------------------------
-SSVAL(buf,pos,val)
-
-sets the unsigned short (16 bit) little-endian integer at offset pos within
-buffer buf to value val.
-
------------------------------------------------------------------------------
-SIVAL(buf,pos,val)
-
-sets the unsigned 32 bit little-endian integer at offset pos within buffer
-buf to the value val.
-
------------------------------------------------------------------------------
-SSVALS(buf,pos,val)
-
-sets the short (16 bit) signed little-endian integer at offset pos within
-buffer buf to the value val.
-
------------------------------------------------------------------------------
-SIVALS(buf,pos,val)
-
-sets the signed 32 bit little-endian integer at offset pos withing buffer
-buf to the value val.
-
------------------------------------------------------------------------------
-RSVAL(buf,pos)
-
-returns the value of the unsigned short (16 bit) big-endian integer at
-offset pos within buffer buf.
-
------------------------------------------------------------------------------
-RIVAL(buf,pos)
-
-returns the value of the unsigned 32 bit big-endian integer at offset
-pos within buffer buf.
-
------------------------------------------------------------------------------
-RSSVAL(buf,pos,val)
-
-sets the value of the unsigned short (16 bit) big-endian integer at
-offset pos within buffer buf to value val.
-refered to as "USHORT".
-
------------------------------------------------------------------------------
-RSIVAL(buf,pos,val)
-
-sets the value of the unsigned 32 bit big-endian integer at offset
-pos within buffer buf to value val.
-
-
-
-
-
-=============================================================================
-This section describes the functions need to make a LAN Manager RPC call.
-This information had been obtained by examining the Samba code and the LAN
-Manager 2.0 API documentation. It should not be considered entirely
-reliable.
-
------------------------------------------------------------------------------
-call_api(int prcnt, int drcnt, int mprcnt, int mdrcnt,
- char *param, char *data, char **rparam, char **rdata);
-
-This function is defined in client.c. It uses an SMB transaction to call a
-remote api.
-
-The parameters are as follows:
-
-prcnt: the number of bytes of parameters begin sent.
-drcnt: the number of bytes of data begin sent.
-mprcnt: the maximum number of bytes of parameters which should be returned
-mdrcnt: the maximum number of bytes of data which should be returned
-param: a pointer to the parameters to be sent.
-data: a pointer to the data to be sent.
-rparam: a pointer to a pointer which will be set to point to the returned
- paramters. The caller of call_api() must deallocate this memory.
-rdata: a pointer to a pointer which will be set to point to the returned
- data. The caller of call_api() must deallocate this memory.
-
------------------------------------------------------------------------------
-These are the parameters which you ought to send, in the order of their
-appearance in the parameter block:
-
-* An unsigned 16 bit integer API number. You should set this value with
-SSVAL(). I do not know where these numbers are described.
-
-* An ASCIIZ string describing the parameters to the API function as defined
-in the LAN Manager documentation. The first parameter, which is the server
-name, is ommited. This string is based uppon the API function as described
-in the manual, not the data which is actually passed.
-
-* An ASCIIZ string describing the data structure which ought to be returned.
-
-* Any parameters which appear in the function call, as defined in the LAN
-Manager API documentation, after the "Server" and up to and including the
-"uLevel" parameters.
-
-* An unsigned 16 bit integer which gives the size in bytes of the buffer we
-will use to receive the returned array of data structures. Presumably this
-should be the same as mdrcnt. This value should be set with SSVAL().
-
-* An ASCIIZ string describing substructures which should be returned. If no
-substructures apply, this string is of zero length.
-
------------------------------------------------------------------------------
-The code in client.c always calls call_api() with no data. It is unclear
-when a non-zero length data buffer would be sent.
-
------------------------------------------------------------------------------
-The returned parameters (pointed to by rparam), in their order of appearance
-are:
-
-* An unsigned 16 bit integer which contains the API function's return code.
-This value should be read with SVAL().
-
-* An adjustment which tells the amount by which pointers in the returned
-data should be adjusted. This value should be read with SVAL(). Basically,
-the address of the start of the returned data buffer should have the returned
-pointer value added to it and then have this value subtracted from it in
-order to obtain the currect offset into the returned data buffer.
-
-* A count of the number of elements in the array of structures returned.
-It is also possible that this may sometimes be the number of bytes returned.
-
------------------------------------------------------------------------------
-When call_api() returns, rparam points to the returned parameters. The
-first if these is the result code. It will be zero if the API call
-suceeded. This value by be read with "SVAL(rparam,0)".
-
-The second parameter may be read as "SVAL(rparam,2)". It is a 16 bit offset
-which indicates what the base address of the returned data buffer was when
-it was built on the server. It should be used to correct pointer before
-use.
-
-The returned data buffer contains the array of returned data structures.
-Note that all pointers must be adjusted before use. The function
-fix_char_ptr() in client.c can be used for this purpose.
-
-The third parameter (which may be read as "SVAL(rparam,4)") has something to
-do with indicating the amount of data returned or possibly the amount of
-data which can be returned if enough buffer space is allowed.
-
------------------------------------------------------------------------------
-Certain data structures are described by means of ASCIIz strings containing
-code characters. These are the code characters:
-
-W a type byte little-endian unsigned integer
-N a count of substructures which follow
-D a four byte little-endian unsigned integer
-B a byte (with optional count expressed as trailing ASCII digits)
-z a four byte offset to a NULL terminated string
-l a four byte offset to non-string user data
-b an offset to data (with count expressed as trailing ASCII digits)
-r pointer to returned data buffer???
-L length in bytes of returned data buffer???
-h number of bytes of information available???
-
-----------------------------------------------------------------------------
diff --git a/source/lib/access.c b/source/lib/access.c
deleted file mode 100644
index c338517ed67..00000000000
--- a/source/lib/access.c
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
-This module is an adaption of code from the tcpd-1.4 package written
-by Wietse Venema, Eindhoven University of Technology, The Netherlands.
-
-The code is used here with permission.
-
-The code has been considerably changed from the original. Bug reports
-should be sent to samba-bugs@samba.anu.edu.au
-*/
-
-#include "includes.h"
-
-#define ALLOW_PURE_ADDRESSES
-
-extern int DEBUGLEVEL;
-
-#ifndef INADDR_NONE
-#define INADDR_NONE ((uint32)~0)
-#endif
-
-
-#define Good True
-#define Bad False
-
-#define CLIENT_MATCH client_match
-
-/* Delimiters for lists of daemons or clients. */
-
-static char sep[] = ", \t";
-
-/* Constants to be used in assignments only, not in comparisons... */
-
-#define YES 1
-#define NO 0
-#define FAIL (-1)
-
-/* Forward declarations. */
-static int list_match(char *list,char *item, int (*match_fn)());
-static int client_match(char *tok,char *item);
-static int string_match(char *tok,char *s);
-static int masked_match(char *tok, char *slash, char *s);
-
-/* Size of logical line buffer. */
-#define BUFLEN 2048
-
-/* return true if access should be allowed to a service*/
-BOOL check_access(int snum)
-{
- char *denyl,*allowl;
- BOOL ret = False;
-
- denyl = lp_hostsdeny(snum);
- if (denyl) denyl = strdup(denyl);
-
- allowl = lp_hostsallow(snum);
- if (allowl) allowl = strdup(allowl);
-
- if ((!denyl || *denyl==0) && (!allowl || *allowl==0))
- ret = True;
-
- if (!ret)
- {
- if (allow_access(denyl,allowl,client_name(),client_addr()))
- {
- if (snum >= 0)
- DEBUG(2,("Allowed connection from %s (%s) to %s\n",
- client_name(),client_addr(),
- lp_servicename(snum)));
- ret = True;
- }
- else
- if (snum >= 0)
- DEBUG(0,("%s Denied connection from %s (%s) to %s\n",
- timestring(), client_name(),client_addr(),
- lp_servicename(snum)));
- }
-
- if (denyl) free(denyl);
- if (allowl) free(allowl);
- return(ret);
-}
-
-
-/* return true if access should be allowed */
-BOOL allow_access(char *deny_list,char *allow_list,char *cname,char *caddr)
-{
- char *client[2];
-
- client[0] = cname;
- client[1] = caddr;
-
- /* if theres no deny list and no allow list then allow access */
- if ((!deny_list || *deny_list == 0) && (!allow_list || *allow_list == 0))
- return(True);
-
- /* if there is an allow list but no deny list then allow only hosts
- on the allow list */
- if (!deny_list || *deny_list == 0)
- return(list_match(allow_list,(char *)client,CLIENT_MATCH));
-
- /* if theres a deny list but no allow list then allow
- all hosts not on the deny list */
- if (!allow_list || *allow_list == 0)
- return(!list_match(deny_list,(char *)client,CLIENT_MATCH));
-
- /* if there are both type of list then allow all hosts on the allow list */
- if (list_match(allow_list,(char *)client,CLIENT_MATCH))
- return (True);
-
- /* if there are both type of list and it's not on the allow then
- allow it if its not on the deny */
- if (list_match(deny_list,(char *)client,CLIENT_MATCH))
- return (False);
-
- return (True);
-}
-
-/* list_match - match an item against a list of tokens with exceptions */
-/* (All modifications are marked with the initials "jkf") */
-static int list_match(char *list,char *item, int (*match_fn)())
-{
- char *tok;
- char *listcopy; /* jkf */
- int match = NO;
-
- /*
- * jkf@soton.ac.uk -- 31 August 1994 -- Stop list_match()
- * overwriting the list given as its first parameter.
- */
-
- /* jkf -- can get called recursively with NULL list */
- listcopy = (list == 0) ? (char *)0 : strdup(list);
-
- /*
- * Process tokens one at a time. We have exhausted all possible matches
- * when we reach an "EXCEPT" token or the end of the list. If we do find
- * a match, look for an "EXCEPT" list and recurse to determine whether
- * the match is affected by any exceptions.
- */
-
- for (tok = strtok(listcopy, sep); tok ; tok = strtok(NULL, sep)) {
- if (strcasecmp(tok, "EXCEPT") == 0) /* EXCEPT: give up */
- break;
- if ((match = (*match_fn) (tok, item))) /* YES or FAIL */
- break;
- }
- /* Process exceptions to YES or FAIL matches. */
-
- if (match != NO) {
- while ((tok = strtok((char *) 0, sep)) && strcasecmp(tok, "EXCEPT"))
- /* VOID */ ;
- if (tok == 0 || list_match((char *) 0, item, match_fn) == NO) {
- if (listcopy != 0) free(listcopy); /* jkf */
- return (match);
- }
- }
-
- if (listcopy != 0) free(listcopy); /* jkf */
- return (NO);
-}
-
-
-/* client_match - match host name and address against token */
-static int client_match(char *tok,char *item)
-{
- char **client = (char **)item;
- int match;
-
- /*
- * Try to match the address first. If that fails, try to match the host
- * name if available.
- */
-
- if ((match = string_match(tok, client[1])) == 0)
- if (client[0][0] != 0)
- match = string_match(tok, client[0]);
- return (match);
-}
-
-/* string_match - match string against token */
-static int string_match(char *tok,char *s)
-{
- int tok_len;
- int str_len;
- char *cut;
-
- /*
- * Return YES if a token has the magic value "ALL". Return FAIL if the
- * token is "FAIL". If the token starts with a "." (domain name), return
- * YES if it matches the last fields of the string. If the token has the
- * magic value "LOCAL", return YES if the string does not contain a "."
- * character. If the token ends on a "." (network number), return YES if
- * it matches the first fields of the string. If the token begins with a
- * "@" (netgroup name), return YES if the string is a (host) member of
- * the netgroup. Return YES if the token fully matches the string. If the
- * token is a netnumber/netmask pair, return YES if the address is a
- * member of the specified subnet.
- */
-
- if (tok[0] == '.') { /* domain: match last fields */
- if ((str_len = strlen(s)) > (tok_len = strlen(tok))
- && strcasecmp(tok, s + str_len - tok_len) == 0)
- return (YES);
- } else if (tok[0] == '@') { /* netgroup: look it up */
-#ifdef NETGROUP
- static char *mydomain = NULL;
- char *hostname = NULL;
- BOOL netgroup_ok = False;
-
- if (!mydomain) yp_get_default_domain(&mydomain);
-
- if (!mydomain) {
- DEBUG(0,("Unable to get default yp domain.\n"));
- return NO;
- }
- if (!(hostname = strdup(s))) {
- DEBUG(1,("out of memory for strdup!\n"));
- return NO;
- }
-
- netgroup_ok = innetgr(tok + 1, hostname, (char *) 0, mydomain);
-
- DEBUG(5,("looking for %s of domain %s in netgroup %s gave %s\n",
- hostname,
- mydomain,
- tok+1,
- BOOLSTR(netgroup_ok)));
-
-#ifdef NETGROUP_INSECURE
- /* if you really want netgroups that match non qualified names
- then define NETGROUP_INSECURE. It can, however, be a big
- security hole */
- {
- char *clnt_domain;
- if (!netgroup_ok && (clnt_domain=strchr(hostname,'.'))) {
- *clnt_domain++ = '\0';
- netgroup_ok = innetgr(tok + 1, hostname, (char *) 0, mydomain);
- }
- }
-#endif
-
- free(hostname);
-
- if (netgroup_ok) return(YES);
-#else
- DEBUG(0,("access: netgroup support is not configured\n"));
- return (NO);
-#endif
- } else if (strcasecmp(tok, "ALL") == 0) { /* all: match any */
- return (YES);
- } else if (strcasecmp(tok, "FAIL") == 0) { /* fail: match any */
- return (FAIL);
- } else if (strcasecmp(tok, "LOCAL") == 0) { /* local: no dots */
- if (strchr(s, '.') == 0 && strcasecmp(s, "unknown") != 0)
- return (YES);
- } else if (!strcasecmp(tok, s)) { /* match host name or address */
- return (YES);
- } else if (tok[(tok_len = strlen(tok)) - 1] == '.') { /* network */
- if (strncmp(tok, s, tok_len) == 0)
- return (YES);
- } else if ((cut = strchr(tok, '/')) != 0) { /* netnumber/netmask */
- if (isdigit(s[0]) && masked_match(tok, cut, s))
- return (YES);
- }
- return (NO);
-}
-
-/* masked_match - match address against netnumber/netmask */
-static int masked_match(char *tok, char *slash, char *s)
-{
- uint32 net;
- uint32 mask;
- uint32 addr;
-
- if ((addr = interpret_addr(s)) == INADDR_NONE)
- return (NO);
- *slash = 0;
- net = interpret_addr(tok);
- *slash = '/';
- if (net == INADDR_NONE || (mask = interpret_addr(slash + 1)) == INADDR_NONE) {
- DEBUG(0,("access: bad net/mask access control: %s", tok));
- return (NO);
- }
- return ((addr & mask) == net);
-}
-
-
-
-
diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c
deleted file mode 100644
index a7dff4224be..00000000000
--- a/source/lib/charcnv.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Character set conversion Extensions
- Copyright (C) Andrew Tridgell 1992-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.
-
-*/
-#include "includes.h"
-#define CTRLZ 26
-extern int DEBUGLEVEL;
-
-static char cvtbuf[1024];
-
-static BOOL mapsinited = 0;
-
-static char unix2dos[256];
-static char dos2unix[256];
-
-static void initmaps() {
- int k;
-
- for (k = 0; k < 256; k++) unix2dos[k] = k;
- for (k = 0; k < 256; k++) dos2unix[k] = k;
-
- mapsinited = True;
-}
-
-static void update_map(char * str) {
- char *p;
-
- for (p = str; *p; p++) {
- if (p[1]) {
- unix2dos[(unsigned char)*p] = p[1];
- dos2unix[(unsigned char)p[1]] = *p;
- p++;
- }
- }
-}
-
-static void init_iso8859_1() {
-
- int i;
- if (!mapsinited) initmaps();
-
- /* Do not map undefined characters to some accidental code */
- for (i = 128; i < 256; i++)
- {
- unix2dos[i] = CTRLZ;
- dos2unix[i] = CTRLZ;
- }
-
-/* MSDOS Code Page 850 -> ISO-8859 */
-update_map("\240\377\241\255\242\275\243\234\244\317\245\276\246\335\247\365");
-update_map("\250\371\251\270\252\246\253\256\254\252\255\360\256\251\257\356");
-update_map("\260\370\261\361\262\375\263\374\264\357\265\346\266\364\267\372");
-update_map("\270\367\271\373\272\247\273\257\274\254\275\253\276\363\277\250");
-update_map("\300\267\301\265\302\266\303\307\304\216\305\217\306\222\307\200");
-update_map("\310\324\311\220\312\322\313\323\314\336\315\326\316\327\317\330");
-update_map("\320\321\321\245\322\343\323\340\324\342\325\345\326\231\327\236");
-update_map("\330\235\331\353\332\351\333\352\334\232\335\355\336\350\337\341");
-update_map("\340\205\341\240\342\203\343\306\344\204\345\206\346\221\347\207");
-update_map("\350\212\351\202\352\210\353\211\354\215\355\241\356\214\357\213");
-update_map("\360\320\361\244\362\225\363\242\364\223\365\344\366\224\367\366");
-update_map("\370\233\371\227\372\243\373\226\374\201\375\354\376\347\377\230");
-
-}
-
-/* Init for eastern european languages. May need more work ? */
-
-static void init_iso8859_2() {
-
- int i;
- if (!mapsinited) initmaps();
-
- /* Do not map undefined characters to some accidental code */
- for (i = 128; i < 256; i++)
- {
- unix2dos[i] = CTRLZ;
- dos2unix[i] = CTRLZ;
- }
-
-update_map("\241\244\306\217\312\250\243\235\321\343\323\340\246\227\254\215");
-update_map("\257\275\261\245\346\206\352\251\263\210\361\344\363\242\266\230");
-update_map("\274\253\277\276");
-}
-
-/*
- * Convert unix to dos
- */
-char *unix2dos_format(char *str,BOOL overwrite)
-{
- char *p;
- char *dp;
-
- if (!mapsinited) initmaps();
-
- if(lp_client_code_page() == KANJI_CODEPAGE)
- return (*_unix_to_dos)(str, overwrite);
- else {
- if (overwrite) {
- for (p = str; *p; p++) *p = unix2dos[(unsigned char)*p];
- return str;
- } else {
- for (p = str, dp = cvtbuf; *p; p++,dp++) *dp = unix2dos[(unsigned char)*p];
- *dp = 0;
- return cvtbuf;
- }
- }
-}
-
-/*
- * Convert dos to unix
- */
-char *dos2unix_format(char *str, BOOL overwrite)
-{
- char *p;
- char *dp;
-
- if (!mapsinited) initmaps();
-
- if(lp_client_code_page() == KANJI_CODEPAGE)
- return (*_dos_to_unix)(str, overwrite);
- else {
- if (overwrite) {
- for (p = str; *p; p++) *p = dos2unix[(unsigned char)*p];
- return str;
- } else {
- for (p = str, dp = cvtbuf; *p; p++,dp++) *dp = dos2unix[(unsigned char)*p];
- *dp = 0;
- return cvtbuf;
- }
- }
-}
-
-
-/*
- * Interpret character set.
- */
-int interpret_character_set(char *str, int def)
-{
-
- if (strequal (str, "iso8859-1")) {
- init_iso8859_1();
- } else if (strequal (str, "iso8859-2")) {
- init_iso8859_2();
- } else {
- DEBUG(0,("unrecognized character set\n"));
- }
- return def;
-}
diff --git a/source/lib/charset.c b/source/lib/charset.c
deleted file mode 100644
index 4869e09fecf..00000000000
--- a/source/lib/charset.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Character set handling
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-
-#define CHARSET_C
-#include "includes.h"
-
-extern int DEBUGLEVEL;
-
-/*
- * Codepage definitions.
- */
-
-#if !defined(KANJI)
-/* lower->upper mapping for IBM Code Page 850 - MS-DOS Latin 1 */
-unsigned char cp_850[][4] = {
-/* dec col/row oct hex description */
-/* 133 08/05 205 85 a grave */
-/* 183 11/07 267 B7 A grave */ {0x85,0xB7,1,1},
-/* 160 10/00 240 A0 a acute */
-/* 181 11/05 265 B5 A acute */ {0xA0,0xB5,1,1},
-/* 131 08/03 203 83 a circumflex */
-/* 182 11/06 266 B6 A circumflex */ {0x83,0xB6,1,1},
-/* 198 12/06 306 C6 a tilde */
-/* 199 12/07 307 C7 A tilde */ {0xC6,0xC7,1,1},
-/* 132 08/04 204 84 a diaeresis */
-/* 142 08/14 216 8E A diaeresis */ {0x84,0x8E,1,1},
-/* 134 08/06 206 86 a ring */
-/* 143 08/15 217 8F A ring */ {0x86,0x8F,1,1},
-/* 145 09/01 221 91 ae diphthong */
-/* 146 09/02 222 92 AE diphthong */ {0x91,0x92,1,1},
-/* 135 08/07 207 87 c cedilla */
-/* 128 08/00 200 80 C cedilla */ {0x87,0x80,1,1},
-/* 138 08/10 212 8A e grave */
-/* 212 13/04 324 D4 E grave */ {0x8A,0xD4,1,1},
-/* 130 08/02 202 82 e acute */
-/* 144 09/00 220 90 E acute */ {0x82,0x90,1,1},
-/* 136 08/08 210 88 e circumflex */
-/* 210 13/02 322 D2 E circumflex */ {0x88,0xD2,1,1},
-/* 137 08/09 211 89 e diaeresis */
-/* 211 13/03 323 D3 E diaeresis */ {0x89,0xD3,1,1},
-/* 141 08/13 215 8D i grave */
-/* 222 13/14 336 DE I grave */ {0x8D,0xDE,1,1},
-/* 161 10/01 241 A1 i acute */
-/* 214 13/06 326 D6 I acute */ {0xA1,0xD6,1,1},
-/* 140 08/12 214 8C i circumflex */
-/* 215 13/07 327 D7 I circumflex */ {0x8C,0xD7,1,1},
-/* 139 08/11 213 8B i diaeresis */
-/* 216 13/08 330 D8 I diaeresis */ {0x8B,0xD8,1,1},
-/* 208 13/00 320 D0 Icelandic eth */
-/* 209 13/01 321 D1 Icelandic Eth */ {0xD0,0xD1,1,1},
-/* 164 10/04 244 A4 n tilde */
-/* 165 10/05 245 A5 N tilde */ {0xA4,0xA5,1,1},
-/* 149 09/05 225 95 o grave */
-/* 227 14/03 343 E3 O grave */ {0x95,0xE3,1,1},
-/* 162 10/02 242 A2 o acute */
-/* 224 14/00 340 E0 O acute */ {0xA2,0xE0,1,1},
-/* 147 09/03 223 93 o circumflex */
-/* 226 14/02 342 E2 O circumflex */ {0x93,0xE2,1,1},
-/* 228 14/04 344 E4 o tilde */
-/* 229 14/05 345 E5 O tilde */ {0xE4,0xE5,1,1},
-/* 148 09/04 224 94 o diaeresis */
-/* 153 09/09 231 99 O diaeresis */ {0x94,0x99,1,1},
-/* 155 09/11 233 9B o slash */
-/* 157 09/13 235 9D O slash */ {0x9B,0x9D,1,1},
-/* 151 09/07 227 97 u grave */
-/* 235 14/11 353 EB U grave */ {0x97,0xEB,1,1},
-/* 163 10/03 243 A3 u acute */
-/* 233 14/09 351 E9 U acute */ {0xA3,0xE9,1,1},
-/* 150 09/06 226 96 u circumflex */
-/* 234 14/10 352 EA U circumflex */ {0x96,0xEA,1,1},
-/* 129 08/01 201 81 u diaeresis */
-/* 154 09/10 232 9A U diaeresis */ {0x81,0x9A,1,1},
-/* 236 14/12 354 EC y acute */
-/* 237 14/13 355 ED Y acute */ {0xEC,0xED,1,1},
-/* 231 14/07 347 E7 Icelandic thorn */
-/* 232 14/08 350 E8 Icelandic Thorn */ {0xE7,0xE8,1,1},
-
- {0x9C,0,0,0}, /* Pound */
- {0,0,0,0}
-};
-#else /* KANJI */
-/* lower->upper mapping for IBM Code Page 932 - MS-DOS Japanese SJIS */
-unsigned char cp_932[][4] = {
- {0,0,0,0}
-};
-#endif /* KANJI */
-
-char xx_dos_char_map[256];
-char xx_upper_char_map[256];
-char xx_lower_char_map[256];
-
-char *dos_char_map = xx_dos_char_map;
-char *upper_char_map = xx_upper_char_map;
-char *lower_char_map = xx_lower_char_map;
-
-/*
- * This code has been extended to deal with ascynchronous mappings
- * like MS-DOS Latin US (Code page 437) where things like :
- * a acute are capitalized to 'A', but the reverse mapping
- * must not hold true. This allows the filename case insensitive
- * matching in do_match() to work, as the DOS/Win95/NT client
- * uses 'A' as a mask to match against characters like a acute.
- * This is the meaning behind the parameters that allow a
- * mapping from lower to upper, but not upper to lower.
- */
-
-static void add_dos_char(int lower, BOOL map_lower_to_upper,
- int upper, BOOL map_upper_to_lower)
-{
- lower &= 0xff;
- upper &= 0xff;
- DEBUG(6,("Adding chars 0x%x 0x%x (l->u = %s) (u->l = %s)\n",lower,upper,
- map_lower_to_upper ? "True" : "False",
- map_upper_to_lower ? "True" : "False"));
- if (lower) dos_char_map[lower] = 1;
- if (upper) dos_char_map[upper] = 1;
- if (lower && upper) {
- if(map_upper_to_lower)
- lower_char_map[upper] = (char)lower;
- if(map_lower_to_upper)
- upper_char_map[lower] = (char)upper;
- }
-}
-
-/****************************************************************************
-initialise the charset arrays
-****************************************************************************/
-void charset_initialise()
-{
- int i;
-
-#ifdef LC_ALL
- /* include <locale.h> in includes.h if available for OS */
- /* we take only standard 7-bit ASCII definitions from ctype */
- setlocale(LC_ALL,"C");
-#endif
-
- for (i= 0;i<=255;i++) {
- dos_char_map[i] = 0;
- }
-
- for (i=0;i<=127;i++) {
- if (isalnum((char)i) || strchr("._^$~!#%&-{}()@'`",(char)i))
- add_dos_char(i,False,0,False);
- }
-
- for (i=0; i<=255; i++) {
- char c = (char)i;
- upper_char_map[i] = lower_char_map[i] = c;
- if (isupper(c)) lower_char_map[i] = tolower(c);
- if (islower(c)) upper_char_map[i] = toupper(c);
- }
-}
-
-/****************************************************************************
-load the client codepage.
-****************************************************************************/
-
-typedef unsigned char (*codepage_p)[4];
-
-static codepage_p load_client_codepage( int client_codepage )
-{
- pstring codepage_file_name;
- unsigned char buf[8];
- FILE *fp = NULL;
- unsigned int size;
- codepage_p cp_p = NULL;
- struct stat st;
-
- DEBUG(5, ("load_client_codepage: loading codepage %d.\n", client_codepage));
-
- if(strlen(CODEPAGEDIR) + 14 > sizeof(codepage_file_name))
- {
- DEBUG(0,("load_client_codepage: filename too long to load\n"));
- return NULL;
- }
-
- strcpy(codepage_file_name, CODEPAGEDIR);
- strcat(codepage_file_name, "/");
- strcat(codepage_file_name, "codepage.");
- sprintf( &codepage_file_name[strlen(codepage_file_name)], "%03d",
- client_codepage);
-
- if(!file_exist(codepage_file_name,&st))
- {
- DEBUG(0,("load_client_codepage: filename %s does not exist.\n",
- codepage_file_name));
- return NULL;
- }
-
- /* Check if it is at least big enough to hold the required
- data. Should be 2 byte version, 2 byte codepage, 4 byte length,
- plus zero or more bytes of data. Note that the data cannot be more
- than 512 bytes - giving a max size of 520.
- */
- size = (unsigned int)st.st_size;
-
- if( size < CODEPAGE_HEADER_SIZE || size > (CODEPAGE_HEADER_SIZE + 256))
- {
- DEBUG(0,("load_client_codepage: file %s is an incorrect size for a \
-code page file.\n", codepage_file_name));
- return NULL;
- }
-
- /* Read the first 8 bytes of the codepage file - check
- the version number and code page number. All the data
- is held in little endian format.
- */
-
- if((fp = fopen( codepage_file_name, "r")) == NULL)
- {
- DEBUG(0,("load_client_codepage: cannot open file %s. Error was %s\n",
- codepage_file_name, strerror(errno)));
- return NULL;
- }
-
- if(fread( buf, 1, CODEPAGE_HEADER_SIZE, fp)!=CODEPAGE_HEADER_SIZE)
- {
- DEBUG(0,("load_client_codepage: cannot read header from file %s. Error was %s\n",
- codepage_file_name, strerror(errno)));
- goto clean_and_exit;
- }
-
- /* Check the version value */
- if(SVAL(buf,CODEPAGE_VERSION_OFFSET) != CODEPAGE_FILE_VERSION_ID)
- {
- DEBUG(0,("load_client_codepage: filename %s has incorrect version id. \
-Needed %hu, got %hu.\n",
- codepage_file_name, (uint16)CODEPAGE_FILE_VERSION_ID,
- SVAL(buf,CODEPAGE_VERSION_OFFSET)));
- goto clean_and_exit;
- }
-
- /* Check the codepage matches */
- if(SVAL(buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET) != (uint16)client_codepage)
- {
- DEBUG(0,("load_client_codepage: filename %s has incorrect codepage. \
-Needed %hu, got %hu.\n",
- codepage_file_name, (uint16)client_codepage,
- SVAL(buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET)));
- goto clean_and_exit;
- }
-
- /* Check the length is correct. */
- if(IVAL(buf,CODEPAGE_LENGTH_OFFSET) !=
- (unsigned int)(size - CODEPAGE_HEADER_SIZE))
- {
- DEBUG(0,("load_client_codepage: filename %s has incorrect size headers. \
-Needed %u, got %u.\n", codepage_file_name, size - CODEPAGE_HEADER_SIZE,
- IVAL(buf,CODEPAGE_LENGTH_OFFSET)));
- goto clean_and_exit;
- }
-
- size -= CODEPAGE_HEADER_SIZE; /* Remove header */
-
- /* Make sure the size is a multiple of 4. */
- if((size % 4 ) != 0)
- {
- DEBUG(0,("load_client_codepage: filename %s has a codepage size not a \
-multiple of 4.\n", codepage_file_name));
- goto clean_and_exit;
- }
-
- /* Allocate space for the code page file and read it all in. */
- if((cp_p = (codepage_p)malloc( size + 4 )) == NULL)
- {
- DEBUG(0,("load_client_codepage: malloc fail.\n"));
- goto clean_and_exit;
- }
-
- if(fread( (char *)cp_p, 1, size, fp)!=size)
- {
- DEBUG(0,("load_client_codepage: read fail on file %s. Error was %s.\n",
- codepage_file_name, strerror(errno)));
- goto clean_and_exit;
- }
-
- /* Ensure array is correctly terminated. */
- memset(((char *)cp_p) + size, '\0', 4);
-
- fclose(fp);
- return cp_p;
-
-clean_and_exit:
-
- /* pseudo destructor :-) */
-
- if(fp != NULL)
- fclose(fp);
- if(cp_p)
- free((char *)cp_p);
- return NULL;
-}
-
-/****************************************************************************
-initialise the client codepage.
-****************************************************************************/
-void codepage_initialise(int client_codepage)
-{
- int i;
- codepage_p cp = NULL;
- static BOOL done = False;
-
- if(done == True)
- {
- DEBUG(6,
- ("codepage_initialise: called twice - ignoring second client code page = %d\n",
- client_codepage));
- return;
- }
-
- DEBUG(6,("codepage_initialise: client code page = %d\n", client_codepage));
-
- /*
- * Known client codepages - these can be added to.
- */
- cp = load_client_codepage( client_codepage );
-
- if(cp == NULL)
- {
-#ifdef KANJI
- DEBUG(6,("codepage_initialise: loading dynamic codepage file %s/codepage.%d \
-for code page %d failed. Using default client codepage 932\n",
- CODEPAGEDIR, client_codepage, client_codepage));
- cp = cp_932;
-#else /* KANJI */
- DEBUG(6,("codepage_initialise: loading dynamic codepage file %s/codepage.%d \
-for code page %d failed. Using default client codepage 850\n",
- CODEPAGEDIR, client_codepage, client_codepage));
- cp = cp_850;
-#endif /* KANJI */
- }
-
- if(cp)
- {
- for(i = 0; !((cp[i][0] == '\0') && (cp[i][1] == '\0')); i++)
- add_dos_char(cp[i][0], (BOOL)cp[i][2], cp[i][1], (BOOL)cp[i][3]);
- }
-
- done = True;
-}
-
-/*******************************************************************
-add characters depending on a string passed by the user
-********************************************************************/
-void add_char_string(char *s)
-{
- char *extra_chars = (char *)strdup(s);
- char *t;
- if (!extra_chars) return;
-
- for (t=strtok(extra_chars," \t\r\n"); t; t=strtok(NULL," \t\r\n")) {
- char c1=0,c2=0;
- int i1=0,i2=0;
- if (isdigit((unsigned char)*t) || (*t)=='-') {
- sscanf(t,"%i:%i",&i1,&i2);
- add_dos_char(i1,True,i2,True);
- } else {
- sscanf(t,"%c:%c",&c1,&c2);
- add_dos_char((unsigned char)c1,True,(unsigned char)c2, True);
- }
- }
-
- free(extra_chars);
-}
diff --git a/source/lib/fault.c b/source/lib/fault.c
deleted file mode 100644
index 61715a4f225..00000000000
--- a/source/lib/fault.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Critical Fault handling
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-
-#include "includes.h"
-extern int DEBUGLEVEL;
-
-
-static void (*cont_fn)();
-
-
-/*******************************************************************
-report a fault
-********************************************************************/
-static void fault_report(int sig)
-{
- DEBUG(0,("===============================================================\n"));
- DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)getpid(),VERSION));
- DEBUG(0,("\nPlease read the file BUGS.txt in the distribution\n"));
- DEBUG(0,("===============================================================\n"));
-
-#if AJT
- ajt_panic();
-#endif
-
- if (cont_fn)
- {
- fault_setup(cont_fn);
- cont_fn(NULL);
-#ifdef SIGSEGV
- signal(SIGSEGV,SIGNAL_CAST SIG_DFL);
-#endif
-#ifdef SIGBUS
- signal(SIGBUS,SIGNAL_CAST SIG_DFL);
-#endif
- return; /* this should cause a core dump */
- }
- exit(1);
-}
-
-/****************************************************************************
-catch serious errors
-****************************************************************************/
-static void sig_fault(int sig)
-{
- fault_report(sig);
-}
-
-/*******************************************************************
-setup our fault handlers
-********************************************************************/
-void fault_setup(void (*fn)())
-{
- cont_fn = fn;
-
-#ifdef SIGSEGV
- signal(SIGSEGV,SIGNAL_CAST sig_fault);
-#endif
-#ifdef SIGBUS
- signal(SIGBUS,SIGNAL_CAST sig_fault);
-#endif
-}
-
-
-
diff --git a/source/lib/getsmbpass.c b/source/lib/getsmbpass.c
deleted file mode 100644
index e8cb683d0b1..00000000000
--- a/source/lib/getsmbpass.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/* Copyright (C) 1992-1997 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library 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
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-/* Modified to use with samba by Jeremy Allison, 8th July 1995. */
-
-#include "includes.h"
-
-#ifdef REPLACE_GETPASS
-
-#ifdef SYSV_TERMIO
-
-/* SYSTEM V TERMIO HANDLING */
-
-static struct termio t;
-
-#define ECHO_IS_ON(t) ((t).c_lflag & ECHO)
-#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO)
-#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO)
-
-#ifndef TCSAFLUSH
-#define TCSAFLUSH 1
-#endif
-
-#ifndef TCSANOW
-#define TCSANOW 0
-#endif
-
- int tcgetattr(int fd, struct termio *t)
-{
- return ioctl(fd, TCGETA, t);
-}
-
- int tcsetattr(int fd, int flags, struct termio *t)
-{
- if(flags & TCSAFLUSH)
- ioctl(fd, TCFLSH, TCIOFLUSH);
- return ioctl(fd, TCSETS, t);
-}
-
-#else /* SYSV_TERMIO */
-#ifdef BSD_TERMIO
-
-/* BSD TERMIO HANDLING */
-
-static struct sgttyb t;
-
-#define ECHO_IS_ON(t) ((t).sg_flags & ECHO)
-#define TURN_ECHO_OFF(t) ((t).sg_flags &= ~ECHO)
-#define TURN_ECHO_ON(t) ((t).sg_flags |= ECHO)
-
-#ifndef TCSAFLUSH
-#define TCSAFLUSH 1
-#endif
-
-#ifndef TCSANOW
-#define TCSANOW 0
-#endif
-
- int tcgetattr(int fd, struct sgttyb *t)
-{
- return ioctl(fd, TIOCGETP, (char *)t);
-}
-
- int tcsetattr(int fd, int flags, struct sgttyb *t)
-{
- return ioctl(fd, TIOCSETP, (char *)t);
-}
-
-#else /* BSD_TERMIO */
-
-/* POSIX TERMIO HANDLING */
-#define ECHO_IS_ON(t) ((t).c_lflag & ECHO)
-#define TURN_ECHO_OFF(t) ((t).c_lflag &= ~ECHO)
-#define TURN_ECHO_ON(t) ((t).c_lflag |= ECHO)
-
-static struct termios t;
-#endif /* BSD_TERMIO */
-#endif /* SYSV_TERMIO */
-
-char *getsmbpass(char *prompt)
-{
- FILE *in, *out;
- int echo_off;
- static char buf[256];
- static size_t bufsize = sizeof(buf);
- size_t nread;
-
- /* Catch problematic signals */
- signal(SIGINT, SIGNAL_CAST SIG_IGN);
-
- /* Try to write to and read from the terminal if we can.
- If we can't open the terminal, use stderr and stdin. */
-
- in = fopen ("/dev/tty", "w+");
- if (in == NULL)
- {
- in = stdin;
- out = stderr;
- }
- else
- out = in;
-
- setvbuf(in, NULL, _IONBF, 0);
-
- /* Turn echoing off if it is on now. */
-
- if (tcgetattr (fileno (in), &t) == 0)
- {
- if (ECHO_IS_ON(t))
- {
- TURN_ECHO_OFF(t);
- echo_off = tcsetattr (fileno (in), TCSAFLUSH, &t) == 0;
- TURN_ECHO_ON(t);
- }
- else
- echo_off = 0;
- }
- else
- echo_off = 0;
-
- /* Write the prompt. */
- fputs (prompt, out);
- fflush (out);
-
- /* Read the password. */
- buf[0] = 0;
- fgets(buf, bufsize, in);
- nread = strlen(buf);
- if (buf[nread - 1] == '\n')
- buf[nread - 1] = '\0';
-
- /* Restore echoing. */
- if (echo_off)
- (void) tcsetattr (fileno (in), TCSANOW, &t);
-
- if (in != stdin)
- /* We opened the terminal; now close it. */
- fclose (in);
-
- /* Catch problematic signals */
- signal(SIGINT, SIGNAL_CAST SIG_DFL);
-
- printf("\n");
- return buf;
-}
-
-#else
-
- void getsmbpasswd_dummy() {;}
-#endif
diff --git a/source/lib/interface.c b/source/lib/interface.c
deleted file mode 100644
index 147425d0fc1..00000000000
--- a/source/lib/interface.c
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- multiple interface handling
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-
-#include "includes.h"
-
-extern int DEBUGLEVEL;
-
-struct in_addr ipzero;
-struct in_addr wins_ip;
-static struct in_addr default_ip;
-static struct in_addr default_bcast;
-static struct in_addr default_nmask;
-static BOOL got_ip=False;
-static BOOL got_bcast=False;
-static BOOL got_nmask=False;
-
-struct interface *local_interfaces = NULL;
-
-struct interface *last_iface;
-
-/****************************************************************************
-calculate the default netmask for an address
-****************************************************************************/
-static void default_netmask(struct in_addr *inm, struct in_addr *iad)
-{
- uint32 ad = ntohl(iad->s_addr);
- uint32 nm;
- /*
- ** Guess a netmask based on the class of the IP address given.
- */
- if ( (ad & 0x80000000) == 0 ) {
- /* class A address */
- nm = 0xFF000000;
- } else if ( (ad & 0xC0000000) == 0x80000000 ) {
- /* class B address */
- nm = 0xFFFF0000;
- } else if ( (ad & 0xE0000000) == 0xC0000000 ) {
- /* class C address */
- nm = 0xFFFFFF00;
- } else {
- /* class D or E; netmask doesn't make much sense - guess 4 bits */
- nm = 0xFFFFFFF0;
- }
- inm->s_addr = htonl(nm);
-}
-
-
-/****************************************************************************
- get the broadcast address for our address
-(troyer@saifr00.ateng.az.honeywell.com)
-****************************************************************************/
-static void get_broadcast(struct in_addr *if_ipaddr,
- struct in_addr *if_bcast,
- struct in_addr *if_nmask)
-{
- BOOL found = False;
-#ifndef NO_GET_BROADCAST
- int sock = -1; /* AF_INET raw socket desc */
- char buff[1024];
- struct ifreq *ifr=NULL;
- int i;
-
-#if defined(EVEREST)
- int n_interfaces;
- struct ifconf ifc;
- struct ifreq *ifreqs;
-#elif defined(USE_IFREQ)
- struct ifreq ifreq;
- struct strioctl strioctl;
- struct ifconf *ifc;
-#else
- struct ifconf ifc;
-#endif
-#endif
-
- /* get a default netmask and broadcast */
- default_netmask(if_nmask, if_ipaddr);
-
-#ifndef NO_GET_BROADCAST
- /* Create a socket to the INET kernel. */
-#if USE_SOCKRAW
- if ((sock = socket(AF_INET, SOCK_RAW, PF_INET )) < 0)
-#else
- if ((sock = socket(AF_INET, SOCK_DGRAM, 0 )) < 0)
-#endif
- {
- DEBUG(0,( "Unable to open socket to get broadcast address\n"));
- return;
- }
-
- /* Get a list of the configured interfaces */
-#ifdef EVEREST
- /* This is part of SCO Openserver 5: The ioctls are no longer part
- if the lower level STREAMS interface glue. They are now real
- ioctl calls */
-
- if (ioctl(sock, SIOCGIFANUM, &n_interfaces) < 0) {
- DEBUG(0,( "SIOCGIFANUM: %s\n", strerror(errno)));
- } else {
- DEBUG(0,( "number of interfaces returned is: %d\n", n_interfaces));
-
- ifc.ifc_len = sizeof(struct ifreq) * n_interfaces;
- ifc.ifc_buf = (caddr_t) alloca(ifc.ifc_len);
-
- if (ioctl(sock, SIOCGIFCONF, &ifc) < 0)
- DEBUG(0, ( "SIOCGIFCONF: %s\n", strerror(errno)));
- else {
- ifr = ifc.ifc_req;
-
- for (i = 0; i < n_interfaces; ++i) {
- if (if_ipaddr->s_addr ==
- ((struct sockaddr_in *) &ifr[i].ifr_addr)->sin_addr.s_addr) {
- found = True;
- break;
- }
- }
- }
- }
-#elif defined(USE_IFREQ)
- ifc = (struct ifconf *)buff;
- ifc->ifc_len = BUFSIZ - sizeof(struct ifconf);
- strioctl.ic_cmd = SIOCGIFCONF;
- strioctl.ic_dp = (char *)ifc;
- strioctl.ic_len = sizeof(buff);
- if (ioctl(sock, I_STR, &strioctl) < 0) {
- DEBUG(0,( "I_STR/SIOCGIFCONF: %s\n", strerror(errno)));
- } else {
- ifr = (struct ifreq *)ifc->ifc_req;
-
- /* Loop through interfaces, looking for given IP address */
- for (i = ifc->ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {
- if (if_ipaddr->s_addr ==
- (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
- found = True;
- break;
- }
- }
- }
-#elif defined(__FreeBSD__) || defined(NETBSD) || defined(AMIGA) || defined(_AIX41)
- ifc.ifc_len = sizeof(buff);
- ifc.ifc_buf = buff;
- if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
- DEBUG(0,("SIOCGIFCONF: %s\n", strerror(errno)));
- } else {
- ifr = ifc.ifc_req;
- /* Loop through interfaces, looking for given IP address */
- i = ifc.ifc_len;
- while (i > 0) {
- if (if_ipaddr->s_addr ==
- (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
- found = True;
- break;
- }
- i -= ifr->ifr_addr.sa_len + IFNAMSIZ;
- ifr = (struct ifreq*) ((char*) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ);
- }
- }
-#else
- ifc.ifc_len = sizeof(buff);
- ifc.ifc_buf = buff;
- if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
- DEBUG(0,("SIOCGIFCONF: %s\n", strerror(errno)));
- } else {
- ifr = ifc.ifc_req;
-
- /* Loop through interfaces, looking for given IP address */
- for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {
-#ifdef BSDI
- if (ioctl(sock, SIOCGIFADDR, ifr) < 0) break;
-#endif
- if (if_ipaddr->s_addr ==
- (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
- found = True;
- break;
- }
- }
- }
-#endif
-
- if (!found) {
- DEBUG(0,("No interface found for address %s\n", inet_ntoa(*if_ipaddr)));
- } else {
- /* Get the netmask address from the kernel */
-#ifdef USE_IFREQ
- ifreq = *ifr;
-
- strioctl.ic_cmd = SIOCGIFNETMASK;
- strioctl.ic_dp = (char *)&ifreq;
- strioctl.ic_len = sizeof(struct ifreq);
- if (ioctl(sock, I_STR, &strioctl) < 0)
- DEBUG(0,("Failed I_STR/SIOCGIFNETMASK: %s\n", strerror(errno)));
- else
- *if_nmask = ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr;
-#else
- if (ioctl(sock, SIOCGIFNETMASK, ifr) < 0)
- DEBUG(0,("SIOCGIFNETMASK failed\n"));
- else
- *if_nmask = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
-#endif
-
- DEBUG(4,("Netmask for %s = %s\n", ifr->ifr_name,
- inet_ntoa(*if_nmask)));
- }
-
- /* Close up shop */
- (void) close(sock);
-
-#endif
-
- /* sanity check on the netmask */
- {
- uint32 nm = ntohl(if_nmask->s_addr);
- if ((nm >> 24) != 0xFF) {
- DEBUG(0,("Impossible netmask %s - using defaults\n",inet_ntoa(*if_nmask)));
- default_netmask(if_nmask, if_ipaddr);
- }
- }
-
- /* derive the broadcast assuming a 1's broadcast, as this is what
- all MS operating systems do, we have to comply even if the unix
- box is setup differently */
- {
- uint32 ad = ntohl(if_ipaddr->s_addr);
- uint32 nm = ntohl(if_nmask->s_addr);
- uint32 bc = (ad & nm) | (0xffffffff & ~nm);
- if_bcast->s_addr = htonl(bc);
- }
-
- DEBUG(4,("Derived broadcast address %s\n", inet_ntoa(*if_bcast)));
-} /* get_broadcast */
-
-
-
-/****************************************************************************
-load a list of network interfaces
-****************************************************************************/
-static void interpret_interfaces(char *s, struct interface **interfaces,
- char *description)
-{
- char *ptr = s;
- fstring token;
- struct interface *iface;
- struct in_addr ip;
-
- ipzero = *interpret_addr2("0.0.0.0");
- wins_ip = *interpret_addr2("255.255.255.255");
-
- while (next_token(&ptr,token,NULL)) {
- /* parse it into an IP address/netmasklength pair */
- char *p = strchr(token,'/');
- if (p) *p = 0;
-
- ip = *interpret_addr2(token);
-
- /* maybe we already have it listed */
- {
- struct interface *i;
- for (i=(*interfaces);i;i=i->next)
- if (ip_equal(ip,i->ip)) break;
- if (i) continue;
- }
-
- iface = (struct interface *)malloc(sizeof(*iface));
- if (!iface) return;
-
- iface->ip = ip;
-
- if (p) {
- if (strlen(p+1)>2)
- iface->nmask = *interpret_addr2(p+1);
- else
- iface->nmask.s_addr = htonl(~((1<<(32-atoi(p+1)))-1));
- } else {
- default_netmask(&iface->nmask,&iface->ip);
- }
- iface->bcast.s_addr = iface->ip.s_addr | ~iface->nmask.s_addr;
- iface->next = NULL;
-
- if (!(*interfaces)) {
- (*interfaces) = iface;
- } else {
- last_iface->next = iface;
- }
- last_iface = iface;
- DEBUG(1,("Added %s ip=%s ",description,inet_ntoa(iface->ip)));
- DEBUG(1,("bcast=%s ",inet_ntoa(iface->bcast)));
- DEBUG(1,("nmask=%s\n",inet_ntoa(iface->nmask)));
- }
-
- if (*interfaces) return;
-
- /* setup a default interface */
- iface = (struct interface *)malloc(sizeof(*iface));
- if (!iface) return;
-
- iface->next = NULL;
-
- if (got_ip) {
- iface->ip = default_ip;
- } else {
- get_myname(NULL,&iface->ip);
- }
-
- if (got_bcast) {
- iface->bcast = default_bcast;
- } else {
- get_broadcast(&iface->ip,&iface->bcast,&iface->nmask);
- }
-
- if (got_nmask) {
- iface->nmask = default_nmask;
- iface->bcast.s_addr = iface->ip.s_addr | ~iface->nmask.s_addr;
- }
-
- if (iface->bcast.s_addr != (iface->ip.s_addr | ~iface->nmask.s_addr)) {
- DEBUG(2,("Warning: inconsistant interface %s\n",inet_ntoa(iface->ip)));
- }
-
- iface->next = NULL;
- (*interfaces) = last_iface = iface;
-
- DEBUG(2,("Added interface ip=%s ",inet_ntoa(iface->ip)));
- DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast)));
- DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask)));
-}
-
-
-/****************************************************************************
-load the remote and local interfaces
-****************************************************************************/
-void load_interfaces(void)
-{
- /* add the machine's interfaces to local interface structure*/
- interpret_interfaces(lp_interfaces(), &local_interfaces,"interface");
-}
-
-
-/****************************************************************************
- override the defaults
- **************************************************************************/
-void iface_set_default(char *ip,char *bcast,char *nmask)
-{
- if (ip) {
- got_ip = True;
- default_ip = *interpret_addr2(ip);
- }
-
- if (bcast) {
- got_bcast = True;
- default_bcast = *interpret_addr2(bcast);
- }
-
- if (nmask) {
- got_nmask = True;
- default_nmask = *interpret_addr2(nmask);
- }
-}
-
-
-/****************************************************************************
- check if an IP is one of mine
- **************************************************************************/
-BOOL ismyip(struct in_addr ip)
-{
- struct interface *i;
- for (i=local_interfaces;i;i=i->next)
- if (ip_equal(i->ip,ip)) return True;
- return False;
-}
-
-/****************************************************************************
- check if a bcast is one of mine
- **************************************************************************/
-BOOL ismybcast(struct in_addr bcast)
-{
- struct interface *i;
- for (i=local_interfaces;i;i=i->next)
- if (ip_equal(i->bcast,bcast)) return True;
- return False;
-}
-
-/****************************************************************************
- how many interfaces do we have
- **************************************************************************/
-int iface_count(void)
-{
- int ret = 0;
- struct interface *i;
-
- for (i=local_interfaces;i;i=i->next)
- ret++;
- return ret;
-}
-
-/****************************************************************************
- return IP of the Nth interface
- **************************************************************************/
-struct in_addr *iface_n_ip(int n)
-{
- struct interface *i;
-
- for (i=local_interfaces;i && n;i=i->next)
- n--;
-
- if (i) return &i->ip;
- return NULL;
-}
-
-static struct interface *iface_find(struct in_addr ip)
-{
- struct interface *i;
- if (zero_ip(ip)) return local_interfaces;
-
- for (i=local_interfaces;i;i=i->next)
- if (same_net(i->ip,ip,i->nmask)) return i;
-
- return local_interfaces;
-}
-
-/* these 3 functions return the ip/bcast/nmask for the interface
- most appropriate for the given ip address */
-
-struct in_addr *iface_bcast(struct in_addr ip)
-{
- return(&iface_find(ip)->bcast);
-}
-
-struct in_addr *iface_nmask(struct in_addr ip)
-{
- return(&iface_find(ip)->nmask);
-}
-
-struct in_addr *iface_ip(struct in_addr ip)
-{
- return(&iface_find(ip)->ip);
-}
-
-
-
diff --git a/source/lib/kanji.c b/source/lib/kanji.c
deleted file mode 100644
index 5d7de87248d..00000000000
--- a/source/lib/kanji.c
+++ /dev/null
@@ -1,868 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Kanji Extensions
- Copyright (C) Andrew Tridgell 1992-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.
-
- Adding for Japanese language by <fujita@ainix.isac.co.jp> 1994.9.5
- and extend coding system to EUC/SJIS/JIS/HEX at 1994.10.11
- and add all jis codes sequence type at 1995.8.16
- Notes: Hexadecimal code by <ohki@gssm.otuka.tsukuba.ac.jp>
-*/
-
-#define _KANJI_C_
-#include "includes.h"
-
-/* coding system keep in */
-int coding_system = SJIS_CODE;
-
-/* jis si/so sequence */
-char jis_kso = JIS_KSO;
-char jis_ksi = JIS_KSI;
-char hex_tag = HEXTAG;
-
-/*******************************************************************
- SHIFT JIS functions
-********************************************************************/
-/*******************************************************************
- search token from S1 separated any char of S2
- S1 contain SHIFT JIS chars.
-********************************************************************/
-char *sj_strtok(char *s1, char *s2)
-{
- static char *s = NULL;
- char *q;
- if (!s1) {
- if (!s) {
- return NULL;
- }
- s1 = s;
- }
- for (q = s1; *s1; ) {
- if (is_shift_jis (*s1)) {
- s1 += 2;
- } else if (is_kana (*s1)) {
- s1++;
- } else {
- char *p = strchr (s2, *s1);
- if (p) {
- if (s1 != q) {
- s = s1 + 1;
- *s1 = '\0';
- return q;
- }
- q = s1 + 1;
- }
- s1++;
- }
- }
- s = NULL;
- if (*q) {
- return q;
- }
- return NULL;
-}
-
-/*******************************************************************
- search string S2 from S1
- S1 contain SHIFT JIS chars.
-********************************************************************/
-char *sj_strstr(char *s1, char *s2)
-{
- int len = strlen ((char *) s2);
- if (!*s2)
- return (char *) s1;
- for (;*s1;) {
- if (*s1 == *s2) {
- if (strncmp (s1, s2, len) == 0)
- return (char *) s1;
- }
- if (is_shift_jis (*s1)) {
- s1 += 2;
- } else {
- s1++;
- }
- }
- return 0;
-}
-
-/*******************************************************************
- Search char C from beginning of S.
- S contain SHIFT JIS chars.
-********************************************************************/
-char *sj_strchr (char *s, int c)
-{
- for (; *s; ) {
- if (*s == c)
- return (char *) s;
- if (is_shift_jis (*s)) {
- s += 2;
- } else {
- s++;
- }
- }
- return 0;
-}
-
-/*******************************************************************
- Search char C end of S.
- S contain SHIFT JIS chars.
-********************************************************************/
-char *sj_strrchr(char *s, int c)
-{
- char *q;
-
- for (q = 0; *s; ) {
- if (*s == c) {
- q = (char *) s;
- }
- if (is_shift_jis (*s)) {
- s += 2;
- } else {
- s++;
- }
- }
- return q;
-}
-
-/*******************************************************************
- Code conversion
-********************************************************************/
-/* convesion buffer */
-static char cvtbuf[1024];
-
-/*******************************************************************
- EUC <-> SJIS
-********************************************************************/
-static int euc2sjis (int hi, int lo)
-{
- if (hi & 1)
- return ((hi / 2 + (hi < 0xdf ? 0x31 : 0x71)) << 8) |
- (lo - (lo >= 0xe0 ? 0x60 : 0x61));
- else
- return ((hi / 2 + (hi < 0xdf ? 0x30 : 0x70)) << 8) | (lo - 2);
-}
-
-static int sjis2euc (int hi, int lo)
-{
- if (lo >= 0x9f)
- return ((hi * 2 - (hi >= 0xe0 ? 0xe0 : 0x60)) << 8) | (lo + 2);
- else
- return ((hi * 2 - (hi >= 0xe0 ? 0xe1 : 0x61)) << 8) |
- (lo + (lo >= 0x7f ? 0x60 : 0x61));
-}
-
-/*******************************************************************
- Convert FROM contain SHIFT JIS codes to EUC codes
- return converted buffer
-********************************************************************/
-static char *sj_to_euc(char *from, BOOL overwrite)
-{
- char *out;
- char *save;
-
- save = (char *) from;
- for (out = cvtbuf; *from;) {
- if (is_shift_jis (*from)) {
- int code = sjis2euc ((int) from[0] & 0xff, (int) from[1] & 0xff);
- *out++ = (code >> 8) & 0xff;
- *out++ = code;
- from += 2;
- } else if (is_kana (*from)) {
- *out++ = euc_kana;
- *out++ = *from++;
- } else {
- *out++ = *from++;
- }
- }
- *out = 0;
- if (overwrite) {
- strcpy((char *) save, (char *) cvtbuf);
- return (char *) save;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- Convert FROM contain EUC codes to SHIFT JIS codes
- return converted buffer
-********************************************************************/
-static char *euc_to_sj(char *from, BOOL overwrite)
-{
- char *out;
- char *save;
-
- save = (char *) from;
- for (out = cvtbuf; *from; ) {
- if (is_euc (*from)) {
- int code = euc2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
- *out++ = (code >> 8) & 0xff;
- *out++ = code;
- from += 2;
- } else if (is_euc_kana (*from)) {
- *out++ = from[1];
- from += 2;
- } else {
- *out++ = *from++;
- }
- }
- *out = 0;
- if (overwrite) {
- strcpy(save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- JIS7,JIS8,JUNET <-> SJIS
-********************************************************************/
-static int sjis2jis(int hi, int lo)
-{
- if (lo >= 0x9f)
- return ((hi * 2 - (hi >= 0xe0 ? 0x160 : 0xe0)) << 8) | (lo - 0x7e);
- else
- return ((hi * 2 - (hi >= 0xe0 ? 0x161 : 0xe1)) << 8) |
- (lo - (lo >= 0x7f ? 0x20 : 0x1f));
-}
-
-static int jis2sjis(int hi, int lo)
-{
- if (hi & 1)
- return ((hi / 2 + (hi < 0x5f ? 0x71 : 0xb1)) << 8) |
- (lo + (lo >= 0x60 ? 0x20 : 0x1f));
- else
- return ((hi / 2 + (hi < 0x5f ? 0x70 : 0xb0)) << 8) | (lo + 0x7e);
-}
-
-/*******************************************************************
- Convert FROM contain JIS codes to SHIFT JIS codes
- return converted buffer
-********************************************************************/
-static char *jis8_to_sj(char *from, BOOL overwrite)
-{
- char *out;
- int shifted;
- char *save;
-
- shifted = _KJ_ROMAN;
- save = (char *) from;
- for (out = cvtbuf; *from;) {
- if (is_esc (*from)) {
- if (is_so1 (from[1]) && is_so2 (from[2])) {
- shifted = _KJ_KANJI;
- from += 3;
- } else if (is_si1 (from[1]) && is_si2 (from[2])) {
- shifted = _KJ_ROMAN;
- from += 3;
- } else { /* sequence error */
- goto normal;
- }
- } else {
- normal:
- switch (shifted) {
- default:
- case _KJ_ROMAN:
- *out++ = *from++;
- break;
- case _KJ_KANJI:
- {
- int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
- *out++ = (code >> 8) & 0xff;
- *out++ = code;
- from += 2;
- }
- break;
- }
- }
- }
- *out = 0;
- if (overwrite) {
- strcpy (save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- Convert FROM contain SHIFT JIS codes to JIS codes
- return converted buffer
-********************************************************************/
-static char *sj_to_jis8(char *from, BOOL overwrite)
-{
- char *out;
- int shifted;
- char *save;
-
- shifted = _KJ_ROMAN;
- save = (char *) from;
- for (out = cvtbuf; *from; ) {
- if (is_shift_jis (*from)) {
- int code;
- switch (shifted) {
- case _KJ_ROMAN: /* to KANJI */
- *out++ = jis_esc;
- *out++ = jis_so1;
- *out++ = jis_kso;
- shifted = _KJ_KANJI;
- break;
- }
- code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
- *out++ = (code >> 8) & 0xff;
- *out++ = code;
- from += 2;
- } else {
- switch (shifted) {
- case _KJ_KANJI: /* to ROMAN/KANA */
- *out++ = jis_esc;
- *out++ = jis_si1;
- *out++ = jis_ksi;
- shifted = _KJ_ROMAN;
- break;
- }
- *out++ = *from++;
- }
- }
- switch (shifted) {
- case _KJ_KANJI: /* to ROMAN/KANA */
- *out++ = jis_esc;
- *out++ = jis_si1;
- *out++ = jis_ksi;
- shifted = _KJ_ROMAN;
- break;
- }
- *out = 0;
- if (overwrite) {
- strcpy (save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- Convert FROM contain 7 bits JIS codes to SHIFT JIS codes
- return converted buffer
-********************************************************************/
-static char *jis7_to_sj(char *from, BOOL overwrite)
-{
- char *out;
- int shifted;
- char *save;
-
- shifted = _KJ_ROMAN;
- save = (char *) from;
- for (out = cvtbuf; *from;) {
- if (is_esc (*from)) {
- if (is_so1 (from[1]) && is_so2 (from[2])) {
- shifted = _KJ_KANJI;
- from += 3;
- } else if (is_si1 (from[1]) && is_si2 (from[2])) {
- shifted = _KJ_ROMAN;
- from += 3;
- } else { /* sequence error */
- goto normal;
- }
- } else if (is_so (*from)) {
- shifted = _KJ_KANA; /* to KANA */
- from++;
- } else if (is_si (*from)) {
- shifted = _KJ_ROMAN; /* to ROMAN */
- from++;
- } else {
- normal:
- switch (shifted) {
- default:
- case _KJ_ROMAN:
- *out++ = *from++;
- break;
- case _KJ_KANJI:
- {
- int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
- *out++ = (code >> 8) & 0xff;
- *out++ = code;
- from += 2;
- }
- break;
- case _KJ_KANA:
- *out++ = ((int) from[0]) + 0x80;
- break;
- }
- }
- }
- *out = 0;
- if (overwrite) {
- strcpy (save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- Convert FROM contain SHIFT JIS codes to 7 bits JIS codes
- return converted buffer
-********************************************************************/
-static char *sj_to_jis7(char *from, BOOL overwrite)
-{
- char *out;
- int shifted;
- char *save;
-
- shifted = _KJ_ROMAN;
- save = (char *) from;
- for (out = cvtbuf; *from; ) {
- if (is_shift_jis (*from)) {
- int code;
- switch (shifted) {
- case _KJ_KANA:
- *out++ = jis_si; /* to ROMAN and through down */
- case _KJ_ROMAN: /* to KANJI */
- *out++ = jis_esc;
- *out++ = jis_so1;
- *out++ = jis_kso;
- shifted = _KJ_KANJI;
- break;
- }
- code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
- *out++ = (code >> 8) & 0xff;
- *out++ = code;
- from += 2;
- } else if (is_kana (from[0])) {
- switch (shifted) {
- case _KJ_KANJI: /* to ROMAN */
- *out++ = jis_esc;
- *out++ = jis_si1;
- *out++ = jis_ksi;
- case _KJ_ROMAN: /* to KANA */
- *out++ = jis_so;
- shifted = _KJ_KANA;
- break;
- }
- *out++ = ((int) *from++) - 0x80;
- } else {
- switch (shifted) {
- case _KJ_KANA:
- *out++ = jis_si; /* to ROMAN */
- shifted = _KJ_ROMAN;
- break;
- case _KJ_KANJI: /* to ROMAN */
- *out++ = jis_esc;
- *out++ = jis_si1;
- *out++ = jis_ksi;
- shifted = _KJ_ROMAN;
- break;
- }
- *out++ = *from++;
- }
- }
- switch (shifted) {
- case _KJ_KANA:
- *out++ = jis_si; /* to ROMAN */
- break;
- case _KJ_KANJI: /* to ROMAN */
- *out++ = jis_esc;
- *out++ = jis_si1;
- *out++ = jis_ksi;
- break;
- }
- *out = 0;
- if (overwrite) {
- strcpy (save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- Convert FROM contain 7 bits JIS(junet) codes to SHIFT JIS codes
- return converted buffer
-********************************************************************/
-static char *junet_to_sj(char *from, BOOL overwrite)
-{
- char *out;
- int shifted;
- char *save;
-
- shifted = _KJ_ROMAN;
- save = (char *) from;
- for (out = cvtbuf; *from;) {
- if (is_esc (*from)) {
- if (is_so1 (from[1]) && is_so2 (from[2])) {
- shifted = _KJ_KANJI;
- from += 3;
- } else if (is_si1 (from[1]) && is_si2 (from[2])) {
- shifted = _KJ_ROMAN;
- from += 3;
- } else if (is_juk1(from[1]) && is_juk2 (from[2])) {
- shifted = _KJ_KANA;
- from += 3;
- } else { /* sequence error */
- goto normal;
- }
- } else {
- normal:
- switch (shifted) {
- default:
- case _KJ_ROMAN:
- *out++ = *from++;
- break;
- case _KJ_KANJI:
- {
- int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
- *out++ = (code >> 8) & 0xff;
- *out++ = code;
- from += 2;
- }
- break;
- case _KJ_KANA:
- *out++ = ((int) from[0]) + 0x80;
- break;
- }
- }
- }
- *out = 0;
- if (overwrite) {
- strcpy (save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- Convert FROM contain SHIFT JIS codes to 7 bits JIS(junet) codes
- return converted buffer
-********************************************************************/
-static char *sj_to_junet(char *from, BOOL overwrite)
-{
- char *out;
- int shifted;
- char *save;
-
- shifted = _KJ_ROMAN;
- save = (char *) from;
- for (out = cvtbuf; *from; ) {
- if (is_shift_jis (*from)) {
- int code;
- switch (shifted) {
- case _KJ_KANA:
- case _KJ_ROMAN: /* to KANJI */
- *out++ = jis_esc;
- *out++ = jis_so1;
- *out++ = jis_so2;
- shifted = _KJ_KANJI;
- break;
- }
- code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
- *out++ = (code >> 8) & 0xff;
- *out++ = code;
- from += 2;
- } else if (is_kana (from[0])) {
- switch (shifted) {
- case _KJ_KANJI: /* to ROMAN */
- case _KJ_ROMAN: /* to KANA */
- *out++ = jis_esc;
- *out++ = junet_kana1;
- *out++ = junet_kana2;
- shifted = _KJ_KANA;
- break;
- }
- *out++ = ((int) *from++) - 0x80;
- } else {
- switch (shifted) {
- case _KJ_KANA:
- case _KJ_KANJI: /* to ROMAN */
- *out++ = jis_esc;
- *out++ = jis_si1;
- *out++ = jis_si2;
- shifted = _KJ_ROMAN;
- break;
- }
- *out++ = *from++;
- }
- }
- switch (shifted) {
- case _KJ_KANA:
- case _KJ_KANJI: /* to ROMAN */
- *out++ = jis_esc;
- *out++ = jis_si1;
- *out++ = jis_si2;
- break;
- }
- *out = 0;
- if (overwrite) {
- strcpy (save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- HEX <-> SJIS
-********************************************************************/
-/* ":xx" -> a byte */
-static char *hex_to_sj(char *from, BOOL overwrite)
-{
- char *sp, *dp;
-
- sp = (char *) from;
- dp = cvtbuf;
- while (*sp) {
- if (*sp == hex_tag && isxdigit (sp[1]) && isxdigit (sp[2])) {
- *dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2]));
- sp += 3;
- } else
- *dp++ = *sp++;
- }
- *dp = '\0';
- if (overwrite) {
- strcpy ((char *) from, (char *) cvtbuf);
- return (char *) from;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- kanji/kana -> ":xx"
-********************************************************************/
-static char *sj_to_hex(char *from, BOOL overwrite)
-{
- unsigned char *sp, *dp;
-
- sp = (unsigned char*) from;
- dp = (unsigned char*) cvtbuf;
- while (*sp) {
- if (is_kana(*sp)) {
- *dp++ = hex_tag;
- *dp++ = bin2hex (((*sp)>>4)&0x0f);
- *dp++ = bin2hex ((*sp)&0x0f);
- sp++;
- } else if (is_shift_jis (*sp) && is_shift_jis2 (sp[1])) {
- *dp++ = hex_tag;
- *dp++ = bin2hex (((*sp)>>4)&0x0f);
- *dp++ = bin2hex ((*sp)&0x0f);
- sp++;
- *dp++ = hex_tag;
- *dp++ = bin2hex (((*sp)>>4)&0x0f);
- *dp++ = bin2hex ((*sp)&0x0f);
- sp++;
- } else
- *dp++ = *sp++;
- }
- *dp = '\0';
- if (overwrite) {
- strcpy ((char *) from, (char *) cvtbuf);
- return (char *) from;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- kanji/kana -> ":xx"
-********************************************************************/
-static char *sj_to_cap(char *from, BOOL overwrite)
-{
- unsigned char *sp, *dp;
-
- sp = (unsigned char*) from;
- dp = (unsigned char*) cvtbuf;
- while (*sp) {
- if (*sp >= 0x80) {
- *dp++ = hex_tag;
- *dp++ = bin2hex (((*sp)>>4)&0x0f);
- *dp++ = bin2hex ((*sp)&0x0f);
- sp++;
- } else {
- *dp++ = *sp++;
- }
- }
- *dp = '\0';
- if (overwrite) {
- strcpy ((char *) from, (char *) cvtbuf);
- return (char *) from;
- } else {
- return cvtbuf;
- }
-}
-
-/*******************************************************************
- sj to sj
-********************************************************************/
-static char *sj_to_sj(char *from, BOOL overwrite)
-{
- if (!overwrite) {
- strcpy (cvtbuf, (char *) from);
- return cvtbuf;
- } else {
- return (char *) from;
- }
-}
-
-/************************************************************************
- conversion:
- _dos_to_unix _unix_to_dos
-************************************************************************/
-
-char *(*_dos_to_unix)(char *str, BOOL overwrite) = sj_to_sj;
-char *(*_unix_to_dos)(char *str, BOOL overwrite) = sj_to_sj;
-
-static int setup_string_function(int codes)
-{
- switch (codes) {
- default:
- case SJIS_CODE:
- _dos_to_unix = sj_to_sj;
- _unix_to_dos = sj_to_sj;
-
- break;
-
- case EUC_CODE:
- _dos_to_unix = sj_to_euc;
- _unix_to_dos = euc_to_sj;
- break;
-
- case JIS7_CODE:
- _dos_to_unix = sj_to_jis7;
- _unix_to_dos = jis7_to_sj;
- break;
-
- case JIS8_CODE:
- _dos_to_unix = sj_to_jis8;
- _unix_to_dos = jis8_to_sj;
- break;
-
- case JUNET_CODE:
- _dos_to_unix = sj_to_junet;
- _unix_to_dos = junet_to_sj;
- break;
-
- case HEX_CODE:
- _dos_to_unix = sj_to_hex;
- _unix_to_dos = hex_to_sj;
- break;
-
- case CAP_CODE:
- _dos_to_unix = sj_to_cap;
- _unix_to_dos = hex_to_sj;
- break;
- }
- return codes;
-}
-
-/*
- * Interpret coding system.
- */
-int interpret_coding_system(char *str, int def)
-{
- int codes = def;
-
- if (strequal (str, "sjis")) {
- codes = SJIS_CODE;
- } else if (strequal (str, "euc")) {
- codes = EUC_CODE;
- } else if (strequal (str, "cap")) {
- codes = CAP_CODE;
- hex_tag = HEXTAG;
- } else if (strequal (str, "hex")) {
- codes = HEX_CODE;
- hex_tag = HEXTAG;
- } else if (strncasecmp (str, "hex", 3)) {
- codes = HEX_CODE;
- hex_tag = (str[3] ? str[3] : HEXTAG);
- } else if (strequal (str, "j8bb")) {
- codes = JIS8_CODE;
- jis_kso = 'B';
- jis_ksi = 'B';
- } else if (strequal (str, "j8bj") || strequal (str, "jis8")) {
- codes = JIS8_CODE;
- jis_kso = 'B';
- jis_ksi = 'J';
- } else if (strequal (str, "j8bh")) {
- codes = JIS8_CODE;
- jis_kso = 'B';
- jis_ksi = 'H';
- } else if (strequal (str, "j8@b")) {
- codes = JIS8_CODE;
- jis_kso = '@';
- jis_ksi = 'B';
- } else if (strequal (str, "j8@j")) {
- codes = JIS8_CODE;
- jis_kso = '@';
- jis_ksi = 'J';
- } else if (strequal (str, "j8@h")) {
- codes = JIS8_CODE;
- jis_kso = '@';
- jis_ksi = 'H';
- } else if (strequal (str, "j7bb")) {
- codes = JIS7_CODE;
- jis_kso = 'B';
- jis_ksi = 'B';
- } else if (strequal (str, "j7bj") || strequal (str, "jis7")) {
- codes = JIS7_CODE;
- jis_kso = 'B';
- jis_ksi = 'J';
- } else if (strequal (str, "j7bh")) {
- codes = JIS7_CODE;
- jis_kso = 'B';
- jis_ksi = 'H';
- } else if (strequal (str, "j7@b")) {
- codes = JIS7_CODE;
- jis_kso = '@';
- jis_ksi = 'B';
- } else if (strequal (str, "j7@j")) {
- codes = JIS7_CODE;
- jis_kso = '@';
- jis_ksi = 'J';
- } else if (strequal (str, "j7@h")) {
- codes = JIS7_CODE;
- jis_kso = '@';
- jis_ksi = 'H';
- } else if (strequal (str, "jubb")) {
- codes = JUNET_CODE;
- jis_kso = 'B';
- jis_ksi = 'B';
- } else if (strequal (str, "jubj") || strequal (str, "junet")) {
- codes = JUNET_CODE;
- jis_kso = 'B';
- jis_ksi = 'J';
- } else if (strequal (str, "jubh")) {
- codes = JUNET_CODE;
- jis_kso = 'B';
- jis_ksi = 'H';
- } else if (strequal (str, "ju@b")) {
- codes = JUNET_CODE;
- jis_kso = '@';
- jis_ksi = 'B';
- } else if (strequal (str, "ju@j")) {
- codes = JUNET_CODE;
- jis_kso = '@';
- jis_ksi = 'J';
- } else if (strequal (str, "ju@h")) {
- codes = JUNET_CODE;
- jis_kso = '@';
- jis_ksi = 'H';
- }
- return setup_string_function (codes);
-}
diff --git a/source/lib/md4.c b/source/lib/md4.c
deleted file mode 100644
index 1c9c2e6ecd5..00000000000
--- a/source/lib/md4.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- a implementation of MD4 designed for use in the SMB authentication protocol
- Copyright (C) Andrew Tridgell 1997
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-
-/* NOTE: This code makes no attempt to be fast!
-
- It assumes that a int is at least 32 bits long
-*/
-
-typedef unsigned int uint32;
-
-static uint32 A, B, C, D;
-
-static uint32 F(uint32 X, uint32 Y, uint32 Z)
-{
- return (X&Y) | ((~X)&Z);
-}
-
-static uint32 G(uint32 X, uint32 Y, uint32 Z)
-{
- return (X&Y) | (X&Z) | (Y&Z);
-}
-
-static uint32 H(uint32 X, uint32 Y, uint32 Z)
-{
- return X^Y^Z;
-}
-
-static uint32 lshift(uint32 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)0x5A827999,s)
-#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (uint32)0x6ED9EBA1,s)
-
-/* this applies md4 to 64 byte chunks */
-static void mdfour64(uint32 *M)
-{
- int j;
- uint32 AA, BB, CC, DD;
- uint32 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 *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 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 M[16];
- uint32 b = n * 8;
- int i;
-
- A = 0x67452301;
- B = 0xefcdab89;
- C = 0x98badcfe;
- D = 0x10325476;
-
- while (n > 64) {
- copy64(M, in);
- mdfour64(M);
- in += 64;
- n -= 64;
- }
-
- for (i=0;i<128;i++)
- buf[i] = 0;
- memcpy(buf, in, n);
- buf[n] = 0x80;
-
- if (n <= 55) {
- copy4(buf+56, b);
- copy64(M, buf);
- mdfour64(M);
- } else {
- copy4(buf+120, b);
- copy64(M, buf);
- mdfour64(M);
- copy64(M, buf+64);
- mdfour64(M);
- }
-
- for (i=0;i<128;i++)
- buf[i] = 0;
- copy64(M, buf);
-
- copy4(out, A);
- copy4(out+4, B);
- copy4(out+8, C);
- copy4(out+12, D);
-
- A = B = C = D = 0;
-}
-
-
diff --git a/source/lib/replace.c b/source/lib/replace.c
deleted file mode 100644
index 67c18a15237..00000000000
--- a/source/lib/replace.c
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- replacement routines for broken systems
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-
-#include "includes.h"
-
-extern int DEBUGLEVEL;
-
-
- void replace_dummy(void)
-{}
-
-#ifdef REPLACE_STRLEN
-/****************************************************************************
-a replacement strlen() that returns int for solaris
-****************************************************************************/
- int Strlen(char *s)
-{
- int ret=0;
- if (!s) return(0);
- while (*s++) ret++;
- return(ret);
-}
-#endif
-
-#ifdef NO_FTRUNCATE
- /*******************************************************************
-ftruncate for operating systems that don't have it
-********************************************************************/
- int ftruncate(int f,long l)
-{
- struct flock fl;
-
- fl.l_whence = 0;
- fl.l_len = 0;
- fl.l_start = l;
- fl.l_type = F_WRLCK;
- return fcntl(f, F_FREESP, &fl);
-}
-#endif
-
-
-#ifdef REPLACE_STRSTR
-/****************************************************************************
-Mips version of strstr doesn't seem to work correctly.
-There is a #define in includes.h to redirect calls to this function.
-****************************************************************************/
-char *Strstr(char *s, char *p)
-{
- int len = strlen(p);
-
- while ( *s != '\0' ) {
- if ( strncmp(s, p, len) == 0 )
- return s;
- s++;
- }
-
- return NULL;
-}
-#endif /* REPLACE_STRSTR */
-
-
-#ifdef REPLACE_MKTIME
-/*******************************************************************
-a mktime() replacement for those who don't have it - contributed by
-C.A. Lademann <cal@zls.com>
-********************************************************************/
-#define MINUTE 60
-#define HOUR 60*MINUTE
-#define DAY 24*HOUR
-#define YEAR 365*DAY
-time_t Mktime(struct tm *t)
-{
- struct tm *u;
- time_t epoch = 0;
- int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
- y, m, i;
-
- if(t->tm_year < 70)
- return((time_t)-1);
-
- epoch = (t->tm_year - 70) * YEAR +
- (t->tm_year / 4 - 70 / 4 - t->tm_year / 100) * DAY;
-
- y = t->tm_year;
- m = 0;
-
- for(i = 0; i < t->tm_mon; i++) {
- epoch += mon [m] * DAY;
- if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
- epoch += DAY;
-
- if(++m > 11) {
- m = 0;
- y++;
- }
- }
-
- epoch += (t->tm_mday - 1) * DAY;
- epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec;
-
- if((u = localtime(&epoch)) != NULL) {
- t->tm_sec = u->tm_sec;
- t->tm_min = u->tm_min;
- t->tm_hour = u->tm_hour;
- t->tm_mday = u->tm_mday;
- t->tm_mon = u->tm_mon;
- t->tm_year = u->tm_year;
- t->tm_wday = u->tm_wday;
- t->tm_yday = u->tm_yday;
- t->tm_isdst = u->tm_isdst;
-#ifndef NO_TM_NAME
- memcpy(t->tm_name, u->tm_name, LTZNMAX);
-#endif
- }
-
- return(epoch);
-}
-#endif /* REPLACE_MKTIME */
-
-
-
-#ifdef REPLACE_RENAME
-/* Rename a file. (from libiberty in GNU binutils) */
- int rename (zfrom, zto)
- const char *zfrom;
- const char *zto;
-{
- if (link (zfrom, zto) < 0)
- {
- if (errno != EEXIST)
- return -1;
- if (unlink (zto) < 0
- || link (zfrom, zto) < 0)
- return -1;
- }
- return unlink (zfrom);
-}
-#endif
-
-
-#ifdef REPLACE_INNETGR
-/*
- * Search for a match in a netgroup. This replaces it on broken systems.
- */
-int InNetGr(char *group,char *host,char *user,char *dom)
-{
- char *hst, *usr, *dm;
-
- setnetgrent(group);
- while (getnetgrent(&hst, &usr, &dm))
- if (((host == 0) || (hst == 0) || !strcmp(host, hst)) &&
- ((user == 0) || (usr == 0) || !strcmp(user, usr)) &&
- ((dom == 0) || (dm == 0) || !strcmp(dom, dm))) {
- endnetgrent();
- return (1);
- }
- endnetgrent();
- return (0);
-}
-#endif
-
-
-
-#ifdef NO_INITGROUPS
-#include <sys/types.h>
-#include <limits.h>
-#include <grp.h>
-
-#ifndef NULL
-#define NULL (void *)0
-#endif
-
-/****************************************************************************
- some systems don't have an initgroups call
-****************************************************************************/
- int initgroups(char *name,gid_t id)
-{
-#ifdef NO_SETGROUPS
- /* yikes! no SETGROUPS or INITGROUPS? how can this work? */
- return(0);
-#else
- gid_t grouplst[NGROUPS_MAX];
- int i,j;
- struct group *g;
- char *gr;
-
- grouplst[0] = id;
- i = 1;
- while (i < NGROUPS_MAX &&
- ((g = (struct group *)getgrent()) != (struct group *)NULL))
- {
- if (g->gr_gid == id)
- continue;
- j = 0;
- gr = g->gr_mem[0];
- while (gr && (*gr != (char)NULL)) {
- if (strcmp(name,gr) == 0) {
- grouplst[i] = g->gr_gid;
- i++;
- gr = (char *)NULL;
- break;
- }
- gr = g->gr_mem[++j];
- }
- }
- endgrent();
- return(setgroups(i,grouplst));
-#endif
-}
-#endif
-
-
-#if (defined(SecureWare) && defined(SCO))
-/* This is needed due to needing the nap() function but we don't want
- to include the Xenix libraries since that will break other things...
- BTW: system call # 0x0c28 is the same as calling nap() */
-long nap(long milliseconds) {
- return syscall(0x0c28, milliseconds);
-}
-#endif
-
-
-
-#if WRAP_MALLOC
-
-/* undo the wrapping temporarily */
-#undef malloc
-#undef realloc
-#undef free
-
-/****************************************************************************
-wrapper for malloc() to catch memory errors
-****************************************************************************/
-void *malloc_wrapped(int size,char *file,int line)
-{
-#ifdef xx_old_malloc
- void *res = xx_old_malloc(size);
-#else
- void *res = malloc(size);
-#endif
- DEBUG(3,("Malloc called from %s(%d) with size=%d gave ptr=0x%X\n",
- file,line,
- size,(unsigned int)res));
- return(res);
-}
-
-/****************************************************************************
-wrapper for realloc() to catch memory errors
-****************************************************************************/
-void *realloc_wrapped(void *ptr,int size,char *file,int line)
-{
-#ifdef xx_old_realloc
- void *res = xx_old_realloc(ptr,size);
-#else
- void *res = realloc(ptr,size);
-#endif
- DEBUG(3,("Realloc\n"));
- DEBUG(3,("free called from %s(%d) with ptr=0x%X\n",
- file,line,
- (unsigned int)ptr));
- DEBUG(3,("Malloc called from %s(%d) with size=%d gave ptr=0x%X\n",
- file,line,
- size,(unsigned int)res));
- return(res);
-}
-
-/****************************************************************************
-wrapper for free() to catch memory errors
-****************************************************************************/
-void free_wrapped(void *ptr,char *file,int line)
-{
-#ifdef xx_old_free
- xx_old_free(ptr);
-#else
- free(ptr);
-#endif
- DEBUG(3,("free called from %s(%d) with ptr=0x%X\n",
- file,line,(unsigned int)ptr));
- return;
-}
-
-/* and re-do the define for spots lower in this file */
-#define malloc(size) malloc_wrapped(size,__FILE__,__LINE__)
-#define realloc(ptr,size) realloc_wrapped(ptr,size,__FILE__,__LINE__)
-#define free(ptr) free_wrapped(ptr,__FILE__,__LINE__)
-
-#endif
-
-
-#if WRAP_MEMCPY
-#undef memcpy
-/*******************************************************************
-a wrapper around memcpy for diagnostic purposes
-********************************************************************/
-void *memcpy_wrapped(void *d,void *s,int l,char *fname,int line)
-{
- if (l>64 && (((int)d)%4) != (((int)s)%4))
- DEBUG(4,("Misaligned memcpy(0x%X,0x%X,%d) at %s(%d)\n",d,s,l,fname,line));
-#ifdef xx_old_memcpy
- return(xx_old_memcpy(d,s,l));
-#else
- return(memcpy(d,s,l));
-#endif
-}
-#define memcpy(d,s,l) memcpy_wrapped(d,s,l,__FILE__,__LINE__)
-#endif
-
diff --git a/source/lib/system.c b/source/lib/system.c
deleted file mode 100644
index fe8e8004d04..00000000000
--- a/source/lib/system.c
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Samba system utilities
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-
-#include "includes.h"
-
-extern int DEBUGLEVEL;
-
-/*
- The idea is that this file will eventually have wrappers around all
- important system calls in samba. The aims are:
-
- - to enable easier porting by putting OS dependent stuff in here
-
- - to allow for hooks into other "pseudo-filesystems"
-
- - to allow easier integration of things like the japanese extensions
-
- - to support the philosophy of Samba to expose the features of
- the OS within the SMB model. In general whatever file/printer/variable
- expansions/etc make sense to the OS should be acceptable to Samba.
-*/
-
-
-/*******************************************************************
-this replaces the normal select() system call
-return if some data has arrived on one of the file descriptors
-return -1 means error
-********************************************************************/
-#ifdef NO_SELECT
-static int pollfd(int fd)
-{
- int r=0;
-
-#ifdef HAS_RDCHK
- r = rdchk(fd);
-#elif defined(TCRDCHK)
- (void)ioctl(fd, TCRDCHK, &r);
-#else
- (void)ioctl(fd, FIONREAD, &r);
-#endif
-
- return(r);
-}
-
-int sys_select(fd_set *fds,struct timeval *tval)
-{
- fd_set fds2;
- int counter=0;
- int found=0;
-
- FD_ZERO(&fds2);
-
- while (1)
- {
- int i;
- for (i=0;i<255;i++) {
- if (FD_ISSET(i,fds) && pollfd(i)>0) {
- found++;
- FD_SET(i,&fds2);
- }
- }
-
- if (found) {
- memcpy((void *)fds,(void *)&fds2,sizeof(fds2));
- return(found);
- }
-
- if (tval && tval->tv_sec < counter) return(0);
- sleep(1);
- counter++;
- }
-}
-
-#else
-int sys_select(fd_set *fds,struct timeval *tval)
-{
- struct timeval t2;
- int selrtn;
-
- do {
- if (tval) memcpy((void *)&t2,(void *)tval,sizeof(t2));
- errno = 0;
- selrtn = select(255,SELECT_CAST fds,NULL,NULL,tval?&t2:NULL);
- } while (selrtn<0 && errno == EINTR);
-
- return(selrtn);
-}
-#endif
-
-
-/*******************************************************************
-just a unlink wrapper
-********************************************************************/
-int sys_unlink(char *fname)
-{
- return(unlink(dos_to_unix(fname,False)));
-}
-
-
-/*******************************************************************
-a simple open() wrapper
-********************************************************************/
-int sys_open(char *fname,int flags,int mode)
-{
- return(open(dos_to_unix(fname,False),flags,mode));
-}
-
-
-/*******************************************************************
-a simple opendir() wrapper
-********************************************************************/
-DIR *sys_opendir(char *dname)
-{
- return(opendir(dos_to_unix(dname,False)));
-}
-
-
-/*******************************************************************
-and a stat() wrapper
-********************************************************************/
-int sys_stat(char *fname,struct stat *sbuf)
-{
- return(stat(dos_to_unix(fname,False),sbuf));
-}
-
-/*******************************************************************
-The wait() calls vary between systems
-********************************************************************/
-int sys_waitpid(pid_t pid,int *status,int options)
-{
-#ifdef USE_WAITPID
- return waitpid(pid,status,options);
-#else /* USE_WAITPID */
- return wait4(pid, status, options, NULL);
-#endif /* USE_WAITPID */
-}
-
-/*******************************************************************
-don't forget lstat()
-********************************************************************/
-int sys_lstat(char *fname,struct stat *sbuf)
-{
- return(lstat(dos_to_unix(fname,False),sbuf));
-}
-
-
-/*******************************************************************
-mkdir() gets a wrapper
-********************************************************************/
-int sys_mkdir(char *dname,int mode)
-{
- return(mkdir(dos_to_unix(dname,False),mode));
-}
-
-
-/*******************************************************************
-do does rmdir()
-********************************************************************/
-int sys_rmdir(char *dname)
-{
- return(rmdir(dos_to_unix(dname,False)));
-}
-
-
-/*******************************************************************
-I almost forgot chdir()
-********************************************************************/
-int sys_chdir(char *dname)
-{
- return(chdir(dos_to_unix(dname,False)));
-}
-
-
-/*******************************************************************
-now for utime()
-********************************************************************/
-int sys_utime(char *fname,struct utimbuf *times)
-{
- return(utime(dos_to_unix(fname,False),times));
-}
-
-/*********************************************************
-for rename across filesystems Patch from Warren Birnbaum
-<warrenb@hpcvscdp.cv.hp.com>
-**********************************************************/
-
-static int copy_reg(char *source, const char *dest)
-{
- struct stat source_stats;
- int ifd;
- int full_write();
- int safe_read();
- int ofd;
- char *buf;
- int len; /* Number of bytes read into `buf'. */
-
- lstat (source, &source_stats);
- if (!S_ISREG (source_stats.st_mode))
- {
- return 1;
- }
-
- if (unlink (dest) && errno != ENOENT)
- {
- return 1;
- }
-
- if((ifd = open (source, O_RDONLY, 0)) < 0)
- {
- return 1;
- }
- if((ofd = open (dest, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0 )
- {
- close (ifd);
- return 1;
- }
-
- if((buf = malloc( COPYBUF_SIZE )) == NULL)
- {
- close (ifd);
- close (ofd);
- unlink (dest);
- return 1;
- }
-
- while ((len = read(ifd, buf, COPYBUF_SIZE)) > 0)
- {
- if (write_data(ofd, buf, len) < 0)
- {
- close (ifd);
- close (ofd);
- unlink (dest);
- free(buf);
- return 1;
- }
- }
- free(buf);
- if (len < 0)
- {
- close (ifd);
- close (ofd);
- unlink (dest);
- return 1;
- }
-
- if (close (ifd) < 0)
- {
- close (ofd);
- return 1;
- }
- if (close (ofd) < 0)
- {
- return 1;
- }
-
- /* chown turns off set[ug]id bits for non-root,
- so do the chmod last. */
-
- /* Try to copy the old file's modtime and access time. */
- {
- struct utimbuf tv;
-
- tv.actime = source_stats.st_atime;
- tv.modtime = source_stats.st_mtime;
- if (utime (dest, &tv))
- {
- return 1;
- }
- }
-
- /* Try to preserve ownership. For non-root it might fail, but that's ok.
- But root probably wants to know, e.g. if NFS disallows it. */
- if (chown (dest, source_stats.st_uid, source_stats.st_gid)
- && (errno != EPERM))
- {
- return 1;
- }
-
- if (chmod (dest, source_stats.st_mode & 07777))
- {
- return 1;
- }
- unlink (source);
- return 0;
-}
-
-/*******************************************************************
-for rename()
-********************************************************************/
-int sys_rename(char *from, char *to)
-{
- int rcode;
- pstring zfrom, zto;
-
- pstrcpy (zfrom, dos_to_unix (from, False));
- pstrcpy (zto, dos_to_unix (to, False));
- rcode = rename (zfrom, zto);
-
- if (errno == EXDEV)
- {
- /* Rename across filesystems needed. */
- rcode = copy_reg (zfrom, zto);
- }
- return rcode;
-}
-
-/*******************************************************************
-for chmod
-********************************************************************/
-int sys_chmod(char *fname,int mode)
-{
- return(chmod(dos_to_unix(fname,False),mode));
-}
-
-/*******************************************************************
-for getwd
-********************************************************************/
-char *sys_getwd(char *s)
-{
- char *wd;
-#ifdef USE_GETCWD
- wd = (char *) getcwd (s, sizeof (pstring));
-#else
- wd = (char *) getwd (s);
-#endif
- if (wd)
- unix_to_dos (wd, True);
- return wd;
-}
-
-/*******************************************************************
-chown isn't used much but OS/2 doesn't have it
-********************************************************************/
-int sys_chown(char *fname,int uid,int gid)
-{
-#ifdef NO_CHOWN
- DEBUG(1,("Warning - chown(%s,%d,%d) not done\n",fname,uid,gid));
-#else
- return(chown(fname,uid,gid));
-#endif
-}
-
-/*******************************************************************
-os/2 also doesn't have chroot
-********************************************************************/
-int sys_chroot(char *dname)
-{
-#ifdef NO_CHROOT
- DEBUG(1,("Warning - chroot(%s) not done\n",dname));
-#else
- return(chroot(dname));
-#endif
-}
-
-/**************************************************************************
-A wrapper for gethostbyname() that tries avoids looking up hostnames
-in the root domain, which can cause dial-on-demand links to come up for no
-apparent reason.
-****************************************************************************/
-struct hostent *sys_gethostbyname(char *name)
-{
-#ifdef REDUCE_ROOT_DNS_LOOKUPS
- char query[256], hostname[256];
- char *domain;
-
- /* Does this name have any dots in it? If so, make no change */
-
- if (strchr(name, '.'))
- return(gethostbyname(name));
-
- /* Get my hostname, which should have domain name
- attached. If not, just do the gethostname on the
- original string.
- */
-
- gethostname(hostname, sizeof(hostname) - 1);
- hostname[sizeof(hostname) - 1] = 0;
- if ((domain = strchr(hostname, '.')) == NULL)
- return(gethostbyname(name));
-
- /* Attach domain name to query and do modified query.
- If names too large, just do gethostname on the
- original string.
- */
-
- if((strlen(name) + strlen(domain)) >= sizeof(query))
- return(gethostbyname(name));
-
- sprintf(query, "%s%s", name, domain);
- return(gethostbyname(query));
-#else /* REDUCE_ROOT_DNS_LOOKUPS */
- return(gethostbyname(name));
-#endif /* REDUCE_ROOT_DNS_LOOKUPS */
-}
-
diff --git a/source/lib/time.c b/source/lib/time.c
deleted file mode 100644
index 4f688d2214a..00000000000
--- a/source/lib/time.c
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- time handling functions
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-
-#include "includes.h"
-
-/*
- This stuff was largely rewritten by Paul Eggert <eggert@twinsun.com>
- in May 1996
- */
-
-
-int serverzone=0;
-int extra_time_offset = 0;
-
-extern int DEBUGLEVEL;
-
-#ifndef CHAR_BIT
-#define CHAR_BIT 8
-#endif
-
-#ifndef TIME_T_MIN
-#define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
- : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
-#endif
-#ifndef TIME_T_MAX
-#define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
-#endif
-
-
-
-/*******************************************************************
-a gettimeofday wrapper
-********************************************************************/
-void GetTimeOfDay(struct timeval *tval)
-{
-#ifdef GETTIMEOFDAY1
- gettimeofday(tval);
-#else
- gettimeofday(tval,NULL);
-#endif
-}
-
-#define TM_YEAR_BASE 1900
-
-/*******************************************************************
-yield the difference between *A and *B, in seconds, ignoring leap seconds
-********************************************************************/
-static int tm_diff(struct tm *a, struct tm *b)
-{
- int ay = a->tm_year + (TM_YEAR_BASE - 1);
- int by = b->tm_year + (TM_YEAR_BASE - 1);
- int intervening_leap_days =
- (ay/4 - by/4) - (ay/100 - by/100) + (ay/400 - by/400);
- int years = ay - by;
- int days = 365*years + intervening_leap_days + (a->tm_yday - b->tm_yday);
- int hours = 24*days + (a->tm_hour - b->tm_hour);
- int minutes = 60*hours + (a->tm_min - b->tm_min);
- int seconds = 60*minutes + (a->tm_sec - b->tm_sec);
- return seconds;
-}
-
-/*******************************************************************
- return the UTC offset in seconds west of UTC
- ******************************************************************/
-static int TimeZone(time_t t)
-{
- struct tm tm_utc = *(gmtime(&t));
- return tm_diff(&tm_utc,localtime(&t));
-}
-
-
-/*******************************************************************
-init the time differences
-********************************************************************/
-void TimeInit(void)
-{
- serverzone = TimeZone(time(NULL));
- DEBUG(4,("Serverzone is %d\n",serverzone));
-}
-
-
-/*******************************************************************
-return the same value as TimeZone, but it should be more efficient.
-
-We keep a table of DST offsets to prevent calling localtime() on each
-call of this function. This saves a LOT of time on many unixes.
-
-Updated by Paul Eggert <eggert@twinsun.com>
-********************************************************************/
-static int TimeZoneFaster(time_t t)
-{
- static struct dst_table {time_t start,end; int zone;} *dst_table = NULL;
- static int table_size = 0;
- int i;
- int zone = 0;
-
- if (t == 0) t = time(NULL);
-
- /* Tunis has a 8 day DST region, we need to be careful ... */
-#define MAX_DST_WIDTH (365*24*60*60)
-#define MAX_DST_SKIP (7*24*60*60)
-
- for (i=0;i<table_size;i++)
- if (t >= dst_table[i].start && t <= dst_table[i].end) break;
-
- if (i<table_size) {
- zone = dst_table[i].zone;
- } else {
- time_t low,high;
-
- zone = TimeZone(t);
- dst_table = (struct dst_table *)Realloc(dst_table,
- sizeof(dst_table[0])*(i+1));
- if (!dst_table) {
- table_size = 0;
- } else {
- table_size++;
-
- dst_table[i].zone = zone;
- dst_table[i].start = dst_table[i].end = t;
-
- /* no entry will cover more than 6 months */
- low = t - MAX_DST_WIDTH/2;
- if (t < low)
- low = TIME_T_MIN;
-
- high = t + MAX_DST_WIDTH/2;
- if (high < t)
- high = TIME_T_MAX;
-
- /* widen the new entry using two bisection searches */
- while (low+60*60 < dst_table[i].start) {
- if (dst_table[i].start - low > MAX_DST_SKIP*2)
- t = dst_table[i].start - MAX_DST_SKIP;
- else
- t = low + (dst_table[i].start-low)/2;
- if (TimeZone(t) == zone)
- dst_table[i].start = t;
- else
- low = t;
- }
-
- while (high-60*60 > dst_table[i].end) {
- if (high - dst_table[i].end > MAX_DST_SKIP*2)
- t = dst_table[i].end + MAX_DST_SKIP;
- else
- t = high - (high-dst_table[i].end)/2;
- if (TimeZone(t) == zone)
- dst_table[i].end = t;
- else
- high = t;
- }
-#if 0
- DEBUG(1,("Added DST entry from %s ",
- asctime(localtime(&dst_table[i].start))));
- DEBUG(1,("to %s (%d)\n",asctime(localtime(&dst_table[i].end)),
- dst_table[i].zone));
-#endif
- }
- }
- return zone;
-}
-
-/****************************************************************************
- return the UTC offset in seconds west of UTC, adjusted for extra time offset
- **************************************************************************/
-int TimeDiff(time_t t)
-{
- return TimeZoneFaster(t) + 60*extra_time_offset;
-}
-
-
-/****************************************************************************
- return the UTC offset in seconds west of UTC, adjusted for extra time
- offset, for a local time value. If ut = lt + LocTimeDiff(lt), then
- lt = ut - TimeDiff(ut), but the converse does not necessarily hold near
- daylight savings transitions because some local times are ambiguous.
- LocTimeDiff(t) equals TimeDiff(t) except near daylight savings transitions.
- +**************************************************************************/
-static int LocTimeDiff(time_t lte)
-{
- time_t lt = lte - 60*extra_time_offset;
- int d = TimeZoneFaster(lt);
- time_t t = lt + d;
-
- /* if overflow occurred, ignore all the adjustments so far */
- if (((lte < lt) ^ (extra_time_offset < 0)) | ((t < lt) ^ (d < 0)))
- t = lte;
-
- /* now t should be close enough to the true UTC to yield the right answer */
- return TimeDiff(t);
-}
-
-
-/****************************************************************************
-try to optimise the localtime call, it can be quite expenive on some machines
-****************************************************************************/
-struct tm *LocalTime(time_t *t)
-{
- time_t t2 = *t;
-
- t2 -= TimeDiff(t2);
-
- return(gmtime(&t2));
-}
-
-
-#define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
-
-/****************************************************************************
-interpret an 8 byte "filetime" structure to a time_t
-It's originally in "100ns units since jan 1st 1601"
-
-It appears to be kludge-GMT (at least for file listings). This means
-its the GMT you get by taking a localtime and adding the
-serverzone. This is NOT the same as GMT in some cases. This routine
-converts this to real GMT.
-****************************************************************************/
-time_t interpret_long_date(char *p)
-{
- double d;
- time_t ret;
- uint32 tlow,thigh;
- tlow = IVAL(p,0);
- thigh = IVAL(p,4);
-
- if (thigh == 0) return(0);
-
- d = ((double)thigh)*4.0*(double)(1<<30);
- d += (tlow&0xFFF00000);
- d *= 1.0e-7;
-
- /* now adjust by 369 years to make the secs since 1970 */
- d -= TIME_FIXUP_CONSTANT;
-
- if (!(TIME_T_MIN <= d && d <= TIME_T_MAX))
- return(0);
-
- ret = (time_t)(d+0.5);
-
- /* this takes us from kludge-GMT to real GMT */
- ret -= serverzone;
- ret += LocTimeDiff(ret);
-
- return(ret);
-}
-
-
-/****************************************************************************
-put a 8 byte filetime from a time_t
-This takes real GMT as input and converts to kludge-GMT
-****************************************************************************/
-void put_long_date(char *p,time_t t)
-{
- uint32 tlow,thigh;
- double d;
-
- if (t==0) {
- SIVAL(p,0,0); SIVAL(p,4,0);
- return;
- }
-
- /* this converts GMT to kludge-GMT */
- t -= TimeDiff(t) - serverzone;
-
- d = (double) (t);
-
- d += TIME_FIXUP_CONSTANT;
-
- d *= 1.0e7;
-
- thigh = (uint32)(d * (1.0/(4.0*(double)(1<<30))));
- tlow = (uint32)(d - ((double)thigh)*4.0*(double)(1<<30));
-
- SIVAL(p,0,tlow);
- SIVAL(p,4,thigh);
-}
-
-
-/****************************************************************************
-check if it's a null mtime
-****************************************************************************/
-static BOOL null_mtime(time_t mtime)
-{
- if (mtime == 0 || mtime == 0xFFFFFFFF || mtime == (time_t)-1)
- return(True);
- return(False);
-}
-
-/*******************************************************************
- create a 16 bit dos packed date
-********************************************************************/
-static uint16 make_dos_date1(time_t unixdate,struct tm *t)
-{
- uint16 ret=0;
- ret = (((unsigned)(t->tm_mon+1)) >> 3) | ((t->tm_year-80) << 1);
- ret = ((ret&0xFF)<<8) | (t->tm_mday | (((t->tm_mon+1) & 0x7) << 5));
- return(ret);
-}
-
-/*******************************************************************
- create a 16 bit dos packed time
-********************************************************************/
-static uint16 make_dos_time1(time_t unixdate,struct tm *t)
-{
- uint16 ret=0;
- ret = ((((unsigned)t->tm_min >> 3)&0x7) | (((unsigned)t->tm_hour) << 3));
- ret = ((ret&0xFF)<<8) | ((t->tm_sec/2) | ((t->tm_min & 0x7) << 5));
- return(ret);
-}
-
-/*******************************************************************
- create a 32 bit dos packed date/time from some parameters
- This takes a GMT time and returns a packed localtime structure
-********************************************************************/
-static uint32 make_dos_date(time_t unixdate)
-{
- struct tm *t;
- uint32 ret=0;
-
- t = LocalTime(&unixdate);
-
- ret = make_dos_date1(unixdate,t);
- ret = ((ret&0xFFFF)<<16) | make_dos_time1(unixdate,t);
-
- return(ret);
-}
-
-/*******************************************************************
-put a dos date into a buffer (time/date format)
-This takes GMT time and puts local time in the buffer
-********************************************************************/
-void put_dos_date(char *buf,int offset,time_t unixdate)
-{
- uint32 x = make_dos_date(unixdate);
- SIVAL(buf,offset,x);
-}
-
-/*******************************************************************
-put a dos date into a buffer (date/time format)
-This takes GMT time and puts local time in the buffer
-********************************************************************/
-void put_dos_date2(char *buf,int offset,time_t unixdate)
-{
- uint32 x = make_dos_date(unixdate);
- x = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16);
- SIVAL(buf,offset,x);
-}
-
-/*******************************************************************
-put a dos 32 bit "unix like" date into a buffer. This routine takes
-GMT and converts it to LOCAL time before putting it (most SMBs assume
-localtime for this sort of date)
-********************************************************************/
-void put_dos_date3(char *buf,int offset,time_t unixdate)
-{
- if (!null_mtime(unixdate))
- unixdate -= TimeDiff(unixdate);
- SIVAL(buf,offset,unixdate);
-}
-
-/*******************************************************************
- interpret a 32 bit dos packed date/time to some parameters
-********************************************************************/
-static void interpret_dos_date(uint32 date,int *year,int *month,int *day,int *hour,int *minute,int *second)
-{
- uint32 p0,p1,p2,p3;
-
- p0=date&0xFF; p1=((date&0xFF00)>>8)&0xFF;
- p2=((date&0xFF0000)>>16)&0xFF; p3=((date&0xFF000000)>>24)&0xFF;
-
- *second = 2*(p0 & 0x1F);
- *minute = ((p0>>5)&0xFF) + ((p1&0x7)<<3);
- *hour = (p1>>3)&0xFF;
- *day = (p2&0x1F);
- *month = ((p2>>5)&0xFF) + ((p3&0x1)<<3) - 1;
- *year = ((p3>>1)&0xFF) + 80;
-}
-
-/*******************************************************************
- create a unix date (int GMT) from a dos date (which is actually in
- localtime)
-********************************************************************/
-time_t make_unix_date(void *date_ptr)
-{
- uint32 dos_date=0;
- struct tm t;
- time_t ret;
-
- dos_date = IVAL(date_ptr,0);
-
- if (dos_date == 0) return(0);
-
- interpret_dos_date(dos_date,&t.tm_year,&t.tm_mon,
- &t.tm_mday,&t.tm_hour,&t.tm_min,&t.tm_sec);
- t.tm_isdst = -1;
-
- /* mktime() also does the local to GMT time conversion for us */
- ret = mktime(&t);
-
- return(ret);
-}
-
-/*******************************************************************
-like make_unix_date() but the words are reversed
-********************************************************************/
-time_t make_unix_date2(void *date_ptr)
-{
- uint32 x,x2;
-
- x = IVAL(date_ptr,0);
- x2 = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16);
- SIVAL(&x,0,x2);
-
- return(make_unix_date((void *)&x));
-}
-
-/*******************************************************************
- create a unix GMT date from a dos date in 32 bit "unix like" format
- these generally arrive as localtimes, with corresponding DST
- ******************************************************************/
-time_t make_unix_date3(void *date_ptr)
-{
- time_t t = IVAL(date_ptr,0);
- if (!null_mtime(t))
- t += LocTimeDiff(t);
- return(t);
-}
-
-/****************************************************************************
-set the time on a file
-****************************************************************************/
-BOOL set_filetime(char *fname,time_t mtime)
-{
- struct utimbuf times;
-
- if (null_mtime(mtime)) return(True);
-
- times.modtime = times.actime = mtime;
-
- if (sys_utime(fname,&times)) {
- DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
- }
-
- return(True);
-}
-
-
-/****************************************************************************
- return the date and time as a string
-****************************************************************************/
-char *timestring(void )
-{
- static fstring TimeBuf;
- time_t t = time(NULL);
- struct tm *tm = LocalTime(&t);
-
-#ifdef NO_STRFTIME
- fstrcpy(TimeBuf, asctime(tm));
-#elif defined(CLIX) || defined(CONVEX)
- strftime(TimeBuf,100,"%m/%d/%y %I:%M:%S %p",tm);
-#elif defined(AMPM)
- strftime(TimeBuf,100,"%D %r",tm);
-#elif defined(TZ_TIME)
- {
- int zone = TimeDiff(t);
- int absZoneMinutes = (zone<0 ? -zone : zone) / 60;
- size_t len = strftime(TimeBuf,sizeof(TimeBuf)-6,"%D %T",tm);
- sprintf(TimeBuf+len," %c%02d%02d",
- zone<0?'+':'-',absZoneMinutes/60,absZoneMinutes%60);
- }
-#else
- strftime(TimeBuf,100,"%D %T",tm);
-#endif
- return(TimeBuf);
-}
-
diff --git a/source/lib/ufc.c b/source/lib/ufc.c
deleted file mode 100644
index 0fa5cfd3a0f..00000000000
--- a/source/lib/ufc.c
+++ /dev/null
@@ -1,782 +0,0 @@
-/*
- This bit of code was derived from the UFC-crypt package which
- carries the following copyright
-
- Modified for use by Samba by Andrew Tridgell, October 1994
-
- Note that this routine is only faster on some machines. Under Linux 1.1.51
- libc 4.5.26 I actually found this routine to be slightly slower.
-
- Under SunOS I found a huge speedup by using these routines
- (a factor of 20 or so)
-
- Warning: I've had a report from Steve Kennedy <steve@gbnet.org>
- that this crypt routine may sometimes get the wrong answer. Only
- use UFC_CRYT if you really need it.
-
-*/
-
-#ifdef UFC_CRYPT
-
-/*
- * UFC-crypt: ultra fast crypt(3) implementation
- *
- * Copyright (C) 1991-1997, Free Software Foundation, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * @(#)crypt_util.c 2.31 02/08/92
- *
- * Support routines
- *
- */
-#include "includes.h"
-
-
-#ifndef long32
-#define long32 int32
-#endif
-
-#ifndef long64
-#define long64 int64
-#endif
-
-#ifndef ufc_long
-#define ufc_long unsigned
-#endif
-
-#ifndef _UFC_64_
-#define _UFC_32_
-#endif
-
-/*
- * Permutation done once on the 56 bit
- * key derived from the original 8 byte ASCII key.
- */
-static int pc1[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
-};
-
-/*
- * How much to rotate each 28 bit half of the pc1 permutated
- * 56 bit key before using pc2 to give the i' key
- */
-static int rots[16] = {
- 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
-};
-
-/*
- * Permutation giving the key
- * of the i' DES round
- */
-static int pc2[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
-};
-
-/*
- * The E expansion table which selects
- * bits from the 32 bit intermediate result.
- */
-static int esel[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 e_inverse[64];
-
-/*
- * Permutation done on the
- * result of sbox lookups
- */
-static int perm32[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
-};
-
-/*
- * The sboxes
- */
-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 }
- }
-};
-
-/*
- * This is the final
- * permutation matrix
- */
-static int final_perm[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
-};
-
-/*
- * The 16 DES keys in BITMASK format
- */
-#ifdef _UFC_32_
-long32 _ufc_keytab[16][2];
-#endif
-
-#ifdef _UFC_64_
-long64 _ufc_keytab[16];
-#endif
-
-
-#define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.')
-#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
-
-/* Macro to set a bit (0..23) */
-#define BITMASK(i) ( (1<<(11-(i)%12+3)) << ((i)<12?16:0) )
-
-/*
- * sb arrays:
- *
- * Workhorses of the inner loop of the DES implementation.
- * They do sbox lookup, shifting of this value, 32 bit
- * permutation and E permutation for the next round.
- *
- * Kept in 'BITMASK' format.
- */
-
-#ifdef _UFC_32_
-long32 _ufc_sb0[8192], _ufc_sb1[8192], _ufc_sb2[8192], _ufc_sb3[8192];
-static long32 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3};
-#endif
-
-#ifdef _UFC_64_
-long64 _ufc_sb0[4096], _ufc_sb1[4096], _ufc_sb2[4096], _ufc_sb3[4096];
-static long64 *sb[4] = {_ufc_sb0, _ufc_sb1, _ufc_sb2, _ufc_sb3};
-#endif
-
-/*
- * eperm32tab: do 32 bit permutation and E selection
- *
- * The first index is the byte number in the 32 bit value to be permuted
- * - second - is the value of this byte
- * - third - selects the two 32 bit values
- *
- * The table is used and generated internally in init_des to speed it up
- */
-static ufc_long eperm32tab[4][256][2];
-
-/*
- * do_pc1: permform pc1 permutation in the key schedule generation.
- *
- * The first index is the byte number in the 8 byte ASCII key
- * - second - - the two 28 bits halfs of the result
- * - third - selects the 7 bits actually used of each byte
- *
- * The result is kept with 28 bit per 32 bit with the 4 most significant
- * bits zero.
- */
-static ufc_long do_pc1[8][2][128];
-
-/*
- * do_pc2: permform pc2 permutation in the key schedule generation.
- *
- * The first index is the septet number in the two 28 bit intermediate values
- * - second - - - septet values
- *
- * Knowledge of the structure of the pc2 permutation is used.
- *
- * The result is kept with 28 bit per 32 bit with the 4 most significant
- * bits zero.
- */
-static ufc_long do_pc2[8][128];
-
-/*
- * efp: undo an extra e selection and do final
- * permutation giving the DES result.
- *
- * Invoked 6 bit a time on two 48 bit values
- * giving two 32 bit longs.
- */
-static ufc_long efp[16][64][2];
-
-static unsigned char bytemask[8] = {
- 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
-};
-
-static ufc_long longmask[32] = {
- 0x80000000, 0x40000000, 0x20000000, 0x10000000,
- 0x08000000, 0x04000000, 0x02000000, 0x01000000,
- 0x00800000, 0x00400000, 0x00200000, 0x00100000,
- 0x00080000, 0x00040000, 0x00020000, 0x00010000,
- 0x00008000, 0x00004000, 0x00002000, 0x00001000,
- 0x00000800, 0x00000400, 0x00000200, 0x00000100,
- 0x00000080, 0x00000040, 0x00000020, 0x00000010,
- 0x00000008, 0x00000004, 0x00000002, 0x00000001
-};
-
-
-/*
- * Silly rewrite of 'bzero'. I do so
- * because some machines don't have
- * bzero and some don't have memset.
- */
-
-static void clearmem(start, cnt)
- char *start;
- int cnt;
- { while(cnt--)
- *start++ = '\0';
- }
-
-static int initialized = 0;
-
-/* lookup a 6 bit value in sbox */
-
-#define s_lookup(i,s) sbox[(i)][(((s)>>4) & 0x2)|((s) & 0x1)][((s)>>1) & 0xf];
-
-/*
- * Initialize unit - may be invoked directly
- * by fcrypt users.
- */
-
-static void ufc_init_des()
- { int comes_from_bit;
- int bit, sg;
- ufc_long j;
- ufc_long mask1, mask2;
-
- /*
- * Create the do_pc1 table used
- * to affect pc1 permutation
- * when generating keys
- */
- for(bit = 0; bit < 56; bit++) {
- comes_from_bit = pc1[bit] - 1;
- mask1 = bytemask[comes_from_bit % 8 + 1];
- mask2 = longmask[bit % 28 + 4];
- for(j = 0; j < 128; j++) {
- if(j & mask1)
- do_pc1[comes_from_bit / 8][bit / 28][j] |= mask2;
- }
- }
-
- /*
- * Create the do_pc2 table used
- * to affect pc2 permutation when
- * generating keys
- */
- for(bit = 0; bit < 48; bit++) {
- comes_from_bit = pc2[bit] - 1;
- mask1 = bytemask[comes_from_bit % 7 + 1];
- mask2 = BITMASK(bit % 24);
- for(j = 0; j < 128; j++) {
- if(j & mask1)
- do_pc2[comes_from_bit / 7][j] |= mask2;
- }
- }
-
- /*
- * Now generate the table used to do combined
- * 32 bit permutation and e expansion
- *
- * We use it because we have to permute 16384 32 bit
- * longs into 48 bit in order to initialize sb.
- *
- * Looping 48 rounds per permutation becomes
- * just too slow...
- *
- */
-
- clearmem((char*)eperm32tab, sizeof(eperm32tab));
-
- for(bit = 0; bit < 48; bit++) {
- ufc_long mask1,comes_from;
-
- comes_from = perm32[esel[bit]-1]-1;
- mask1 = bytemask[comes_from % 8];
-
- for(j = 256; j--;) {
- if(j & mask1)
- eperm32tab[comes_from / 8][j][bit / 24] |= BITMASK(bit % 24);
- }
- }
-
- /*
- * Create the sb tables:
- *
- * For each 12 bit segment of an 48 bit intermediate
- * result, the sb table precomputes the two 4 bit
- * values of the sbox lookups done with the two 6
- * bit halves, shifts them to their proper place,
- * sends them through perm32 and finally E expands
- * them so that they are ready for the next
- * DES round.
- *
- */
- for(sg = 0; sg < 4; sg++) {
- int j1, j2;
- int s1, s2;
-
- for(j1 = 0; j1 < 64; j1++) {
- s1 = s_lookup(2 * sg, j1);
- for(j2 = 0; j2 < 64; j2++) {
- ufc_long to_permute, inx;
-
- s2 = s_lookup(2 * sg + 1, j2);
- to_permute = ((s1 << 4) | s2) << (24 - 8 * sg);
-
-#ifdef _UFC_32_
- inx = ((j1 << 6) | j2) << 1;
- sb[sg][inx ] = eperm32tab[0][(to_permute >> 24) & 0xff][0];
- sb[sg][inx+1] = eperm32tab[0][(to_permute >> 24) & 0xff][1];
- sb[sg][inx ] |= eperm32tab[1][(to_permute >> 16) & 0xff][0];
- sb[sg][inx+1] |= eperm32tab[1][(to_permute >> 16) & 0xff][1];
- sb[sg][inx ] |= eperm32tab[2][(to_permute >> 8) & 0xff][0];
- sb[sg][inx+1] |= eperm32tab[2][(to_permute >> 8) & 0xff][1];
- sb[sg][inx ] |= eperm32tab[3][(to_permute) & 0xff][0];
- sb[sg][inx+1] |= eperm32tab[3][(to_permute) & 0xff][1];
-#endif
-#ifdef _UFC_64_
- inx = ((j1 << 6) | j2);
- sb[sg][inx] =
- ((long64)eperm32tab[0][(to_permute >> 24) & 0xff][0] << 32) |
- (long64)eperm32tab[0][(to_permute >> 24) & 0xff][1];
- sb[sg][inx] |=
- ((long64)eperm32tab[1][(to_permute >> 16) & 0xff][0] << 32) |
- (long64)eperm32tab[1][(to_permute >> 16) & 0xff][1];
- sb[sg][inx] |=
- ((long64)eperm32tab[2][(to_permute >> 8) & 0xff][0] << 32) |
- (long64)eperm32tab[2][(to_permute >> 8) & 0xff][1];
- sb[sg][inx] |=
- ((long64)eperm32tab[3][(to_permute) & 0xff][0] << 32) |
- (long64)eperm32tab[3][(to_permute) & 0xff][1];
-#endif
- }
- }
- }
-
- /*
- * Create an inverse matrix for esel telling
- * where to plug out bits if undoing it
- */
- for(bit=48; bit--;) {
- e_inverse[esel[bit] - 1 ] = bit;
- e_inverse[esel[bit] - 1 + 32] = bit + 48;
- }
-
- /*
- * create efp: the matrix used to
- * undo the E expansion and effect final permutation
- */
- clearmem((char*)efp, sizeof efp);
- for(bit = 0; bit < 64; bit++) {
- int o_bit, o_long;
- ufc_long word_value, mask1, mask2;
- int comes_from_f_bit, comes_from_e_bit;
- int comes_from_word, bit_within_word;
-
- /* See where bit i belongs in the two 32 bit long's */
- o_long = bit / 32; /* 0..1 */
- o_bit = bit % 32; /* 0..31 */
-
- /*
- * And find a bit in the e permutated value setting this bit.
- *
- * Note: the e selection may have selected the same bit several
- * times. By the initialization of e_inverse, we only look
- * for one specific instance.
- */
- comes_from_f_bit = final_perm[bit] - 1; /* 0..63 */
- comes_from_e_bit = e_inverse[comes_from_f_bit]; /* 0..95 */
- comes_from_word = comes_from_e_bit / 6; /* 0..15 */
- bit_within_word = comes_from_e_bit % 6; /* 0..5 */
-
- mask1 = longmask[bit_within_word + 26];
- mask2 = longmask[o_bit];
-
- for(word_value = 64; word_value--;) {
- if(word_value & mask1)
- efp[comes_from_word][word_value][o_long] |= mask2;
- }
- }
- initialized++;
- }
-
-/*
- * Process the elements of the sb table permuting the
- * bits swapped in the expansion by the current salt.
- */
-
-#ifdef _UFC_32_
-static void shuffle_sb(k, saltbits)
- long32 *k;
- ufc_long saltbits;
- { ufc_long j;
- long32 x;
- for(j=4096; j--;) {
- x = (k[0] ^ k[1]) & (long32)saltbits;
- *k++ ^= x;
- *k++ ^= x;
- }
- }
-#endif
-
-#ifdef _UFC_64_
-static void shuffle_sb(k, saltbits)
- long64 *k;
- ufc_long saltbits;
- { ufc_long j;
- long64 x;
- for(j=4096; j--;) {
- x = ((*k >> 32) ^ *k) & (long64)saltbits;
- *k++ ^= (x << 32) | x;
- }
- }
-#endif
-
-/*
- * Setup the unit for a new salt
- * Hopefully we'll not see a new salt in each crypt call.
- */
-
-static unsigned char current_salt[3] = "&&"; /* invalid value */
-static ufc_long current_saltbits = 0;
-static int direction = 0;
-
-static void setup_salt(char *s1)
- { ufc_long i, j, saltbits;
- unsigned char *s2 = (unsigned char *)s1;
-
- if(!initialized)
- ufc_init_des();
-
- if(s2[0] == current_salt[0] && s2[1] == current_salt[1])
- return;
- current_salt[0] = s2[0]; current_salt[1] = s2[1];
-
- /*
- * This is the only crypt change to DES:
- * entries are swapped in the expansion table
- * according to the bits set in the salt.
- */
- saltbits = 0;
- for(i = 0; i < 2; i++) {
- long c=ascii_to_bin(s2[i]);
- if(c < 0 || c > 63)
- c = 0;
- for(j = 0; j < 6; j++) {
- if((c >> j) & 0x1)
- saltbits |= BITMASK(6 * i + j);
- }
- }
-
- /*
- * Permute the sb table values
- * to reflect the changed e
- * selection table
- */
- shuffle_sb(_ufc_sb0, current_saltbits ^ saltbits);
- shuffle_sb(_ufc_sb1, current_saltbits ^ saltbits);
- shuffle_sb(_ufc_sb2, current_saltbits ^ saltbits);
- shuffle_sb(_ufc_sb3, current_saltbits ^ saltbits);
-
- current_saltbits = saltbits;
- }
-
-static void ufc_mk_keytab(key)
- char *key;
- { ufc_long v1, v2, *k1;
- int i;
-#ifdef _UFC_32_
- long32 v, *k2 = &_ufc_keytab[0][0];
-#endif
-#ifdef _UFC_64_
- long64 v, *k2 = &_ufc_keytab[0];
-#endif
-
- v1 = v2 = 0; k1 = &do_pc1[0][0][0];
- for(i = 8; i--;) {
- v1 |= k1[*key & 0x7f]; k1 += 128;
- v2 |= k1[*key++ & 0x7f]; k1 += 128;
- }
-
- for(i = 0; i < 16; i++) {
- k1 = &do_pc2[0][0];
-
- v1 = (v1 << rots[i]) | (v1 >> (28 - rots[i]));
- v = k1[(v1 >> 21) & 0x7f]; k1 += 128;
- v |= k1[(v1 >> 14) & 0x7f]; k1 += 128;
- v |= k1[(v1 >> 7) & 0x7f]; k1 += 128;
- v |= k1[(v1 ) & 0x7f]; k1 += 128;
-
-#ifdef _UFC_32_
- *k2++ = v;
- v = 0;
-#endif
-#ifdef _UFC_64_
- v <<= 32;
-#endif
-
- v2 = (v2 << rots[i]) | (v2 >> (28 - rots[i]));
- v |= k1[(v2 >> 21) & 0x7f]; k1 += 128;
- v |= k1[(v2 >> 14) & 0x7f]; k1 += 128;
- v |= k1[(v2 >> 7) & 0x7f]; k1 += 128;
- v |= k1[(v2 ) & 0x7f];
-
- *k2++ = v;
- }
-
- direction = 0;
- }
-
-/*
- * Undo an extra E selection and do final permutations
- */
-
-ufc_long *_ufc_dofinalperm(l1, l2, r1, r2)
- ufc_long l1,l2,r1,r2;
- { ufc_long v1, v2, x;
- static ufc_long ary[2];
-
- x = (l1 ^ l2) & current_saltbits; l1 ^= x; l2 ^= x;
- x = (r1 ^ r2) & current_saltbits; r1 ^= x; r2 ^= x;
-
- v1=v2=0; l1 >>= 3; l2 >>= 3; r1 >>= 3; r2 >>= 3;
-
- v1 |= efp[15][ r2 & 0x3f][0]; v2 |= efp[15][ r2 & 0x3f][1];
- v1 |= efp[14][(r2 >>= 6) & 0x3f][0]; v2 |= efp[14][ r2 & 0x3f][1];
- v1 |= efp[13][(r2 >>= 10) & 0x3f][0]; v2 |= efp[13][ r2 & 0x3f][1];
- v1 |= efp[12][(r2 >>= 6) & 0x3f][0]; v2 |= efp[12][ r2 & 0x3f][1];
-
- v1 |= efp[11][ r1 & 0x3f][0]; v2 |= efp[11][ r1 & 0x3f][1];
- v1 |= efp[10][(r1 >>= 6) & 0x3f][0]; v2 |= efp[10][ r1 & 0x3f][1];
- v1 |= efp[ 9][(r1 >>= 10) & 0x3f][0]; v2 |= efp[ 9][ r1 & 0x3f][1];
- v1 |= efp[ 8][(r1 >>= 6) & 0x3f][0]; v2 |= efp[ 8][ r1 & 0x3f][1];
-
- v1 |= efp[ 7][ l2 & 0x3f][0]; v2 |= efp[ 7][ l2 & 0x3f][1];
- v1 |= efp[ 6][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 6][ l2 & 0x3f][1];
- v1 |= efp[ 5][(l2 >>= 10) & 0x3f][0]; v2 |= efp[ 5][ l2 & 0x3f][1];
- v1 |= efp[ 4][(l2 >>= 6) & 0x3f][0]; v2 |= efp[ 4][ l2 & 0x3f][1];
-
- v1 |= efp[ 3][ l1 & 0x3f][0]; v2 |= efp[ 3][ l1 & 0x3f][1];
- v1 |= efp[ 2][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 2][ l1 & 0x3f][1];
- v1 |= efp[ 1][(l1 >>= 10) & 0x3f][0]; v2 |= efp[ 1][ l1 & 0x3f][1];
- v1 |= efp[ 0][(l1 >>= 6) & 0x3f][0]; v2 |= efp[ 0][ l1 & 0x3f][1];
-
- ary[0] = v1; ary[1] = v2;
- return ary;
- }
-
-/*
- * crypt only: convert from 64 bit to 11 bit ASCII
- * prefixing with the salt
- */
-
-static char *output_conversion(v1, v2, salt)
- ufc_long v1, v2;
- char *salt;
- { static char outbuf[14];
- int i, s;
-
- outbuf[0] = salt[0];
- outbuf[1] = salt[1] ? salt[1] : salt[0];
-
- for(i = 0; i < 5; i++)
- outbuf[i + 2] = bin_to_ascii((v1 >> (26 - 6 * i)) & 0x3f);
-
- s = (v2 & 0xf) << 2;
- v2 = (v2 >> 2) | ((v1 & 0x3) << 30);
-
- for(i = 5; i < 10; i++)
- outbuf[i + 2] = bin_to_ascii((v2 >> (56 - 6 * i)) & 0x3f);
-
- outbuf[12] = bin_to_ascii(s);
- outbuf[13] = 0;
-
- return outbuf;
- }
-
-/*
- * UNIX crypt function
- */
-
-ufc_long *_ufc_doit(ufc_long , ufc_long, ufc_long, ufc_long, ufc_long);
-
-char *ufc_crypt(char *key,char *salt)
- { ufc_long *s;
- char ktab[9];
-
- /*
- * Hack DES tables according to salt
- */
- setup_salt(salt);
-
- /*
- * Setup key schedule
- */
- clearmem(ktab, sizeof ktab);
- StrnCpy(ktab, key, 8);
- ufc_mk_keytab(ktab);
-
- /*
- * Go for the 25 DES encryptions
- */
- s = _ufc_doit((ufc_long)0, (ufc_long)0,
- (ufc_long)0, (ufc_long)0, (ufc_long)25);
-
- /*
- * And convert back to 6 bit ASCII
- */
- return output_conversion(s[0], s[1], salt);
- }
-
-
-#ifdef _UFC_32_
-
-/*
- * 32 bit version
- */
-
-extern long32 _ufc_keytab[16][2];
-extern long32 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[];
-
-#define SBA(sb, v) (*(long32*)((char*)(sb)+(v)))
-
-static ufc_long *_ufc_doit(l1, l2, r1, r2, itr)
- ufc_long l1, l2, r1, r2, itr;
- { int i;
- long32 s, *k;
-
- while(itr--) {
- k = &_ufc_keytab[0][0];
- for(i=8; i--; ) {
- s = *k++ ^ r1;
- l1 ^= SBA(_ufc_sb1, s & 0xffff); l2 ^= SBA(_ufc_sb1, (s & 0xffff)+4);
- l1 ^= SBA(_ufc_sb0, s >>= 16); l2 ^= SBA(_ufc_sb0, (s) +4);
- s = *k++ ^ r2;
- l1 ^= SBA(_ufc_sb3, s & 0xffff); l2 ^= SBA(_ufc_sb3, (s & 0xffff)+4);
- l1 ^= SBA(_ufc_sb2, s >>= 16); l2 ^= SBA(_ufc_sb2, (s) +4);
-
- s = *k++ ^ l1;
- r1 ^= SBA(_ufc_sb1, s & 0xffff); r2 ^= SBA(_ufc_sb1, (s & 0xffff)+4);
- r1 ^= SBA(_ufc_sb0, s >>= 16); r2 ^= SBA(_ufc_sb0, (s) +4);
- s = *k++ ^ l2;
- r1 ^= SBA(_ufc_sb3, s & 0xffff); r2 ^= SBA(_ufc_sb3, (s & 0xffff)+4);
- r1 ^= SBA(_ufc_sb2, s >>= 16); r2 ^= SBA(_ufc_sb2, (s) +4);
- }
- s=l1; l1=r1; r1=s; s=l2; l2=r2; r2=s;
- }
- return _ufc_dofinalperm(l1, l2, r1, r2);
- }
-
-#endif
-
-#ifdef _UFC_64_
-
-/*
- * 64 bit version
- */
-
-extern long64 _ufc_keytab[16];
-extern long64 _ufc_sb0[], _ufc_sb1[], _ufc_sb2[], _ufc_sb3[];
-
-#define SBA(sb, v) (*(long64*)((char*)(sb)+(v)))
-
-static ufc_long *_ufc_doit(l1, l2, r1, r2, itr)
- ufc_long l1, l2, r1, r2, itr;
- { int i;
- long64 l, r, s, *k;
-
- l = (((long64)l1) << 32) | ((long64)l2);
- r = (((long64)r1) << 32) | ((long64)r2);
-
- while(itr--) {
- k = &_ufc_keytab[0];
- for(i=8; i--; ) {
- s = *k++ ^ r;
- l ^= SBA(_ufc_sb3, (s >> 0) & 0xffff);
- l ^= SBA(_ufc_sb2, (s >> 16) & 0xffff);
- l ^= SBA(_ufc_sb1, (s >> 32) & 0xffff);
- l ^= SBA(_ufc_sb0, (s >> 48) & 0xffff);
-
- s = *k++ ^ l;
- r ^= SBA(_ufc_sb3, (s >> 0) & 0xffff);
- r ^= SBA(_ufc_sb2, (s >> 16) & 0xffff);
- r ^= SBA(_ufc_sb1, (s >> 32) & 0xffff);
- r ^= SBA(_ufc_sb0, (s >> 48) & 0xffff);
- }
- s=l; l=r; r=s;
- }
-
- l1 = l >> 32; l2 = l & 0xffffffff;
- r1 = r >> 32; r2 = r & 0xffffffff;
- return _ufc_dofinalperm(l1, l2, r1, r2);
- }
-
-#endif
-
-
-#else
- int ufc_dummy_procedure(void)
-{return 0;}
-#endif
diff --git a/source/lib/username.c b/source/lib/username.c
deleted file mode 100644
index a9f64259916..00000000000
--- a/source/lib/username.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Username handling
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-
-#include "includes.h"
-extern int DEBUGLEVEL;
-
-/* internal functions - modified versions of the ones in password.c */
-static struct passwd *uname_string_combinations(char *s, struct passwd * (*fn) (), int N);
-static struct passwd *uname_string_combinations2(char *s, int offset, struct passwd * (*fn) (), int N);
-
-/****************************************************************************
-get a users home directory. tries as-is then lower case
-****************************************************************************/
-char *get_home_dir(char *user)
-{
- static struct passwd *pass;
-
- pass = Get_Pwnam(user,False);
-
- if (!pass) return(NULL);
- return(pass->pw_dir);
-}
-
-
-/*******************************************************************
-map a username from a dos name to a unix name by looking in the username
-map
-********************************************************************/
-void map_username(char *user)
-{
- static int depth=0;
- static BOOL initialised=False;
- static fstring last_from,last_to;
- FILE *f;
- char *s;
- char *mapfile = lp_username_map();
- if (!*mapfile || depth) return;
-
- if (!*user) return;
-
- if (!initialised) {
- *last_from = *last_to = 0;
- initialised = True;
- }
-
- if (strequal(user,last_to)) return;
-
- if (strequal(user,last_from)) {
- DEBUG(3,("Mapped user %s to %s\n",user,last_to));
- fstrcpy(user,last_to);
- return;
- }
-
- f = fopen(mapfile,"r");
- if (!f) {
- DEBUG(0,("can't open username map %s\n",mapfile));
- return;
- }
-
- DEBUG(4,("Scanning username map %s\n",mapfile));
-
- depth++;
-
- for (; (s=fgets_slash(NULL,80,f)); free(s)) {
- char *unixname = s;
- char *dosname = strchr(unixname,'=');
-
- if (!dosname) continue;
- *dosname++ = 0;
-
- while (isspace(*unixname)) unixname++;
- if (!*unixname || strchr("#;",*unixname)) continue;
-
- {
- int l = strlen(unixname);
- while (l && isspace(unixname[l-1])) {
- unixname[l-1] = 0;
- l--;
- }
- }
-
- if (strchr(dosname,'*') || user_in_list(user,dosname)) {
- DEBUG(3,("Mapped user %s to %s\n",user,unixname));
- StrnCpy(last_from,user,sizeof(last_from)-1);
- sscanf(unixname,"%s",user);
- StrnCpy(last_to,user,sizeof(last_to)-1);
- }
- }
-
- fclose(f);
-
- depth--;
-}
-
-/****************************************************************************
-internals of Get_Pwnam wrapper
-****************************************************************************/
-static struct passwd *_Get_Pwnam(char *s)
-{
- struct passwd *ret;
-
- ret = getpwnam(s);
- if (ret)
- {
-#ifdef GETPWANAM
- struct passwd_adjunct *pwret;
- pwret = getpwanam(s);
- if (pwret)
- {
- free(ret->pw_passwd);
- ret->pw_passwd = pwret->pwa_passwd;
- }
-#endif
-
- }
-
- return(ret);
-}
-
-
-/****************************************************************************
-a wrapper for getpwnam() that tries with all lower and all upper case
-if the initial name fails. Also tried with first letter capitalised
-Note that this changes user!
-****************************************************************************/
-struct passwd *Get_Pwnam(char *user,BOOL allow_change)
-{
- fstring user2;
- int last_char;
- int usernamelevel = lp_usernamelevel();
-
- struct passwd *ret;
-
- if (!user || !(*user))
- return(NULL);
-
- StrnCpy(user2,user,sizeof(user2)-1);
-
- if (!allow_change) {
- user = &user2[0];
- }
-
- map_username(user);
-
- ret = _Get_Pwnam(user);
- if (ret) return(ret);
-
- strlower(user);
- ret = _Get_Pwnam(user);
- if (ret) return(ret);
-
- strupper(user);
- ret = _Get_Pwnam(user);
- if (ret) return(ret);
-
- /* try with first letter capitalised */
- if (strlen(user) > 1)
- strlower(user+1);
- ret = _Get_Pwnam(user);
- if (ret) return(ret);
-
- /* try with last letter capitalised */
- strlower(user);
- last_char = strlen(user)-1;
- user[last_char] = toupper(user[last_char]);
- DEBUG(3, ("Trying username %s\n", user));
- ret = _Get_Pwnam(user);
- if (ret) return(ret);
-
- /* try all combinations up to usernamelevel */
- strlower(user);
- ret = uname_string_combinations(user, _Get_Pwnam, usernamelevel);
- if (ret) return(ret);
-
- if (allow_change)
- fstrcpy(user,user2);
-
- return(NULL);
-}
-
-
-/****************************************************************************
-check if a user is in a user list
-****************************************************************************/
-BOOL user_in_list(char *user,char *list)
-{
- pstring tok;
- char *p=list;
-
- while (next_token(&p,tok,LIST_SEP))
- {
- if (strequal(user,tok))
- return(True);
-
-#ifdef NETGROUP
- if (*tok == '@')
- {
- static char *mydomain = NULL;
- if (mydomain == 0)
- yp_get_default_domain(&mydomain);
-
- if(mydomain == 0)
- {
- DEBUG(5,("Unable to get default yp domain\n"));
- }
- else
- {
-
- DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
- user, mydomain, &tok[1]));
- DEBUG(5,("innetgr is %s\n",
- innetgr(&tok[1], (char *) 0, user, mydomain)
- ? "TRUE" : "FALSE"));
-
- if (innetgr(&tok[1], (char *)0, user, mydomain))
- return (True);
- }
- }
-#endif
-
-
-#if HAVE_GETGRNAM
- if (*tok == '@')
- {
- struct group *gptr;
- char **member;
- struct passwd *pass = Get_Pwnam(user,False);
-
- if (pass) {
- gptr = getgrgid(pass->pw_gid);
- if (gptr && strequal(gptr->gr_name,&tok[1]))
- return(True);
- }
-
- gptr = (struct group *)getgrnam(&tok[1]);
-
- if (gptr)
- {
- member = gptr->gr_mem;
- while (member && *member)
- {
- if (strequal(*member,user))
- return(True);
- member++;
- }
- }
- }
-#endif
- }
- return(False);
-}
-
-/* The functions below have been taken from password.c and slightly modified */
-/****************************************************************************
-apply a function to upper/lower case combinations
-of a string and return true if one of them returns true.
-try all combinations with N uppercase letters.
-offset is the first char to try and change (start with 0)
-it assumes the string starts lowercased
-****************************************************************************/
-static struct passwd *uname_string_combinations2(char *s,int offset,struct passwd *(*fn)(),int N)
-{
- int len = strlen(s);
- int i;
- struct passwd *ret;
-
-#ifdef PASSWORD_LENGTH
- len = MIN(len,PASSWORD_LENGTH);
-#endif
-
- if (N <= 0 || offset >= len)
- return(fn(s));
-
-
- for (i=offset;i<(len-(N-1));i++)
-
- {
- char c = s[i];
- if (!islower(c)) continue;
- s[i] = toupper(c);
- ret = uname_string_combinations2(s,i+1,fn,N-1);
- if(ret) return(ret);
- s[i] = c;
- }
- return(NULL);
-}
-
-/****************************************************************************
-apply a function to upper/lower case combinations
-of a string and return true if one of them returns true.
-try all combinations with up to N uppercase letters.
-offset is the first char to try and change (start with 0)
-it assumes the string starts lowercased
-****************************************************************************/
-static struct passwd * uname_string_combinations(char *s,struct passwd * (*fn)(),int N)
-{
- int n;
- struct passwd *ret;
-
- for (n=1;n<=N;n++)
- {
- ret = uname_string_combinations2(s,0,fn,n);
- if(ret) return(ret);
- }
- return(NULL);
-}
diff --git a/source/lib/util.c b/source/lib/util.c
deleted file mode 100644
index 4e6bfb7054a..00000000000
--- a/source/lib/util.c
+++ /dev/null
@@ -1,4392 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Samba utility functions
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-
-#include "includes.h"
-
-pstring scope = "";
-
-int DEBUGLEVEL = 1;
-
-BOOL passive = False;
-
-int Protocol = PROTOCOL_COREPLUS;
-
-/* a default finfo structure to ensure all fields are sensible */
-file_info def_finfo = {-1,0,0,0,0,0,0,""};
-
-/* these are some file handles where debug info will be stored */
-FILE *dbf = NULL;
-
-/* the client file descriptor */
-int Client = -1;
-
-/* the last IP received from */
-struct in_addr lastip;
-
-/* the last port received from */
-int lastport=0;
-
-/* this is used by the chaining code */
-int chain_size = 0;
-
-int trans_num = 0;
-
-/*
- case handling on filenames
-*/
-int case_default = CASE_LOWER;
-
-pstring debugf = "";
-int syslog_level;
-
-/* the following control case operations - they are put here so the
- client can link easily */
-BOOL case_sensitive;
-BOOL case_preserve;
-BOOL use_mangled_map = False;
-BOOL short_case_preserve;
-BOOL case_mangle;
-
-fstring remote_machine="";
-fstring local_machine="";
-fstring remote_arch="UNKNOWN";
-static enum remote_arch_types ra_type = RA_UNKNOWN;
-fstring remote_proto="UNKNOWN";
-pstring myhostname="";
-pstring user_socket_options="";
-pstring sesssetup_user="";
-pstring myname = "";
-fstring myworkgroup = "";
-char **my_netbios_names;
-
-int smb_read_error = 0;
-
-static BOOL stdout_logging = False;
-
-static char *filename_dos(char *path,char *buf);
-
-/*******************************************************************
- get ready for syslog stuff
- ******************************************************************/
-void setup_logging(char *pname,BOOL interactive)
-{
-#ifdef SYSLOG
- if (!interactive) {
- char *p = strrchr(pname,'/');
- if (p) pname = p+1;
-#ifdef LOG_DAEMON
- openlog(pname, LOG_PID, LOG_DAEMON);
-#else /* LOG_DAEMON - for old systems that have no facility codes. */
- openlog(pname, LOG_PID);
-#endif /* LOG_DAEMON */
- }
-#endif
- if (interactive) {
- stdout_logging = True;
- dbf = stdout;
- }
-}
-
-
-BOOL append_log=False;
-
-
-/****************************************************************************
-reopen the log files
-****************************************************************************/
-void reopen_logs(void)
-{
- extern FILE *dbf;
- pstring fname;
-
- if (DEBUGLEVEL > 0)
- {
- strcpy(fname,debugf);
- if (lp_loaded() && (*lp_logfile()))
- strcpy(fname,lp_logfile());
-
- if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
- {
- int oldumask = umask(022);
- strcpy(debugf,fname);
- if (dbf) fclose(dbf);
- if (append_log)
- dbf = fopen(debugf,"a");
- else
- dbf = fopen(debugf,"w");
- if (dbf) setbuf(dbf,NULL);
- umask(oldumask);
- }
- }
- else
- {
- if (dbf)
- {
- fclose(dbf);
- dbf = NULL;
- }
- }
-}
-
-
-/*******************************************************************
-check if the log has grown too big
-********************************************************************/
-static void check_log_size(void)
-{
- static int debug_count=0;
- int maxlog;
- struct stat st;
-
- if (debug_count++ < 100 || getuid() != 0) return;
-
- maxlog = lp_max_log_size() * 1024;
- if (!dbf || maxlog <= 0) return;
-
- if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
- fclose(dbf); dbf = NULL;
- reopen_logs();
- if (dbf && file_size(debugf) > maxlog) {
- pstring name;
- fclose(dbf); dbf = NULL;
- sprintf(name,"%s.old",debugf);
- sys_rename(debugf,name);
- reopen_logs();
- }
- }
- debug_count=0;
-}
-
-
-/*******************************************************************
-write an debug message on the debugfile. This is called by the DEBUG
-macro
-********************************************************************/
-#ifdef __STDC__
- int Debug1(char *format_str, ...)
-{
-#else
- int Debug1(va_alist)
-va_dcl
-{
- char *format_str;
-#endif
- va_list ap;
- int old_errno = errno;
-
- if (stdout_logging) {
-#ifdef __STDC__
- va_start(ap, format_str);
-#else
- va_start(ap);
- format_str = va_arg(ap,char *);
-#endif
- vfprintf(dbf,format_str,ap);
- va_end(ap);
- errno = old_errno;
- return(0);
- }
-
-#ifdef SYSLOG
- if (!lp_syslog_only())
-#endif
- {
- if (!dbf) {
- int oldumask = umask(022);
- dbf = fopen(debugf,"w");
- umask(oldumask);
- if (dbf) {
- setbuf(dbf,NULL);
- } else {
- errno = old_errno;
- return(0);
- }
- }
- }
-
-#ifdef SYSLOG
- if (syslog_level < lp_syslog())
- {
- /*
- * map debug levels to syslog() priorities
- * note that not all DEBUG(0, ...) calls are
- * necessarily errors
- */
- static int priority_map[] = {
- LOG_ERR, /* 0 */
- LOG_WARNING, /* 1 */
- LOG_NOTICE, /* 2 */
- LOG_INFO, /* 3 */
- };
- int priority;
- pstring msgbuf;
-
- if (syslog_level >= sizeof(priority_map) / sizeof(priority_map[0]) ||
- syslog_level < 0)
- priority = LOG_DEBUG;
- else
- priority = priority_map[syslog_level];
-
-#ifdef __STDC__
- va_start(ap, format_str);
-#else
- va_start(ap);
- format_str = va_arg(ap,char *);
-#endif
- vsprintf(msgbuf, format_str, ap);
- va_end(ap);
-
- msgbuf[255] = '\0';
- syslog(priority, "%s", msgbuf);
- }
-#endif
-
-#ifdef SYSLOG
- if (!lp_syslog_only())
-#endif
- {
-#ifdef __STDC__
- va_start(ap, format_str);
-#else
- va_start(ap);
- format_str = va_arg(ap,char *);
-#endif
- vfprintf(dbf,format_str,ap);
- va_end(ap);
- fflush(dbf);
- }
-
- check_log_size();
-
- errno = old_errno;
-
- return(0);
-}
-
-/****************************************************************************
- find a suitable temporary directory. The result should be copied immediately
- as it may be overwritten by a subsequent call
- ****************************************************************************/
-char *tmpdir(void)
-{
- char *p;
- if ((p = getenv("TMPDIR"))) {
- return p;
- }
- return "/tmp";
-}
-
-
-
-/****************************************************************************
-determine if a file descriptor is in fact a socket
-****************************************************************************/
-BOOL is_a_socket(int fd)
-{
- int v,l;
- l = sizeof(int);
- return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
-}
-
-
-static char *last_ptr=NULL;
-
-/****************************************************************************
- Get the next token from a string, return False if none found
- handles double-quotes.
-Based on a routine by GJC@VILLAGE.COM.
-Extensively modified by Andrew.Tridgell@anu.edu.au
-****************************************************************************/
-BOOL next_token(char **ptr,char *buff,char *sep)
-{
- char *s;
- BOOL quoted;
-
- if (!ptr) ptr = &last_ptr;
- if (!ptr) return(False);
-
- s = *ptr;
-
- /* default to simple separators */
- if (!sep) sep = " \t\n\r";
-
- /* find the first non sep char */
- while(*s && strchr(sep,*s)) s++;
-
- /* nothing left? */
- if (! *s) return(False);
-
- /* copy over the token */
- for (quoted = False; *s && (quoted || !strchr(sep,*s)); s++)
- {
- if (*s == '\"')
- quoted = !quoted;
- else
- *buff++ = *s;
- }
-
- *ptr = (*s) ? s+1 : s;
- *buff = 0;
- last_ptr = *ptr;
-
- return(True);
-}
-
-/****************************************************************************
-Convert list of tokens to array; dependent on above routine.
-Uses last_ptr from above - bit of a hack.
-****************************************************************************/
-char **toktocliplist(int *ctok, char *sep)
-{
- char *s=last_ptr;
- int ictok=0;
- char **ret, **iret;
-
- if (!sep) sep = " \t\n\r";
-
- while(*s && strchr(sep,*s)) s++;
-
- /* nothing left? */
- if (!*s) return(NULL);
-
- do {
- ictok++;
- while(*s && (!strchr(sep,*s))) s++;
- while(*s && strchr(sep,*s)) *s++=0;
- } while(*s);
-
- *ctok=ictok;
- s=last_ptr;
-
- if (!(ret=iret=malloc(ictok*sizeof(char *)))) return NULL;
-
- while(ictok--) {
- *iret++=s;
- while(*s++);
- while(!*s) s++;
- }
-
- return ret;
-}
-
-#ifndef HAVE_MEMMOVE
-/*******************************************************************
-safely copies memory, ensuring no overlap problems.
-this is only used if the machine does not have it's own memmove().
-this is not the fastest algorithm in town, but it will do for our
-needs.
-********************************************************************/
-void *MemMove(void *dest,void *src,int size)
-{
- unsigned long d,s;
- int i;
- if (dest==src || !size) return(dest);
-
- d = (unsigned long)dest;
- s = (unsigned long)src;
-
- if ((d >= (s+size)) || (s >= (d+size))) {
- /* no overlap */
- memcpy(dest,src,size);
- return(dest);
- }
-
- if (d < s)
- {
- /* we can forward copy */
- if (s-d >= sizeof(int) &&
- !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
- /* do it all as words */
- int *idest = (int *)dest;
- int *isrc = (int *)src;
- size /= sizeof(int);
- for (i=0;i<size;i++) idest[i] = isrc[i];
- } else {
- /* simplest */
- char *cdest = (char *)dest;
- char *csrc = (char *)src;
- for (i=0;i<size;i++) cdest[i] = csrc[i];
- }
- }
- else
- {
- /* must backward copy */
- if (d-s >= sizeof(int) &&
- !(s%sizeof(int)) && !(d%sizeof(int)) && !(size%sizeof(int))) {
- /* do it all as words */
- int *idest = (int *)dest;
- int *isrc = (int *)src;
- size /= sizeof(int);
- for (i=size-1;i>=0;i--) idest[i] = isrc[i];
- } else {
- /* simplest */
- char *cdest = (char *)dest;
- char *csrc = (char *)src;
- for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
- }
- }
- return(dest);
-}
-#endif
-
-
-/****************************************************************************
-prompte a dptr (to make it recently used)
-****************************************************************************/
-void array_promote(char *array,int elsize,int element)
-{
- char *p;
- if (element == 0)
- return;
-
- p = (char *)malloc(elsize);
-
- if (!p)
- {
- DEBUG(5,("Ahh! Can't malloc\n"));
- return;
- }
- memcpy(p,array + element * elsize, elsize);
- memmove(array + elsize,array,elsize*element);
- memcpy(array,p,elsize);
- free(p);
-}
-
-enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
-
-struct
-{
- char *name;
- int level;
- int option;
- int value;
- int opttype;
-} socket_options[] = {
- {"SO_KEEPALIVE", SOL_SOCKET, SO_KEEPALIVE, 0, OPT_BOOL},
- {"SO_REUSEADDR", SOL_SOCKET, SO_REUSEADDR, 0, OPT_BOOL},
- {"SO_BROADCAST", SOL_SOCKET, SO_BROADCAST, 0, OPT_BOOL},
-#ifdef TCP_NODELAY
- {"TCP_NODELAY", IPPROTO_TCP, TCP_NODELAY, 0, OPT_BOOL},
-#endif
-#ifdef IPTOS_LOWDELAY
- {"IPTOS_LOWDELAY", IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY, OPT_ON},
-#endif
-#ifdef IPTOS_THROUGHPUT
- {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
-#endif
-#ifdef SO_SNDBUF
- {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
-#endif
-#ifdef SO_RCVBUF
- {"SO_RCVBUF", SOL_SOCKET, SO_RCVBUF, 0, OPT_INT},
-#endif
-#ifdef SO_SNDLOWAT
- {"SO_SNDLOWAT", SOL_SOCKET, SO_SNDLOWAT, 0, OPT_INT},
-#endif
-#ifdef SO_RCVLOWAT
- {"SO_RCVLOWAT", SOL_SOCKET, SO_RCVLOWAT, 0, OPT_INT},
-#endif
-#ifdef SO_SNDTIMEO
- {"SO_SNDTIMEO", SOL_SOCKET, SO_SNDTIMEO, 0, OPT_INT},
-#endif
-#ifdef SO_RCVTIMEO
- {"SO_RCVTIMEO", SOL_SOCKET, SO_RCVTIMEO, 0, OPT_INT},
-#endif
- {NULL,0,0,0,0}};
-
-
-
-/****************************************************************************
-set user socket options
-****************************************************************************/
-void set_socket_options(int fd, char *options)
-{
- string tok;
-
- while (next_token(&options,tok," \t,"))
- {
- int ret=0,i;
- int value = 1;
- char *p;
- BOOL got_value = False;
-
- if ((p = strchr(tok,'=')))
- {
- *p = 0;
- value = atoi(p+1);
- got_value = True;
- }
-
- for (i=0;socket_options[i].name;i++)
- if (strequal(socket_options[i].name,tok))
- break;
-
- if (!socket_options[i].name)
- {
- DEBUG(0,("Unknown socket option %s\n",tok));
- continue;
- }
-
- switch (socket_options[i].opttype)
- {
- case OPT_BOOL:
- case OPT_INT:
- ret = setsockopt(fd,socket_options[i].level,
- socket_options[i].option,(char *)&value,sizeof(int));
- break;
-
- case OPT_ON:
- if (got_value)
- DEBUG(0,("syntax error - %s does not take a value\n",tok));
-
- {
- int on = socket_options[i].value;
- ret = setsockopt(fd,socket_options[i].level,
- socket_options[i].option,(char *)&on,sizeof(int));
- }
- break;
- }
-
- if (ret != 0)
- DEBUG(0,("Failed to set socket option %s\n",tok));
- }
-}
-
-
-
-/****************************************************************************
- close the socket communication
-****************************************************************************/
-void close_sockets(void )
-{
- close(Client);
- Client = 0;
-}
-
-/****************************************************************************
-determine whether we are in the specified group
-****************************************************************************/
-BOOL in_group(gid_t group, int current_gid, int ngroups, int *groups)
-{
- int i;
-
- if (group == current_gid) return(True);
-
- for (i=0;i<ngroups;i++)
- if (group == groups[i])
- return(True);
-
- return(False);
-}
-
-/****************************************************************************
-this is a safer strcpy(), meant to prevent core dumps when nasty things happen
-****************************************************************************/
-char *StrCpy(char *dest,char *src)
-{
- char *d = dest;
-
-#if AJT
- /* I don't want to get lazy with these ... */
- if (!dest || !src) {
- DEBUG(0,("ERROR: NULL StrCpy() called!\n"));
- ajt_panic();
- }
-#endif
-
- if (!dest) return(NULL);
- if (!src) {
- *dest = 0;
- return(dest);
- }
- while ((*d++ = *src++)) ;
- return(dest);
-}
-
-/****************************************************************************
-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);
-}
-
-
-/*******************************************************************
-copy an IP address from one buffer to another
-********************************************************************/
-void putip(void *dest,void *src)
-{
- memcpy(dest,src,4);
-}
-
-
-/****************************************************************************
-interpret the weird netbios "name". Return the name type
-****************************************************************************/
-static int name_interpret(char *in,char *out)
-{
- int ret;
- int len = (*in++) / 2;
-
- *out=0;
-
- if (len > 30 || len<1) return(0);
-
- while (len--)
- {
- if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
- *out = 0;
- return(0);
- }
- *out = ((in[0]-'A')<<4) + (in[1]-'A');
- in += 2;
- out++;
- }
- *out = 0;
- ret = out[-1];
-
-#ifdef NETBIOS_SCOPE
- /* Handle any scope names */
- while(*in)
- {
- *out++ = '.'; /* Scope names are separated by periods */
- len = *(unsigned char *)in++;
- StrnCpy(out, in, len);
- out += len;
- *out=0;
- in += len;
- }
-#endif
- return(ret);
-}
-
-/****************************************************************************
-mangle a name into netbios format
-
- Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
-****************************************************************************/
-int name_mangle( char *In, char *Out, char name_type )
- {
- int i;
- int c;
- int len;
- char buf[20];
- char *p = Out;
-
- /* Safely copy the input string, In, into buf[]. */
- (void)memset( buf, 0, 20 );
- if( '*' == In[0] )
- buf[0] = '*';
- else
- (void)sprintf( buf, "%-15.15s%c", In, name_type );
-
- /* Place the length of the first field into the output buffer. */
- p[0] = 32;
- p++;
-
- /* Now convert the name to the rfc1001/1002 format. */
- for( i = 0; i < 16; i++ )
- {
- c = toupper( buf[i] );
- p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
- p[(i*2)+1] = (c & 0x000F) + 'A';
- }
- p += 32;
- p[0] = '\0';
-
- /* Add the scope string. */
- for( i = 0, len = 0; NULL != scope; i++, len++ )
- {
- switch( scope[i] )
- {
- case '\0':
- p[0] = len;
- if( len > 0 )
- p[len+1] = 0;
- return( name_len(Out) );
- case '.':
- p[0] = len;
- p += (len + 1);
- len = 0;
- break;
- default:
- p[len+1] = scope[i];
- break;
- }
- }
-
- return( name_len(Out) );
- } /* name_mangle */
-
-/*******************************************************************
- check if a file exists
-********************************************************************/
-BOOL file_exist(char *fname,struct stat *sbuf)
-{
- struct stat st;
- if (!sbuf) sbuf = &st;
-
- if (sys_stat(fname,sbuf) != 0)
- return(False);
-
- return(S_ISREG(sbuf->st_mode));
-}
-
-/*******************************************************************
-check a files mod time
-********************************************************************/
-time_t file_modtime(char *fname)
-{
- struct stat st;
-
- if (sys_stat(fname,&st) != 0)
- return(0);
-
- return(st.st_mtime);
-}
-
-/*******************************************************************
- check if a directory exists
-********************************************************************/
-BOOL directory_exist(char *dname,struct stat *st)
-{
- struct stat st2;
- BOOL ret;
-
- if (!st) st = &st2;
-
- if (sys_stat(dname,st) != 0)
- return(False);
-
- ret = S_ISDIR(st->st_mode);
- if(!ret)
- errno = ENOTDIR;
- return ret;
-}
-
-/*******************************************************************
-returns the size in bytes of the named file
-********************************************************************/
-uint32 file_size(char *file_name)
-{
- struct stat buf;
- buf.st_size = 0;
- sys_stat(file_name,&buf);
- return(buf.st_size);
-}
-
-/*******************************************************************
-return a string representing an attribute for a file
-********************************************************************/
-char *attrib_string(int mode)
-{
- static char attrstr[10];
-
- attrstr[0] = 0;
-
- if (mode & aVOLID) strcat(attrstr,"V");
- if (mode & aDIR) strcat(attrstr,"D");
- if (mode & aARCH) strcat(attrstr,"A");
- if (mode & aHIDDEN) strcat(attrstr,"H");
- if (mode & aSYSTEM) strcat(attrstr,"S");
- if (mode & aRONLY) strcat(attrstr,"R");
-
- return(attrstr);
-}
-
-
-/*******************************************************************
- case insensitive string compararison
-********************************************************************/
-int StrCaseCmp(char *s, char *t)
-{
- /* compare until we run out of string, either t or s, or find a difference */
- /* We *must* use toupper rather than tolower here due to the
- asynchronous upper to lower mapping.
- */
-#if !defined(KANJI_WIN95_COMPATIBILITY)
- if(lp_client_code_page() == KANJI_CODEPAGE)
- {
- /* Win95 treats full width ascii characters as case sensitive. */
- int diff;
- for (;;)
- {
- if (!*s || !*t)
- return toupper (*s) - toupper (*t);
- else if (is_sj_alph (*s) && is_sj_alph (*t))
- {
- diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
- if (diff)
- return diff;
- s += 2;
- t += 2;
- }
- else if (is_shift_jis (*s) && is_shift_jis (*t))
- {
- diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
- if (diff)
- return diff;
- diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
- if (diff)
- return diff;
- s += 2;
- t += 2;
- }
- else if (is_shift_jis (*s))
- return 1;
- else if (is_shift_jis (*t))
- return -1;
- else
- {
- diff = toupper (*s) - toupper (*t);
- if (diff)
- return diff;
- s++;
- t++;
- }
- }
- }
- else
-#endif /* KANJI_WIN95_COMPATIBILITY */
- {
- while (*s && *t && toupper(*s) == toupper(*t))
- {
- s++;
- t++;
- }
-
- return(toupper(*s) - toupper(*t));
- }
-}
-
-/*******************************************************************
- case insensitive string compararison, length limited
-********************************************************************/
-int StrnCaseCmp(char *s, char *t, int n)
-{
- /* compare until we run out of string, either t or s, or chars */
- /* We *must* use toupper rather than tolower here due to the
- asynchronous upper to lower mapping.
- */
-#if !defined(KANJI_WIN95_COMPATIBILITY)
- if(lp_client_code_page() == KANJI_CODEPAGE)
- {
- /* Win95 treats full width ascii characters as case sensitive. */
- int diff;
- for (;n > 0;)
- {
- if (!*s || !*t)
- return toupper (*s) - toupper (*t);
- else if (is_sj_alph (*s) && is_sj_alph (*t))
- {
- diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1));
- if (diff)
- return diff;
- s += 2;
- t += 2;
- n -= 2;
- }
- else if (is_shift_jis (*s) && is_shift_jis (*t))
- {
- diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t);
- if (diff)
- return diff;
- diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1));
- if (diff)
- return diff;
- s += 2;
- t += 2;
- n -= 2;
- }
- else if (is_shift_jis (*s))
- return 1;
- else if (is_shift_jis (*t))
- return -1;
- else
- {
- diff = toupper (*s) - toupper (*t);
- if (diff)
- return diff;
- s++;
- t++;
- n--;
- }
- }
- return 0;
- }
- else
-#endif /* KANJI_WIN95_COMPATIBILITY */
- {
- while (n-- && *s && *t && toupper(*s) == toupper(*t))
- {
- s++;
- t++;
- }
-
- /* not run out of chars - strings are different lengths */
- if (n)
- return(toupper(*s) - toupper(*t));
-
- /* identical up to where we run out of chars,
- and strings are same length */
- return(0);
- }
-}
-
-/*******************************************************************
- compare 2 strings
-********************************************************************/
-BOOL strequal(char *s1, char *s2)
-{
- if (s1 == s2) return(True);
- if (!s1 || !s2) return(False);
-
- return(StrCaseCmp(s1,s2)==0);
-}
-
-/*******************************************************************
- compare 2 strings up to and including the nth char.
- ******************************************************************/
-BOOL strnequal(char *s1,char *s2,int n)
-{
- if (s1 == s2) return(True);
- if (!s1 || !s2 || !n) return(False);
-
- return(StrnCaseCmp(s1,s2,n)==0);
-}
-
-/*******************************************************************
- compare 2 strings (case sensitive)
-********************************************************************/
-BOOL strcsequal(char *s1,char *s2)
-{
- if (s1 == s2) return(True);
- if (!s1 || !s2) return(False);
-
- return(strcmp(s1,s2)==0);
-}
-
-
-/*******************************************************************
- convert a string to lower case
-********************************************************************/
-void strlower(char *s)
-{
- while (*s)
- {
-#if !defined(KANJI_WIN95_COMPATIBILITY)
- if(lp_client_code_page() == KANJI_CODEPAGE)
- {
- /* Win95 treats full width ascii characters as case sensitive. */
- if (is_shift_jis (*s))
- {
- if (is_sj_upper (s[0], s[1]))
- s[1] = sj_tolower2 (s[1]);
- s += 2;
- }
- else if (is_kana (*s))
- {
- s++;
- }
- else
- {
- if (isupper(*s))
- *s = tolower(*s);
- s++;
- }
- }
- else
-#endif /* KANJI_WIN95_COMPATIBILITY */
- {
- if (isupper(*s))
- *s = tolower(*s);
- s++;
- }
- }
-}
-
-/*******************************************************************
- convert a string to upper case
-********************************************************************/
-void strupper(char *s)
-{
- while (*s)
- {
-#if !defined(KANJI_WIN95_COMPATIBILITY)
- if(lp_client_code_page() == KANJI_CODEPAGE)
- {
- /* Win95 treats full width ascii characters as case sensitive. */
- 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(*s))
- *s = toupper(*s);
- s++;
- }
- }
-}
-
-/*******************************************************************
- convert a string to "normal" form
-********************************************************************/
-void strnorm(char *s)
-{
- if (case_default == CASE_UPPER)
- strupper(s);
- else
- strlower(s);
-}
-
-/*******************************************************************
-check if a string is in "normal" case
-********************************************************************/
-BOOL strisnormal(char *s)
-{
- if (case_default == CASE_UPPER)
- return(!strhaslower(s));
-
- return(!strhasupper(s));
-}
-
-
-/****************************************************************************
- string replace
-****************************************************************************/
-void string_replace(char *s,char oldc,char newc)
-{
- while (*s)
- {
-#if !defined(KANJI_WIN95_COMPATIBILITY)
- if(lp_client_code_page() == KANJI_CODEPAGE)
- {
- /* Win95 treats full width ascii characters as case sensitive. */
- if (is_shift_jis (*s))
- s += 2;
- else if (is_kana (*s))
- s++;
- else
- {
- if (oldc == *s)
- *s = newc;
- s++;
- }
- }
- else
-#endif /* KANJI_WIN95_COMPATIBILITY */
- {
- if (oldc == *s)
- *s = newc;
- s++;
- }
- }
-}
-
-/****************************************************************************
- make a file into unix format
-****************************************************************************/
-void unix_format(char *fname)
-{
- pstring namecopy;
- string_replace(fname,'\\','/');
-
- if (*fname == '/')
- {
- pstrcpy(namecopy,fname);
- strcpy(fname,".");
- strcat(fname,namecopy);
- }
-}
-
-/****************************************************************************
- make a file into dos format
-****************************************************************************/
-void dos_format(char *fname)
-{
- string_replace(fname,'/','\\');
-}
-
-
-/*******************************************************************
- show a smb message structure
-********************************************************************/
-void show_msg(char *buf)
-{
- int i;
- int j;
- int bcc=0;
- if (DEBUGLEVEL < 5)
- return;
-
- DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
- smb_len(buf),
- (int)CVAL(buf,smb_com),
- (int)CVAL(buf,smb_rcls),
- (int)CVAL(buf,smb_reh),
- (int)SVAL(buf,smb_err),
- (int)CVAL(buf,smb_flg),
- (int)SVAL(buf,smb_flg2)));
- DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
- (int)SVAL(buf,smb_tid),
- (int)SVAL(buf,smb_pid),
- (int)SVAL(buf,smb_uid),
- (int)SVAL(buf,smb_mid),
- (int)CVAL(buf,smb_wct)));
- for (i=0;i<(int)CVAL(buf,smb_wct);i++)
- DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
- SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
- bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
- DEBUG(5,("smb_bcc=%d\n",bcc));
- if (DEBUGLEVEL < 10)
- return;
- for (i = 0; i < MIN(bcc, 256); i += 16)
- {
- for (j = 0; j < 16 && i+j < MIN(bcc,256); j++)
- {
-
- DEBUG(10,("%2X ",CVAL(smb_buf(buf),i+j)));
- if (j == 7) DEBUG(10, (" "));
-
- }
- DEBUG(10,(" "));
-
- for (j = 0; j < 16 && i+j < MIN(bcc,256); j++)
- {
- unsigned char c = CVAL(smb_buf(buf),i+j);
- if (c < 32 || c > 128) c = '.';
- DEBUG(10,("%c",c));
-
- if (j == 7) DEBUG(10, (" "));
- }
-
- DEBUG(10,("\n"));
-}
-}
-
-/*******************************************************************
- return the length of an smb packet
-********************************************************************/
-int smb_len(char *buf)
-{
- return( PVAL(buf,3) | (PVAL(buf,2)<<8) | ((PVAL(buf,1)&1)<<16) );
-}
-
-/*******************************************************************
- set the length of an smb packet
-********************************************************************/
-void _smb_setlen(char *buf,int len)
-{
- buf[0] = 0;
- buf[1] = (len&0x10000)>>16;
- buf[2] = (len&0xFF00)>>8;
- buf[3] = len&0xFF;
-}
-
-/*******************************************************************
- set the length and marker of an smb packet
-********************************************************************/
-void smb_setlen(char *buf,int len)
-{
- _smb_setlen(buf,len);
-
- CVAL(buf,4) = 0xFF;
- CVAL(buf,5) = 'S';
- CVAL(buf,6) = 'M';
- CVAL(buf,7) = 'B';
-}
-
-/*******************************************************************
- setup the word count and byte count for a smb message
-********************************************************************/
-int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
-{
- if (zero)
- bzero(buf + smb_size,num_words*2 + num_bytes);
- CVAL(buf,smb_wct) = num_words;
- SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
- smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
- return (smb_size + num_words*2 + num_bytes);
-}
-
-/*******************************************************************
-return the number of smb words
-********************************************************************/
-int smb_numwords(char *buf)
-{
- return (CVAL(buf,smb_wct));
-}
-
-/*******************************************************************
-return the size of the smb_buf region of a message
-********************************************************************/
-int smb_buflen(char *buf)
-{
- return(SVAL(buf,smb_vwv0 + smb_numwords(buf)*2));
-}
-
-/*******************************************************************
- return a pointer to the smb_buf data area
-********************************************************************/
-int smb_buf_ofs(char *buf)
-{
- return (smb_size + CVAL(buf,smb_wct)*2);
-}
-
-/*******************************************************************
- return a pointer to the smb_buf data area
-********************************************************************/
-char *smb_buf(char *buf)
-{
- return (buf + smb_buf_ofs(buf));
-}
-
-/*******************************************************************
-return the SMB offset into an SMB buffer
-********************************************************************/
-int smb_offset(char *p,char *buf)
-{
- return(PTR_DIFF(p,buf+4) + chain_size);
-}
-
-
-/*******************************************************************
-skip past some strings in a buffer
-********************************************************************/
-char *skip_string(char *buf,int n)
-{
- while (n--)
- buf += strlen(buf) + 1;
- return(buf);
-}
-
-/*******************************************************************
-trim the specified elements off the front and back of a string
-********************************************************************/
-BOOL trim_string(char *s,char *front,char *back)
-{
- BOOL ret = False;
- while (front && *front && strncmp(s,front,strlen(front)) == 0)
- {
- char *p = s;
- ret = True;
- while (1)
- {
- if (!(*p = p[strlen(front)]))
- break;
- p++;
- }
- }
- while (back && *back && strlen(s) >= strlen(back) &&
- (strncmp(s+strlen(s)-strlen(back),back,strlen(back))==0))
- {
- ret = True;
- s[strlen(s)-strlen(back)] = 0;
- }
- return(ret);
-}
-
-
-/*******************************************************************
-reduce a file name, removing .. elements.
-********************************************************************/
-void dos_clean_name(char *s)
-{
- char *p=NULL;
-
- DEBUG(3,("dos_clean_name [%s]\n",s));
-
- /* remove any double slashes */
- string_sub(s, "\\\\", "\\");
-
- while ((p = strstr(s,"\\..\\")) != NULL)
- {
- pstring s1;
-
- *p = 0;
- pstrcpy(s1,p+3);
-
- if ((p=strrchr(s,'\\')) != NULL)
- *p = 0;
- else
- *s = 0;
- strcat(s,s1);
- }
-
- trim_string(s,NULL,"\\..");
-
- string_sub(s, "\\.\\", "\\");
-}
-
-/*******************************************************************
-reduce a file name, removing .. elements.
-********************************************************************/
-void unix_clean_name(char *s)
-{
- char *p=NULL;
-
- DEBUG(3,("unix_clean_name [%s]\n",s));
-
- /* remove any double slashes */
- string_sub(s, "//","/");
-
- /* Remove leading ./ characters */
- if(strncmp(s, "./", 2) == 0) {
- trim_string(s, "./", NULL);
- if(*s == 0)
- strcpy(s,"./");
- }
-
- while ((p = strstr(s,"/../")) != NULL)
- {
- pstring s1;
-
- *p = 0;
- pstrcpy(s1,p+3);
-
- if ((p=strrchr(s,'/')) != NULL)
- *p = 0;
- else
- *s = 0;
- strcat(s,s1);
- }
-
- trim_string(s,NULL,"/..");
-}
-
-
-/*******************************************************************
-a wrapper for the normal chdir() function
-********************************************************************/
-int ChDir(char *path)
-{
- int res;
- static pstring LastDir="";
-
- if (strcsequal(path,".")) return(0);
-
- if (*path == '/' && strcsequal(LastDir,path)) return(0);
- DEBUG(3,("chdir to %s\n",path));
- res = sys_chdir(path);
- if (!res)
- pstrcpy(LastDir,path);
- return(res);
-}
-
-/* number of list structures for a caching GetWd function. */
-#define MAX_GETWDCACHE (50)
-
-struct
-{
- ino_t inode;
- dev_t dev;
- char *text;
- BOOL valid;
-} ino_list[MAX_GETWDCACHE];
-
-BOOL use_getwd_cache=True;
-
-/*******************************************************************
- return the absolute current directory path
-********************************************************************/
-char *GetWd(char *str)
-{
- pstring s;
- static BOOL getwd_cache_init = False;
- struct stat st, st2;
- int i;
-
- *s = 0;
-
- if (!use_getwd_cache)
- return(sys_getwd(str));
-
- /* init the cache */
- if (!getwd_cache_init)
- {
- getwd_cache_init = True;
- for (i=0;i<MAX_GETWDCACHE;i++)
- {
- string_init(&ino_list[i].text,"");
- ino_list[i].valid = False;
- }
- }
-
- /* Get the inode of the current directory, if this doesn't work we're
- in trouble :-) */
-
- if (stat(".",&st) == -1)
- {
- DEBUG(0,("Very strange, couldn't stat \".\"\n"));
- return(sys_getwd(str));
- }
-
-
- for (i=0; i<MAX_GETWDCACHE; i++)
- if (ino_list[i].valid)
- {
-
- /* If we have found an entry with a matching inode and dev number
- then find the inode number for the directory in the cached string.
- If this agrees with that returned by the stat for the current
- directory then all is o.k. (but make sure it is a directory all
- the same...) */
-
- if (st.st_ino == ino_list[i].inode &&
- st.st_dev == ino_list[i].dev)
- {
- if (stat(ino_list[i].text,&st2) == 0)
- {
- if (st.st_ino == st2.st_ino &&
- st.st_dev == st2.st_dev &&
- (st2.st_mode & S_IFMT) == S_IFDIR)
- {
- strcpy (str, ino_list[i].text);
-
- /* promote it for future use */
- array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
- return (str);
- }
- else
- {
- /* If the inode is different then something's changed,
- scrub the entry and start from scratch. */
- ino_list[i].valid = False;
- }
- }
- }
- }
-
-
- /* We don't have the information to hand so rely on traditional methods.
- The very slow getcwd, which spawns a process on some systems, or the
- not quite so bad getwd. */
-
- if (!sys_getwd(s))
- {
- DEBUG(0,("Getwd failed, errno %s\n",strerror(errno)));
- return (NULL);
- }
-
- strcpy(str,s);
-
- DEBUG(5,("GetWd %s, inode %d, dev %x\n",s,(int)st.st_ino,(int)st.st_dev));
-
- /* add it to the cache */
- i = MAX_GETWDCACHE - 1;
- string_set(&ino_list[i].text,s);
- ino_list[i].dev = st.st_dev;
- ino_list[i].inode = st.st_ino;
- ino_list[i].valid = True;
-
- /* put it at the top of the list */
- array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
-
- return (str);
-}
-
-
-
-/*******************************************************************
-reduce a file name, removing .. elements and checking that
-it is below dir in the heirachy. This uses GetWd() and so must be run
-on the system that has the referenced file system.
-
-widelinks are allowed if widelinks is true
-********************************************************************/
-BOOL reduce_name(char *s,char *dir,BOOL widelinks)
-{
-#ifndef REDUCE_PATHS
- return True;
-#else
- pstring dir2;
- pstring wd;
- pstring basename;
- pstring newname;
- char *p=NULL;
- BOOL relative = (*s != '/');
-
- *dir2 = *wd = *basename = *newname = 0;
-
- if (widelinks)
- {
- unix_clean_name(s);
- /* can't have a leading .. */
- if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
- {
- DEBUG(3,("Illegal file name? (%s)\n",s));
- return(False);
- }
-
- if (strlen(s) == 0)
- strcpy(s,"./");
-
- return(True);
- }
-
- DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
-
- /* remove any double slashes */
- string_sub(s,"//","/");
-
- pstrcpy(basename,s);
- p = strrchr(basename,'/');
-
- if (!p)
- return(True);
-
- if (!GetWd(wd))
- {
- DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
- return(False);
- }
-
- if (ChDir(dir) != 0)
- {
- DEBUG(0,("couldn't chdir to %s\n",dir));
- return(False);
- }
-
- if (!GetWd(dir2))
- {
- DEBUG(0,("couldn't getwd for %s\n",dir));
- ChDir(wd);
- return(False);
- }
-
-
- if (p && (p != basename))
- {
- *p = 0;
- if (strcmp(p+1,".")==0)
- p[1]=0;
- if (strcmp(p+1,"..")==0)
- *p = '/';
- }
-
- if (ChDir(basename) != 0)
- {
- ChDir(wd);
- DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename));
- return(False);
- }
-
- if (!GetWd(newname))
- {
- ChDir(wd);
- DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
- return(False);
- }
-
- if (p && (p != basename))
- {
- strcat(newname,"/");
- strcat(newname,p+1);
- }
-
- {
- int l = strlen(dir2);
- if (dir2[l-1] == '/')
- l--;
-
- if (strncmp(newname,dir2,l) != 0)
- {
- ChDir(wd);
- DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
- return(False);
- }
-
- if (relative)
- {
- if (newname[l] == '/')
- pstrcpy(s,newname + l + 1);
- else
- pstrcpy(s,newname+l);
- }
- else
- pstrcpy(s,newname);
- }
-
- ChDir(wd);
-
- if (strlen(s) == 0)
- strcpy(s,"./");
-
- DEBUG(3,("reduced to %s\n",s));
- return(True);
-#endif
-}
-
-/****************************************************************************
-expand some *s
-****************************************************************************/
-static void expand_one(char *Mask,int len)
-{
- char *p1;
- while ((p1 = strchr(Mask,'*')) != NULL)
- {
- int lfill = (len+1) - strlen(Mask);
- int l1= (p1 - Mask);
- pstring tmp;
- pstrcpy(tmp,Mask);
- memset(tmp+l1,'?',lfill);
- pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
- pstrcpy(Mask,tmp);
- }
-}
-
-/****************************************************************************
-expand a wildcard expression, replacing *s with ?s
-****************************************************************************/
-void expand_mask(char *Mask,BOOL doext)
-{
- pstring mbeg,mext;
- pstring dirpart;
- pstring filepart;
- BOOL hasdot = False;
- char *p1;
- BOOL absolute = (*Mask == '\\');
-
- *mbeg = *mext = *dirpart = *filepart = 0;
-
- /* parse the directory and filename */
- if (strchr(Mask,'\\'))
- dirname_dos(Mask,dirpart);
-
- filename_dos(Mask,filepart);
-
- pstrcpy(mbeg,filepart);
- if ((p1 = strchr(mbeg,'.')) != NULL)
- {
- hasdot = True;
- *p1 = 0;
- p1++;
- pstrcpy(mext,p1);
- }
- else
- {
- strcpy(mext,"");
- if (strlen(mbeg) > 8)
- {
- pstrcpy(mext,mbeg + 8);
- mbeg[8] = 0;
- }
- }
-
- if (*mbeg == 0)
- strcpy(mbeg,"????????");
- if ((*mext == 0) && doext && !hasdot)
- strcpy(mext,"???");
-
- if (strequal(mbeg,"*") && *mext==0)
- strcpy(mext,"*");
-
- /* expand *'s */
- expand_one(mbeg,8);
- if (*mext)
- expand_one(mext,3);
-
- pstrcpy(Mask,dirpart);
- if (*dirpart || absolute) strcat(Mask,"\\");
- strcat(Mask,mbeg);
- strcat(Mask,".");
- strcat(Mask,mext);
-
- DEBUG(6,("Mask expanded to [%s]\n",Mask));
-}
-
-
-/****************************************************************************
-does a string have any uppercase chars in it?
-****************************************************************************/
-BOOL strhasupper(char *s)
-{
- while (*s)
- {
-#if !defined(KANJI_WIN95_COMPATIBILITY)
- if(lp_client_code_page() == KANJI_CODEPAGE)
- {
- /* Win95 treats full width ascii characters as case sensitive. */
- if (is_shift_jis (*s))
- s += 2;
- else if (is_kana (*s))
- s++;
- else
- {
- if (isupper(*s))
- return(True);
- s++;
- }
- }
- else
-#endif /* KANJI_WIN95_COMPATIBILITY */
- {
- if (isupper(*s))
- return(True);
- s++;
- }
- }
- return(False);
-}
-
-/****************************************************************************
-does a string have any lowercase chars in it?
-****************************************************************************/
-BOOL strhaslower(char *s)
-{
- while (*s)
- {
-#if !defined(KANJI_WIN95_COMPATIBILITY)
- if(lp_client_code_page() == KANJI_CODEPAGE)
- {
- /* Win95 treats full width ascii characters as case sensitive. */
- if (is_shift_jis (*s))
- {
- if (is_sj_upper (s[0], s[1]))
- return(True);
- if (is_sj_lower (s[0], s[1]))
- return (True);
- s += 2;
- }
- else if (is_kana (*s))
- {
- s++;
- }
- else
- {
- if (islower(*s))
- return(True);
- s++;
- }
- }
- else
-#endif /* KANJI_WIN95_COMPATIBILITY */
- {
- if (islower(*s))
- return(True);
- s++;
- }
- }
- return(False);
-}
-
-/****************************************************************************
-find the number of chars in a string
-****************************************************************************/
-int count_chars(char *s,char c)
-{
- int count=0;
-
-#if !defined(KANJI_WIN95_COMPATIBILITY)
- if(lp_client_code_page() == KANJI_CODEPAGE)
- {
- /* Win95 treats full width ascii characters as case sensitive. */
- while (*s)
- {
- if (is_shift_jis (*s))
- s += 2;
- else
- {
- if (*s == c)
- count++;
- s++;
- }
- }
- }
- else
-#endif /* KANJI_WIN95_COMPATIBILITY */
- {
- while (*s)
- {
- if (*s == c)
- count++;
- s++;
- }
- }
- return(count);
-}
-
-
-/****************************************************************************
- make a dir struct
-****************************************************************************/
-void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode,time_t date)
-{
- char *p;
- pstring mask2;
-
- pstrcpy(mask2,mask);
-
- if ((mode & aDIR) != 0)
- size = 0;
-
- memset(buf+1,' ',11);
- if ((p = strchr(mask2,'.')) != NULL)
- {
- *p = 0;
- memcpy(buf+1,mask2,MIN(strlen(mask2),8));
- memcpy(buf+9,p+1,MIN(strlen(p+1),3));
- *p = '.';
- }
- else
- memcpy(buf+1,mask2,MIN(strlen(mask2),11));
-
- bzero(buf+21,DIR_STRUCT_SIZE-21);
- CVAL(buf,21) = mode;
- put_dos_date(buf,22,date);
- SSVAL(buf,26,size & 0xFFFF);
- SSVAL(buf,28,size >> 16);
- StrnCpy(buf+30,fname,12);
- if (!case_sensitive)
- strupper(buf+30);
- DEBUG(8,("put name [%s] into dir struct\n",buf+30));
-}
-
-
-/*******************************************************************
-close the low 3 fd's and open dev/null in their place
-********************************************************************/
-void close_low_fds(void)
-{
- int fd;
- int i;
- close(0); close(1); close(2);
- /* try and use up these file descriptors, so silly
- library routines writing to stdout etc won't cause havoc */
- for (i=0;i<3;i++) {
- fd = open("/dev/null",O_RDWR,0);
- if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
- if (fd < 0) {
- DEBUG(0,("Can't open /dev/null\n"));
- return;
- }
- if (fd != i) {
- DEBUG(0,("Didn't get file descriptor %d\n",i));
- return;
- }
- }
-}
-
-/****************************************************************************
-Set a fd into blocking/nonblocking mode. Uses POSIX O_NONBLOCK if available,
-else
-if SYSV use O_NDELAY
-if BSD use FNDELAY
-****************************************************************************/
-int set_blocking(int fd, BOOL set)
-{
- int val;
-#ifdef O_NONBLOCK
-#define FLAG_TO_SET O_NONBLOCK
-#else
-#ifdef SYSV
-#define FLAG_TO_SET O_NDELAY
-#else /* BSD */
-#define FLAG_TO_SET FNDELAY
-#endif
-#endif
-
- if((val = fcntl(fd, F_GETFL, 0)) == -1)
- return -1;
- if(set) /* Turn blocking on - ie. clear nonblock flag */
- val &= ~FLAG_TO_SET;
- else
- val |= FLAG_TO_SET;
- return fcntl( fd, F_SETFL, val);
-#undef FLAG_TO_SET
-}
-
-
-/****************************************************************************
-write to a socket
-****************************************************************************/
-int write_socket(int fd,char *buf,int len)
-{
- int ret=0;
-
- if (passive)
- return(len);
- DEBUG(6,("write_socket(%d,%d)\n",fd,len));
- ret = write_data(fd,buf,len);
-
- DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
- return(ret);
-}
-
-/****************************************************************************
-read from a socket
-****************************************************************************/
-int read_udp_socket(int fd,char *buf,int len)
-{
- int ret;
- struct sockaddr sock;
- int socklen;
-
- socklen = sizeof(sock);
- bzero((char *)&sock,socklen);
- bzero((char *)&lastip,sizeof(lastip));
- ret = recvfrom(fd,buf,len,0,&sock,&socklen);
- if (ret <= 0) {
- DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
- return(0);
- }
-
- lastip = *(struct in_addr *) &sock.sa_data[2];
- lastport = ntohs(((struct sockaddr_in *)&sock)->sin_port);
-
- return(ret);
-}
-
-/****************************************************************************
-read data from a device with a timout in msec.
-mincount = if timeout, minimum to read before returning
-maxcount = number to be read.
-****************************************************************************/
-int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out)
-{
- fd_set fds;
- int selrtn;
- int readret;
- int nread = 0;
- struct timeval timeout;
-
- /* just checking .... */
- if (maxcnt <= 0) return(0);
-
- smb_read_error = 0;
-
- /* Blocking read */
- if (time_out <= 0) {
- if (mincnt == 0) mincnt = maxcnt;
-
- while (nread < mincnt) {
- readret = read(fd, buf + nread, maxcnt - nread);
- if (readret == 0) {
- smb_read_error = READ_EOF;
- return -1;
- }
-
- if (readret == -1) {
- smb_read_error = READ_ERROR;
- return -1;
- }
- nread += readret;
- }
- return(nread);
- }
-
- /* Most difficult - timeout read */
- /* If this is ever called on a disk file and
- mincnt is greater then the filesize then
- system performance will suffer severely as
- select always return true on disk files */
-
- /* Set initial timeout */
- timeout.tv_sec = time_out / 1000;
- timeout.tv_usec = 1000 * (time_out % 1000);
-
- for (nread=0; nread<mincnt; )
- {
- FD_ZERO(&fds);
- FD_SET(fd,&fds);
-
- selrtn = sys_select(&fds,&timeout);
-
- /* Check if error */
- if(selrtn == -1) {
- /* something is wrong. Maybe the socket is dead? */
- smb_read_error = READ_ERROR;
- return -1;
- }
-
- /* Did we timeout ? */
- if (selrtn == 0) {
- smb_read_error = READ_TIMEOUT;
- return -1;
- }
-
- readret = read(fd, buf+nread, maxcnt-nread);
- if (readret == 0) {
- /* we got EOF on the file descriptor */
- smb_read_error = READ_EOF;
- return -1;
- }
-
- if (readret == -1) {
- /* the descriptor is probably dead */
- smb_read_error = READ_ERROR;
- return -1;
- }
-
- nread += readret;
- }
-
- /* Return the number we got */
- return(nread);
-}
-
-/****************************************************************************
-read data from the client. Maxtime is in milliseconds
-****************************************************************************/
-int read_max_udp(int fd,char *buffer,int bufsize,int maxtime)
-{
- fd_set fds;
- int selrtn;
- int nread;
- struct timeval timeout;
-
- FD_ZERO(&fds);
- FD_SET(fd,&fds);
-
- timeout.tv_sec = maxtime / 1000;
- timeout.tv_usec = (maxtime % 1000) * 1000;
-
- selrtn = sys_select(&fds,maxtime>0?&timeout:NULL);
-
- if (!FD_ISSET(fd,&fds))
- return 0;
-
- nread = read_udp_socket(fd, buffer, bufsize);
-
- /* return the number got */
- return(nread);
-}
-
-/*******************************************************************
-find the difference in milliseconds between two struct timeval
-values
-********************************************************************/
-int TvalDiff(struct timeval *tvalold,struct timeval *tvalnew)
-{
- return((tvalnew->tv_sec - tvalold->tv_sec)*1000 +
- ((int)tvalnew->tv_usec - (int)tvalold->tv_usec)/1000);
-}
-
-/****************************************************************************
-send a keepalive packet (rfc1002)
-****************************************************************************/
-BOOL send_keepalive(int client)
-{
- unsigned char buf[4];
-
- buf[0] = 0x85;
- buf[1] = buf[2] = buf[3] = 0;
-
- return(write_data(client,(char *)buf,4) == 4);
-}
-
-
-
-/****************************************************************************
- read data from the client, reading exactly N bytes.
-****************************************************************************/
-int read_data(int fd,char *buffer,int N)
-{
- int ret;
- int total=0;
-
- smb_read_error = 0;
-
- while (total < N)
- {
- ret = read(fd,buffer + total,N - total);
- if (ret == 0) {
- smb_read_error = READ_EOF;
- return 0;
- }
- if (ret == -1) {
- smb_read_error = READ_ERROR;
- return -1;
- }
- total += ret;
- }
- return total;
-}
-
-
-/****************************************************************************
- write data to a fd
-****************************************************************************/
-int write_data(int fd,char *buffer,int N)
-{
- int total=0;
- int ret;
-
- while (total < N)
- {
- ret = write(fd,buffer + total,N - total);
-
- if (ret == -1) return -1;
- if (ret == 0) return total;
-
- total += ret;
- }
- return total;
-}
-
-
-/****************************************************************************
-transfer some data between two fd's
-****************************************************************************/
-int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align)
-{
- static char *buf=NULL;
- static int size=0;
- char *buf1,*abuf;
- int total = 0;
-
- DEBUG(4,("transfer_file %d (head=%d) called\n",n,headlen));
-
- if (size == 0) {
- size = lp_readsize();
- size = MAX(size,1024);
- }
-
- while (!buf && size>0) {
- buf = (char *)Realloc(buf,size+8);
- if (!buf) size /= 2;
- }
-
- if (!buf) {
- DEBUG(0,("Can't allocate transfer buffer!\n"));
- exit(1);
- }
-
- abuf = buf + (align%8);
-
- if (header)
- n += headlen;
-
- while (n > 0)
- {
- int s = MIN(n,size);
- int ret,ret2=0;
-
- ret = 0;
-
- if (header && (headlen >= MIN(s,1024))) {
- buf1 = header;
- s = headlen;
- ret = headlen;
- headlen = 0;
- header = NULL;
- } else {
- buf1 = abuf;
- }
-
- if (header && headlen > 0)
- {
- ret = MIN(headlen,size);
- memcpy(buf1,header,ret);
- headlen -= ret;
- header += ret;
- if (headlen <= 0) header = NULL;
- }
-
- if (s > ret)
- ret += read(infd,buf1+ret,s-ret);
-
- if (ret > 0)
- {
- ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
- if (ret2 > 0) total += ret2;
- /* if we can't write then dump excess data */
- if (ret2 != ret)
- transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
- }
- if (ret <= 0 || ret2 != ret)
- return(total);
- n -= ret;
- }
- return(total);
-}
-
-
-/****************************************************************************
-read 4 bytes of a smb packet and return the smb length of the packet
-possibly store the result in the buffer
-****************************************************************************/
-int read_smb_length(int fd,char *inbuf,int timeout)
-{
- char *buffer;
- char buf[4];
- int len=0, msg_type;
- BOOL ok=False;
-
- if (inbuf)
- buffer = inbuf;
- else
- buffer = buf;
-
- while (!ok)
- {
- if (timeout > 0)
- ok = (read_with_timeout(fd,buffer,4,4,timeout) == 4);
- else
- ok = (read_data(fd,buffer,4) == 4);
-
- if (!ok)
- return(-1);
-
- len = smb_len(buffer);
- msg_type = CVAL(buffer,0);
-
- if (msg_type == 0x85)
- {
- DEBUG(5,("Got keepalive packet\n"));
- ok = False;
- }
- }
-
- DEBUG(10,("got smb length of %d\n",len));
-
- return(len);
-}
-
-
-
-/****************************************************************************
- read an smb from a fd. Note that the buffer *MUST* be of size
- BUFFER_SIZE+SAFETY_MARGIN.
-The timeout is in milli seconds
-****************************************************************************/
-BOOL receive_smb(int fd,char *buffer, int timeout)
-{
- int len,ret;
-
- smb_read_error = 0;
-
- bzero(buffer,smb_size + 100);
-
- len = read_smb_length(fd,buffer,timeout);
- if (len == -1)
- return(False);
-
- if (len > BUFFER_SIZE) {
- DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
- if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
- exit(1);
- }
-
- ret = read_data(fd,buffer+4,len);
- if (ret != len) {
- smb_read_error = READ_ERROR;
- return False;
- }
-
- return(True);
-}
-
-/****************************************************************************
- read a message from a udp fd.
-The timeout is in milli seconds
-****************************************************************************/
-BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout)
-{
- struct sockaddr_in from;
- int fromlen = sizeof(from);
- int32 msg_len = 0;
-
- if(timeout != 0)
- {
- struct timeval to;
- fd_set fds;
- int selrtn;
-
- FD_ZERO(&fds);
- FD_SET(fd,&fds);
-
- to.tv_sec = timeout / 1000;
- to.tv_usec = (timeout % 1000) * 1000;
-
- selrtn = sys_select(&fds,&to);
-
- /* Check if error */
- if(selrtn == -1)
- {
- /* something is wrong. Maybe the socket is dead? */
- smb_read_error = READ_ERROR;
- return False;
- }
-
- /* Did we timeout ? */
- if (selrtn == 0)
- {
- smb_read_error = READ_TIMEOUT;
- return False;
- }
- }
-
- /*
- * Read a loopback udp message.
- */
- msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN],
- buffer_len - UDP_CMD_HEADER_LEN, 0,
- (struct sockaddr *)&from, &fromlen);
-
- if(msg_len < 0)
- {
- DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
- return False;
- }
-
- /* Validate message length. */
- if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN))
- {
- DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
- msg_len,
- buffer_len - UDP_CMD_HEADER_LEN));
- return False;
- }
-
- /* Validate message from address (must be localhost). */
- if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK))
- {
- DEBUG(0,("receive_local_message: invalid 'from' address \
-(was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
- return False;
- }
-
- /* Setup the message header */
- SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len);
- SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port));
-
- return True;
-}
-
-/****************************************************************************
- structure to hold a linked list of local udp messages.
- for processing.
-****************************************************************************/
-
-typedef struct _udp_message_list {
- struct _udp_message_list *msg_next;
- char *msg_buf;
- int msg_len;
-} udp_message_list;
-
-static udp_message_list *udp_msg_head = NULL;
-
-/****************************************************************************
- Function to push a linked list of local udp messages ready
- for processing.
-****************************************************************************/
-BOOL push_local_message(char *buf, int msg_len)
-{
- udp_message_list *msg = (udp_message_list *)malloc(sizeof(udp_message_list));
-
- if(msg == NULL)
- {
- DEBUG(0,("push_local_message: malloc fail (1)\n"));
- return False;
- }
-
- msg->msg_buf = (char *)malloc(msg_len);
- if(msg->msg_buf == NULL)
- {
- DEBUG(0,("push_local_message: malloc fail (2)\n"));
- free((char *)msg);
- return False;
- }
-
- memcpy(msg->msg_buf, buf, msg_len);
- msg->msg_len = msg_len;
-
- msg->msg_next = udp_msg_head;
- udp_msg_head = msg;
-
- return True;
-}
-
-/****************************************************************************
- Do a select on an two fd's - with timeout.
-
- If a local udp message has been pushed onto the
- queue (this can only happen during oplock break
- processing) return this first.
-
- If the first smbfd is ready then read an smb from it.
- if the second (loopback UDP) fd is ready then read a message
- from it and setup the buffer header to identify the length
- and from address.
- Returns False on timeout or error.
- Else returns True.
-
-The timeout is in milli seconds
-****************************************************************************/
-BOOL receive_message_or_smb(int smbfd, int oplock_fd,
- char *buffer, int buffer_len,
- int timeout, BOOL *got_smb)
-{
- fd_set fds;
- int selrtn;
- struct timeval to;
-
- *got_smb = False;
-
- /*
- * Check to see if we already have a message on the udp queue.
- * If so - copy and return it.
- */
-
- if(udp_msg_head)
- {
- udp_message_list *msg = udp_msg_head;
- memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len));
- udp_msg_head = msg->msg_next;
-
- /* Free the message we just copied. */
- free((char *)msg->msg_buf);
- free((char *)msg);
- return True;
- }
-
- FD_ZERO(&fds);
- FD_SET(smbfd,&fds);
- FD_SET(oplock_fd,&fds);
-
- to.tv_sec = timeout / 1000;
- to.tv_usec = (timeout % 1000) * 1000;
-
- selrtn = sys_select(&fds,timeout>0?&to:NULL);
-
- /* Check if error */
- if(selrtn == -1) {
- /* something is wrong. Maybe the socket is dead? */
- smb_read_error = READ_ERROR;
- return False;
- }
-
- /* Did we timeout ? */
- if (selrtn == 0) {
- smb_read_error = READ_TIMEOUT;
- return False;
- }
-
- if (FD_ISSET(smbfd,&fds))
- {
- *got_smb = True;
- return receive_smb(smbfd, buffer, 0);
- }
- else
- {
- return receive_local_message(oplock_fd, buffer, buffer_len, 0);
- }
-}
-
-/****************************************************************************
- send an smb to a fd
-****************************************************************************/
-BOOL send_smb(int fd,char *buffer)
-{
- int len;
- int ret,nwritten=0;
- len = smb_len(buffer) + 4;
-
- while (nwritten < len)
- {
- ret = write_socket(fd,buffer+nwritten,len - nwritten);
- if (ret <= 0)
- {
- DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
- close_sockets();
- exit(1);
- }
- nwritten += ret;
- }
-
-
- return True;
-}
-
-
-/****************************************************************************
-find a pointer to a netbios name
-****************************************************************************/
-char *name_ptr(char *buf,int ofs)
-{
- unsigned char c = *(unsigned char *)(buf+ofs);
-
- if ((c & 0xC0) == 0xC0)
- {
- uint16 l;
- char p[2];
- memcpy(p,buf+ofs,2);
- p[0] &= ~0xC0;
- l = RSVAL(p,0);
- DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
- return(buf + l);
- }
- else
- return(buf+ofs);
-}
-
-/****************************************************************************
-extract a netbios name from a buf
-****************************************************************************/
-int name_extract(char *buf,int ofs,char *name)
-{
- char *p = name_ptr(buf,ofs);
- int d = PTR_DIFF(p,buf+ofs);
- strcpy(name,"");
- if (d < -50 || d > 50) return(0);
- return(name_interpret(p,name));
-}
-
-/****************************************************************************
-return the total storage length of a mangled name
-****************************************************************************/
-int name_len( char *s )
- {
- int len;
-
- /* If the two high bits of the byte are set, return 2. */
- if( 0xC0 == (*(unsigned char *)s & 0xC0) )
- return(2);
-
- /* Add up the length bytes. */
- for( len = 1; (*s); s += (*s) + 1 )
- {
- len += *s + 1;
- }
-
- return( len );
- } /* name_len */
-
-/****************************************************************************
-send a single packet to a port on another machine
-****************************************************************************/
-BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
-{
- BOOL ret;
- int out_fd;
- struct sockaddr_in sock_out;
-
- if (passive)
- return(True);
-
- /* create a socket to write to */
- out_fd = socket(AF_INET, type, 0);
- if (out_fd == -1)
- {
- DEBUG(0,("socket failed"));
- return False;
- }
-
- /* set the address and port */
- bzero((char *)&sock_out,sizeof(sock_out));
- putip((char *)&sock_out.sin_addr,(char *)&ip);
- sock_out.sin_port = htons( port );
- sock_out.sin_family = AF_INET;
-
- if (DEBUGLEVEL > 0)
- DEBUG(3,("sending a packet of len %d to (%s) on port %d of type %s\n",
- len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
-
- /* send it */
- ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
-
- if (!ret)
- DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
- inet_ntoa(ip),port,strerror(errno)));
-
- close(out_fd);
- return(ret);
-}
-
-/*******************************************************************
-sleep for a specified number of milliseconds
-********************************************************************/
-void msleep(int t)
-{
- int tdiff=0;
- struct timeval tval,t1,t2;
- fd_set fds;
-
- GetTimeOfDay(&t1);
- GetTimeOfDay(&t2);
-
- while (tdiff < t) {
- tval.tv_sec = (t-tdiff)/1000;
- tval.tv_usec = 1000*((t-tdiff)%1000);
-
- FD_ZERO(&fds);
- errno = 0;
- sys_select(&fds,&tval);
-
- GetTimeOfDay(&t2);
- tdiff = TvalDiff(&t1,&t2);
- }
-}
-
-/****************************************************************************
-check if a string is part of a list
-****************************************************************************/
-BOOL in_list(char *s,char *list,BOOL casesensitive)
-{
- pstring tok;
- char *p=list;
-
- if (!list) return(False);
-
- while (next_token(&p,tok,LIST_SEP))
- {
- if (casesensitive) {
- if (strcmp(tok,s) == 0)
- return(True);
- } else {
- if (StrCaseCmp(tok,s) == 0)
- return(True);
- }
- }
- return(False);
-}
-
-/* this is used to prevent lots of mallocs of size 1 */
-static char *null_string = NULL;
-
-/****************************************************************************
-set a string value, allocing the space for the string
-****************************************************************************/
-BOOL string_init(char **dest,char *src)
-{
- int l;
- if (!src)
- src = "";
-
- l = strlen(src);
-
- if (l == 0)
- {
- if (!null_string)
- null_string = (char *)malloc(1);
-
- *null_string = 0;
- *dest = null_string;
- }
- else
- {
- (*dest) = (char *)malloc(l+1);
- if ((*dest) == NULL) {
- DEBUG(0,("Out of memory in string_init\n"));
- return False;
- }
-
- strcpy(*dest,src);
- }
- return(True);
-}
-
-/****************************************************************************
-free a string value
-****************************************************************************/
-void string_free(char **s)
-{
- if (!s || !(*s)) return;
- if (*s == null_string)
- *s = NULL;
- if (*s) free(*s);
- *s = NULL;
-}
-
-/****************************************************************************
-set a string value, allocing the space for the string, and deallocating any
-existing space
-****************************************************************************/
-BOOL string_set(char **dest,char *src)
-{
- string_free(dest);
-
- return(string_init(dest,src));
-}
-
-/****************************************************************************
-substitute a string for a pattern in another string. Make sure there is
-enough room!
-
-This routine looks for pattern in s and replaces it with
-insert. It may do multiple replacements.
-
-return True if a substitution was done.
-****************************************************************************/
-BOOL string_sub(char *s,char *pattern,char *insert)
-{
- BOOL ret = False;
- char *p;
- int ls,lp,li;
-
- if (!insert || !pattern || !s) return(False);
-
- ls = strlen(s);
- lp = strlen(pattern);
- li = strlen(insert);
-
- if (!*pattern) return(False);
-
- while (lp <= ls && (p = strstr(s,pattern)))
- {
- ret = True;
- memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
- memcpy(p,insert,li);
- s = p + li;
- ls = strlen(s);
- }
- return(ret);
-}
-
-
-
-/*********************************************************
-* Recursive routine that is called by mask_match.
-* Does the actual matching.
-*********************************************************/
-BOOL do_match(char *str, char *regexp, int case_sig)
-{
- char *p;
-
- for( p = regexp; *p && *str; ) {
- switch(*p) {
- case '?':
- str++; p++;
- break;
-
- case '*':
- /* Look for a character matching
- the one after the '*' */
- p++;
- if(!*p)
- return True; /* Automatic match */
- while(*str) {
- while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
- str++;
- if(do_match(str,p,case_sig))
- return True;
- if(!*str)
- return False;
- else
- str++;
- }
- return False;
-
- default:
- if(case_sig) {
- if(*str != *p)
- return False;
- } else {
- if(toupper(*str) != toupper(*p))
- return False;
- }
- str++, p++;
- break;
- }
- }
- if(!*p && !*str)
- return True;
-
- if (!*p && str[0] == '.' && str[1] == 0)
- return(True);
-
- if (!*str && *p == '?')
- {
- while (*p == '?') p++;
- return(!*p);
- }
-
- if(!*str && (*p == '*' && p[1] == '\0'))
- return True;
- return False;
-}
-
-
-/*********************************************************
-* Routine to match a given string with a regexp - uses
-* simplified regexp that takes * and ? only. Case can be
-* significant or not.
-*********************************************************/
-BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2)
-{
- char *p;
- pstring p1, p2;
- fstring ebase,eext,sbase,sext;
-
- BOOL matched;
-
- /* Make local copies of str and regexp */
- StrnCpy(p1,regexp,sizeof(pstring)-1);
- StrnCpy(p2,str,sizeof(pstring)-1);
-
- if (!strchr(p2,'.')) {
- strcat(p2,".");
- }
-
-/*
- if (!strchr(p1,'.')) {
- strcat(p1,".");
- }
-*/
-
-#if 0
- if (strchr(p1,'.'))
- {
- string_sub(p1,"*.*","*");
- string_sub(p1,".*","*");
- }
-#endif
-
- /* Remove any *? and ** as they are meaningless */
- for(p = p1; *p; p++)
- while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
- (void)strcpy( &p[1], &p[2]);
-
- if (strequal(p1,"*")) return(True);
-
- DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
-
- if (trans2) {
- fstrcpy(ebase,p1);
- fstrcpy(sbase,p2);
- } else {
- if ((p=strrchr(p1,'.'))) {
- *p = 0;
- fstrcpy(ebase,p1);
- fstrcpy(eext,p+1);
- } else {
- fstrcpy(ebase,p1);
- eext[0] = 0;
- }
-
- if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) {
- *p = 0;
- fstrcpy(sbase,p2);
- fstrcpy(sext,p+1);
- } else {
- fstrcpy(sbase,p2);
- fstrcpy(sext,"");
- }
- }
-
- matched = do_match(sbase,ebase,case_sig) &&
- (trans2 || do_match(sext,eext,case_sig));
-
- DEBUG(8,("mask_match returning %d\n", matched));
-
- return matched;
-}
-
-
-
-/****************************************************************************
-become a daemon, discarding the controlling terminal
-****************************************************************************/
-void become_daemon(void)
-{
-#ifndef NO_FORK_DEBUG
- if (fork())
- exit(0);
-
- /* detach from the terminal */
-#ifdef USE_SETSID
- setsid();
-#else /* USE_SETSID */
-#ifdef TIOCNOTTY
- {
- int i = open("/dev/tty", O_RDWR);
- if (i >= 0)
- {
- ioctl(i, (int) TIOCNOTTY, (char *)0);
- close(i);
- }
- }
-#endif /* TIOCNOTTY */
-#endif /* USE_SETSID */
- /* Close fd's 0,1,2. Needed if started by rsh */
- close_low_fds();
-#endif /* NO_FORK_DEBUG */
-}
-
-
-/****************************************************************************
-put up a yes/no prompt
-****************************************************************************/
-BOOL yesno(char *p)
-{
- pstring ans;
- printf("%s",p);
-
- if (!fgets(ans,sizeof(ans)-1,stdin))
- return(False);
-
- if (*ans == 'y' || *ans == 'Y')
- return(True);
-
- return(False);
-}
-
-/****************************************************************************
-read a line from a file with possible \ continuation chars.
-Blanks at the start or end of a line are stripped.
-The string will be allocated if s2 is NULL
-****************************************************************************/
-char *fgets_slash(char *s2,int maxlen,FILE *f)
-{
- char *s=s2;
- int len = 0;
- int c;
- BOOL start_of_line = True;
-
- if (feof(f))
- return(NULL);
-
- if (!s2)
- {
- maxlen = MIN(maxlen,8);
- s = (char *)Realloc(s,maxlen);
- }
-
- if (!s || maxlen < 2) return(NULL);
-
- *s = 0;
-
- while (len < maxlen-1)
- {
- c = getc(f);
- switch (c)
- {
- case '\r':
- break;
- case '\n':
- while (len > 0 && s[len-1] == ' ')
- {
- s[--len] = 0;
- }
- if (len > 0 && s[len-1] == '\\')
- {
- s[--len] = 0;
- start_of_line = True;
- break;
- }
- return(s);
- case EOF:
- if (len <= 0 && !s2)
- free(s);
- return(len>0?s:NULL);
- case ' ':
- if (start_of_line)
- break;
- default:
- start_of_line = False;
- s[len++] = c;
- s[len] = 0;
- }
- if (!s2 && len > maxlen-3)
- {
- maxlen *= 2;
- s = (char *)Realloc(s,maxlen);
- if (!s) return(NULL);
- }
- }
- return(s);
-}
-
-
-
-/****************************************************************************
-set the length of a file from a filedescriptor.
-Returns 0 on success, -1 on failure.
-****************************************************************************/
-int set_filelen(int fd, long len)
-{
-/* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
- extend a file with ftruncate. Provide alternate implementation
- for this */
-
-#if FTRUNCATE_CAN_EXTEND
- return ftruncate(fd, len);
-#else
- struct stat st;
- char c = 0;
- long currpos = lseek(fd, 0L, SEEK_CUR);
-
- if(currpos < 0)
- return -1;
- /* Do an fstat to see if the file is longer than
- the requested size (call ftruncate),
- or shorter, in which case seek to len - 1 and write 1
- byte of zero */
- if(fstat(fd, &st)<0)
- return -1;
-
-#ifdef S_ISFIFO
- if (S_ISFIFO(st.st_mode)) return 0;
-#endif
-
- if(st.st_size == len)
- return 0;
- if(st.st_size > len)
- return ftruncate(fd, len);
-
- if(lseek(fd, len-1, SEEK_SET) != len -1)
- return -1;
- if(write(fd, &c, 1)!=1)
- return -1;
- /* Seek to where we were */
- lseek(fd, currpos, SEEK_SET);
- return 0;
-#endif
-}
-
-
-/****************************************************************************
-return the byte checksum of some data
-****************************************************************************/
-int byte_checksum(char *buf,int len)
-{
- unsigned char *p = (unsigned char *)buf;
- int ret = 0;
- while (len--)
- ret += *p++;
- return(ret);
-}
-
-
-
-#ifdef HPUX
-/****************************************************************************
-this is a version of setbuffer() for those machines that only have setvbuf
-****************************************************************************/
- void setbuffer(FILE *f,char *buf,int bufsize)
-{
- setvbuf(f,buf,_IOFBF,bufsize);
-}
-#endif
-
-
-/****************************************************************************
-parse out a directory name from a path name. Assumes dos style filenames.
-****************************************************************************/
-char *dirname_dos(char *path,char *buf)
-{
- char *p = strrchr(path,'\\');
-
- if (!p)
- strcpy(buf,path);
- else
- {
- *p = 0;
- strcpy(buf,path);
- *p = '\\';
- }
-
- return(buf);
-}
-
-
-/****************************************************************************
-parse out a filename from a path name. Assumes dos style filenames.
-****************************************************************************/
-static char *filename_dos(char *path,char *buf)
-{
- char *p = strrchr(path,'\\');
-
- if (!p)
- strcpy(buf,path);
- else
- strcpy(buf,p+1);
-
- return(buf);
-}
-
-
-
-/****************************************************************************
-expand a pointer to be a particular size
-****************************************************************************/
-void *Realloc(void *p,int size)
-{
- void *ret=NULL;
-
- if (size == 0) {
- if (p) free(p);
- DEBUG(5,("Realloc asked for 0 bytes\n"));
- return NULL;
- }
-
- if (!p)
- ret = (void *)malloc(size);
- else
- ret = (void *)realloc(p,size);
-
- if (!ret)
- DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",size));
-
- return(ret);
-}
-
-#ifdef NOSTRDUP
-/****************************************************************************
-duplicate a string
-****************************************************************************/
- char *strdup(char *s)
-{
- char *ret = NULL;
- if (!s) return(NULL);
- ret = (char *)malloc(strlen(s)+1);
- if (!ret) return(NULL);
- strcpy(ret,s);
- return(ret);
-}
-#endif
-
-
-/****************************************************************************
- Signal handler for SIGPIPE (write on a disconnected socket)
-****************************************************************************/
-void Abort(void )
-{
- DEBUG(0,("Probably got SIGPIPE\nExiting\n"));
- exit(2);
-}
-
-/****************************************************************************
-get my own name and IP
-****************************************************************************/
-BOOL get_myname(char *my_name,struct in_addr *ip)
-{
- struct hostent *hp;
- pstring hostname;
-
- *hostname = 0;
-
- /* get my host name */
- if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
- {
- DEBUG(0,("gethostname failed\n"));
- return False;
- }
-
- /* get host info */
- if ((hp = Get_Hostbyname(hostname)) == 0)
- {
- DEBUG(0,( "Get_Hostbyname: Unknown host %s.\n",hostname));
- return False;
- }
-
- if (my_name)
- {
- /* split off any parts after an initial . */
- char *p = strchr(hostname,'.');
- if (p) *p = 0;
-
- fstrcpy(my_name,hostname);
- }
-
- if (ip)
- putip((char *)ip,(char *)hp->h_addr);
-
- return(True);
-}
-
-
-/****************************************************************************
-true if two IP addresses are equal
-****************************************************************************/
-BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
-{
- uint32 a1,a2;
- a1 = ntohl(ip1.s_addr);
- a2 = ntohl(ip2.s_addr);
- return(a1 == a2);
-}
-
-
-/****************************************************************************
-open a socket of the specified type, port and address for incoming data
-****************************************************************************/
-int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
-{
- struct hostent *hp;
- struct sockaddr_in sock;
- pstring host_name;
- int res;
-
- /* get my host name */
- if (gethostname(host_name, MAXHOSTNAMELEN) == -1)
- { DEBUG(0,("gethostname failed\n")); return -1; }
-
- /* get host info */
- if ((hp = Get_Hostbyname(host_name)) == 0)
- {
- DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",host_name));
- return -1;
- }
-
- bzero((char *)&sock,sizeof(sock));
- memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
-#if defined(__FreeBSD__) || defined(NETBSD) /* XXX not the right ifdef */
- sock.sin_len = sizeof(sock);
-#endif
- sock.sin_port = htons( port );
- sock.sin_family = hp->h_addrtype;
- sock.sin_addr.s_addr = socket_addr;
- res = socket(hp->h_addrtype, type, 0);
- if (res == -1)
- { DEBUG(0,("socket failed\n")); return -1; }
-
- {
- int one=1;
- setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
- }
-
- /* now we've got a socket - we need to bind it */
- if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) < 0)
- {
- if (port) {
- if (port == SMB_PORT || port == NMB_PORT)
- DEBUG(dlevel,("bind failed on port %d socket_addr=%x (%s)\n",
- port,socket_addr,strerror(errno)));
- close(res);
-
- if (dlevel > 0 && port < 1000)
- port = 7999;
-
- if (port >= 1000 && port < 9000)
- return(open_socket_in(type,port+1,dlevel,socket_addr));
- }
-
- return(-1);
- }
- DEBUG(3,("bind succeeded on port %d\n",port));
-
- return res;
-}
-
-
-/****************************************************************************
- create an outgoing socket
- **************************************************************************/
-int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
-{
- struct sockaddr_in sock_out;
- int res,ret;
- int connect_loop = 250; /* 250 milliseconds */
- int loops = (timeout * 1000) / connect_loop;
-
- /* create a socket to write to */
- res = socket(PF_INET, type, 0);
- if (res == -1)
- { DEBUG(0,("socket error\n")); return -1; }
-
- if (type != SOCK_STREAM) return(res);
-
- bzero((char *)&sock_out,sizeof(sock_out));
- putip((char *)&sock_out.sin_addr,(char *)addr);
-
- sock_out.sin_port = htons( port );
- sock_out.sin_family = PF_INET;
-
- /* set it non-blocking */
- set_blocking(res,False);
-
- DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port));
-
- /* and connect it to the destination */
-connect_again:
- ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out));
-
- /* Some systems return EAGAIN when they mean EINPROGRESS */
- if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
- errno == EAGAIN) && loops--) {
- msleep(connect_loop);
- goto connect_again;
- }
-
- if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY ||
- errno == EAGAIN)) {
- DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port));
- close(res);
- return -1;
- }
-
-#ifdef EISCONN
- if (ret < 0 && errno == EISCONN) {
- errno = 0;
- ret = 0;
- }
-#endif
-
- if (ret < 0) {
- DEBUG(1,("error connecting to %s:%d (%s)\n",
- inet_ntoa(*addr),port,strerror(errno)));
- return -1;
- }
-
- /* set it blocking again */
- set_blocking(res,True);
-
- return res;
-}
-
-
-/****************************************************************************
-interpret a protocol description string, with a default
-****************************************************************************/
-int interpret_protocol(char *str,int def)
-{
- if (strequal(str,"NT1"))
- return(PROTOCOL_NT1);
- if (strequal(str,"LANMAN2"))
- return(PROTOCOL_LANMAN2);
- if (strequal(str,"LANMAN1"))
- return(PROTOCOL_LANMAN1);
- if (strequal(str,"CORE"))
- return(PROTOCOL_CORE);
- if (strequal(str,"COREPLUS"))
- return(PROTOCOL_COREPLUS);
- if (strequal(str,"CORE+"))
- return(PROTOCOL_COREPLUS);
-
- DEBUG(0,("Unrecognised protocol level %s\n",str));
-
- return(def);
-}
-
-/****************************************************************************
-interpret a security level
-****************************************************************************/
-int interpret_security(char *str,int def)
-{
- if (strequal(str,"SERVER"))
- return(SEC_SERVER);
- if (strequal(str,"USER"))
- return(SEC_USER);
- if (strequal(str,"SHARE"))
- return(SEC_SHARE);
-
- DEBUG(0,("Unrecognised security level %s\n",str));
-
- return(def);
-}
-
-
-/****************************************************************************
-interpret an internet address or name into an IP address in 4 byte form
-****************************************************************************/
-uint32 interpret_addr(char *str)
-{
- struct hostent *hp;
- uint32 res;
- int i;
- BOOL pure_address = True;
-
- if (strcmp(str,"0.0.0.0") == 0) return(0);
- if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
-
- for (i=0; pure_address && str[i]; i++)
- if (!(isdigit(str[i]) || str[i] == '.'))
- pure_address = False;
-
- /* if it's in the form of an IP address then get the lib to interpret it */
- if (pure_address) {
- res = inet_addr(str);
- } else {
- /* otherwise assume it's a network name of some sort and use
- Get_Hostbyname */
- if ((hp = Get_Hostbyname(str)) == 0) {
- DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
- return 0;
- }
- if(hp->h_addr == NULL) {
- DEBUG(3,("Get_Hostbyname: host address is invalid for host %s.\n",str));
- return 0;
- }
- putip((char *)&res,(char *)hp->h_addr);
- }
-
- if (res == (uint32)-1) return(0);
-
- return(res);
-}
-
-/*******************************************************************
- a convenient addition to interpret_addr()
- ******************************************************************/
-struct in_addr *interpret_addr2(char *str)
-{
- static struct in_addr ret;
- uint32 a = interpret_addr(str);
- ret.s_addr = a;
- return(&ret);
-}
-
-/*******************************************************************
- check if an IP is the 0.0.0.0
- ******************************************************************/
-BOOL zero_ip(struct in_addr ip)
-{
- uint32 a;
- putip((char *)&a,(char *)&ip);
- return(a == 0);
-}
-
-
-/*******************************************************************
- matchname - determine if host name matches IP address
- ******************************************************************/
-static BOOL matchname(char *remotehost,struct in_addr addr)
-{
- struct hostent *hp;
- int i;
-
- if ((hp = Get_Hostbyname(remotehost)) == 0) {
- DEBUG(0,("Get_Hostbyname(%s): lookup failure", remotehost));
- return False;
- }
-
- /*
- * Make sure that gethostbyname() returns the "correct" host name.
- * Unfortunately, gethostbyname("localhost") sometimes yields
- * "localhost.domain". Since the latter host name comes from the
- * local DNS, we just have to trust it (all bets are off if the local
- * DNS is perverted). We always check the address list, though.
- */
-
- if (strcasecmp(remotehost, hp->h_name)
- && strcasecmp(remotehost, "localhost")) {
- DEBUG(0,("host name/name mismatch: %s != %s",
- remotehost, hp->h_name));
- return False;
- }
-
- /* Look up the host address in the address list we just got. */
- for (i = 0; hp->h_addr_list[i]; i++) {
- if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
- return True;
- }
-
- /*
- * The host name does not map to the original host address. Perhaps
- * someone has compromised a name server. More likely someone botched
- * it, but that could be dangerous, too.
- */
-
- DEBUG(0,("host name/address mismatch: %s != %s",
- inet_ntoa(addr), hp->h_name));
- return False;
-}
-
-/*******************************************************************
- Reset the 'done' variables so after a client process is created
- from a fork call these calls will be re-done. This should be
- expanded if more variables need reseting.
- ******************************************************************/
-
-static BOOL global_client_name_done = False;
-static BOOL global_client_addr_done = False;
-
-void reset_globals_after_fork()
-{
- global_client_name_done = False;
- global_client_addr_done = False;
-}
-
-/*******************************************************************
- return the DNS name of the client
- ******************************************************************/
-char *client_name(void)
-{
- extern int Client;
- struct sockaddr sa;
- struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
- int length = sizeof(sa);
- static pstring name_buf;
- struct hostent *hp;
-
- if (global_client_name_done)
- return name_buf;
-
- strcpy(name_buf,"UNKNOWN");
-
- if (getpeername(Client, &sa, &length) < 0) {
- DEBUG(0,("getpeername failed\n"));
- return name_buf;
- }
-
- /* Look up the remote host name. */
- if ((hp = gethostbyaddr((char *) &sockin->sin_addr,
- sizeof(sockin->sin_addr),
- AF_INET)) == 0) {
- DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr()));
- StrnCpy(name_buf,client_addr(),sizeof(name_buf) - 1);
- } else {
- StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
- if (!matchname(name_buf, sockin->sin_addr)) {
- DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr()));
- strcpy(name_buf,"UNKNOWN");
- }
- }
- global_client_name_done = True;
- return name_buf;
-}
-
-/*******************************************************************
- return the IP addr of the client as a string
- ******************************************************************/
-char *client_addr(void)
-{
- extern int Client;
- struct sockaddr sa;
- struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
- int length = sizeof(sa);
- static fstring addr_buf;
-
- if (global_client_addr_done)
- return addr_buf;
-
- strcpy(addr_buf,"0.0.0.0");
-
- if (getpeername(Client, &sa, &length) < 0) {
- DEBUG(0,("getpeername failed\n"));
- return addr_buf;
- }
-
- fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
-
- global_client_addr_done = True;
- return addr_buf;
-}
-
-/*******************************************************************
-sub strings with useful parameters
-Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
-Paul Rippin <pr3245@nopc.eurostat.cec.be>
-********************************************************************/
-void standard_sub_basic(char *str)
- {
- char *s, *p;
- char pidstr[10];
- struct passwd *pass;
-
- for (s = str ; (p = strchr(s,'%')) != NULL ; s = p )
- {
- switch (*(p+1))
- {
- case 'G' : if ((pass = Get_Pwnam(sesssetup_user,False))!=NULL)
- string_sub(p,"%G",gidtoname(pass->pw_gid));
- else
- p += 2;
- break;
- case 'I' : string_sub(p,"%I",client_addr()); break;
- case 'L' : string_sub(p,"%L",local_machine); break;
- case 'M' : string_sub(p,"%M",client_name()); break;
- case 'R' : string_sub(p,"%R",remote_proto); break;
- case 'T' : string_sub(p,"%T",timestring()); break;
- case 'U' : string_sub(p,"%U",sesssetup_user); break;
- case 'a' : string_sub(p,"%a",remote_arch); break;
- case 'd' : sprintf(pidstr,"%d",(int)getpid());
- string_sub(p,"%d",pidstr);
- break;
- case 'h' : string_sub(p,"%h",myhostname); break;
- case 'm' : string_sub(p,"%m",remote_machine); break;
- case 'v' : string_sub(p,"%v",VERSION); break;
- case '\0' : p++; break; /* don't run off end if last character is % */
- default : p+=2; break;
- }
- }
- return;
-}
-
-/*******************************************************************
-are two IPs on the same subnet?
-********************************************************************/
-BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
-{
- uint32 net1,net2,nmask;
-
- nmask = ntohl(mask.s_addr);
- net1 = ntohl(ip1.s_addr);
- net2 = ntohl(ip2.s_addr);
-
- return((net1 & nmask) == (net2 & nmask));
-}
-
-
-/*******************************************************************
-write a string in unicoode format
-********************************************************************/
-int PutUniCode(char *dst,char *src)
-{
- int ret = 0;
- while (*src) {
- dst[ret++] = src[0];
- dst[ret++] = 0;
- src++;
- }
- dst[ret++]=0;
- dst[ret++]=0;
- return(ret);
-}
-
-/****************************************************************************
-a wrapper for gethostbyname() that tries with all lower and all upper case
-if the initial name fails
-****************************************************************************/
-struct hostent *Get_Hostbyname(char *name)
-{
- char *name2 = strdup(name);
- struct hostent *ret;
-
- if (!name2)
- {
- DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
- exit(0);
- }
-
- if (!isalnum(*name2))
- {
- free(name2);
- return(NULL);
- }
-
- ret = sys_gethostbyname(name2);
- if (ret != NULL)
- {
- free(name2);
- return(ret);
- }
-
- /* try with all lowercase */
- strlower(name2);
- ret = sys_gethostbyname(name2);
- if (ret != NULL)
- {
- free(name2);
- return(ret);
- }
-
- /* try with all uppercase */
- strupper(name2);
- ret = sys_gethostbyname(name2);
- if (ret != NULL)
- {
- free(name2);
- return(ret);
- }
-
- /* nothing works :-( */
- free(name2);
- return(NULL);
-}
-
-
-/****************************************************************************
-check if a process exists. Does this work on all unixes?
-****************************************************************************/
-BOOL process_exists(int pid)
-{
-#ifdef LINUX
- fstring s;
- sprintf(s,"/proc/%d",pid);
- return(directory_exist(s,NULL));
-#else
- {
- static BOOL tested=False;
- static BOOL ok=False;
- fstring s;
- if (!tested) {
- tested = True;
- sprintf(s,"/proc/%05d",(int)getpid());
- ok = file_exist(s,NULL);
- }
- if (ok) {
- sprintf(s,"/proc/%05d",pid);
- return(file_exist(s,NULL));
- }
- }
-
- /* CGH 8/16/96 - added ESRCH test */
- return(pid == getpid() || kill(pid,0) == 0 || errno != ESRCH);
-#endif
-}
-
-
-/*******************************************************************
-turn a uid into a user name
-********************************************************************/
-char *uidtoname(int uid)
-{
- static char name[40];
- struct passwd *pass = getpwuid(uid);
- if (pass) return(pass->pw_name);
- sprintf(name,"%d",uid);
- return(name);
-}
-
-/*******************************************************************
-turn a gid into a group name
-********************************************************************/
-char *gidtoname(int gid)
-{
- static char name[40];
- struct group *grp = getgrgid(gid);
- if (grp) return(grp->gr_name);
- sprintf(name,"%d",gid);
- return(name);
-}
-
-/*******************************************************************
-block sigs
-********************************************************************/
-void BlockSignals(BOOL block,int signum)
-{
-#ifdef USE_SIGBLOCK
- int block_mask = sigmask(signum);
- static int oldmask = 0;
- if (block)
- oldmask = sigblock(block_mask);
- else
- sigsetmask(oldmask);
-#elif defined(USE_SIGPROCMASK)
- sigset_t set;
- sigemptyset(&set);
- sigaddset(&set,signum);
- sigprocmask(block?SIG_BLOCK:SIG_UNBLOCK,&set,NULL);
-#endif
-}
-
-#if AJT
-/*******************************************************************
-my own panic function - not suitable for general use
-********************************************************************/
-void ajt_panic(void)
-{
- system("/usr/bin/X11/xedit -display ljus:0 /tmp/ERROR_FAULT");
-}
-#endif
-
-#ifdef USE_DIRECT
-#define DIRECT direct
-#else
-#define DIRECT dirent
-#endif
-
-/*******************************************************************
-a readdir wrapper which just returns the file name
-also return the inode number if requested
-********************************************************************/
-char *readdirname(void *p)
-{
- struct DIRECT *ptr;
- char *dname;
-
- if (!p) return(NULL);
-
- ptr = (struct DIRECT *)readdir(p);
- if (!ptr) return(NULL);
-
- dname = ptr->d_name;
-
-#ifdef NEXT2
- if (telldir(p) < 0) return(NULL);
-#endif
-
-#ifdef SUNOS5
- /* this handles a broken compiler setup, causing a mixture
- of BSD and SYSV headers and libraries */
- {
- static BOOL broken_readdir = False;
- if (!broken_readdir && !(*(dname)) && strequal("..",dname-2))
- {
- DEBUG(0,("Your readdir() is broken. You have somehow mixed SYSV and BSD headers and libraries\n"));
- broken_readdir = True;
- }
- if (broken_readdir)
- dname = dname - 2;
- }
-#endif
-
- {
- static pstring buf;
- pstrcpy(buf, dname);
- unix_to_dos(buf, True);
- dname = buf;
- }
-
- return(dname);
-}
-
-/*******************************************************************
- Utility function used to decide if the last component
- of a path matches a (possibly wildcarded) entry in a namelist.
-********************************************************************/
-
-BOOL is_in_path(char *name, name_compare_entry *namelist)
-{
- pstring last_component;
- char *p;
-
- DEBUG(8, ("is_in_path: %s\n", name));
-
- /* if we have no list it's obviously not in the path */
- if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
- {
- DEBUG(8,("is_in_path: no name list.\n"));
- return False;
- }
-
- /* Get the last component of the unix name. */
- p = strrchr(name, '/');
- strncpy(last_component, p ? p : name, sizeof(last_component)-1);
- last_component[sizeof(last_component)-1] = '\0';
-
- for(; namelist->name != NULL; namelist++)
- {
- if(namelist->is_wild)
- {
- /* look for a wildcard match. */
- if (mask_match(last_component, namelist->name, case_sensitive, False))
- {
- DEBUG(8,("is_in_path: mask match succeeded\n"));
- return True;
- }
- }
- else
- {
- if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
- (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
- {
- DEBUG(8,("is_in_path: match succeeded\n"));
- return True;
- }
- }
- }
- DEBUG(8,("is_in_path: match not found\n"));
-
- return False;
-}
-
-/*******************************************************************
- Strip a '/' separated list into an array of
- name_compare_enties structures suitable for
- passing to is_in_path(). We do this for
- speed so we can pre-parse all the names in the list
- and don't do it for each call to is_in_path().
- namelist is modified here and is assumed to be
- a copy owned by the caller.
- We also check if the entry contains a wildcard to
- remove a potentially expensive call to mask_match
- if possible.
-********************************************************************/
-
-void set_namearray(name_compare_entry **ppname_array, char *namelist)
-{
- char *name_end;
- char *nameptr = namelist;
- int num_entries = 0;
- int i;
-
- (*ppname_array) = NULL;
-
- if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
- return;
-
- /* We need to make two passes over the string. The
- first to count the number of elements, the second
- to split it.
- */
- while(*nameptr)
- {
- if ( *nameptr == '/' )
- {
- /* cope with multiple (useless) /s) */
- nameptr++;
- continue;
- }
- /* find the next / */
- name_end = strchr(nameptr, '/');
-
- /* oops - the last check for a / didn't find one. */
- if (name_end == NULL)
- break;
-
- /* next segment please */
- nameptr = name_end + 1;
- num_entries++;
- }
-
- if(num_entries == 0)
- return;
-
- if(( (*ppname_array) = (name_compare_entry *)malloc(
- (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
- {
- DEBUG(0,("set_namearray: malloc fail\n"));
- return;
- }
-
- /* Now copy out the names */
- nameptr = namelist;
- i = 0;
- while(*nameptr)
- {
- if ( *nameptr == '/' )
- {
- /* cope with multiple (useless) /s) */
- nameptr++;
- continue;
- }
- /* find the next / */
- if ((name_end = strchr(nameptr, '/')) != NULL)
- {
- *name_end = 0;
- }
-
- /* oops - the last check for a / didn't find one. */
- if(name_end == NULL)
- break;
-
- (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
- (strchr( nameptr, '*')!=NULL));
- if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
- {
- DEBUG(0,("set_namearray: malloc fail (1)\n"));
- return;
- }
-
- /* next segment please */
- nameptr = name_end + 1;
- i++;
- }
-
- (*ppname_array)[i].name = NULL;
-
- return;
-}
-
-/****************************************************************************
-routine to free a namearray.
-****************************************************************************/
-
-void free_namearray(name_compare_entry *name_array)
-{
- if(name_array == 0)
- return;
-
- if(name_array->name != NULL)
- free(name_array->name);
-
- free((char *)name_array);
-}
-
-/****************************************************************************
-routine to do file locking
-****************************************************************************/
-BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type)
-{
-#if HAVE_FCNTL_LOCK
- struct flock lock;
- int ret;
-
-#if 1
- uint32 mask = 0xC0000000;
-
- /* make sure the count is reasonable, we might kill the lockd otherwise */
- count &= ~mask;
-
- /* the offset is often strange - remove 2 of its bits if either of
- the top two bits are set. Shift the top ones by two bits. This
- still allows OLE2 apps to operate, but should stop lockd from
- dieing */
- if ((offset & mask) != 0)
- offset = (offset & ~mask) | ((offset & mask) >> 2);
-#else
- uint32 mask = ((unsigned)1<<31);
-
- /* interpret negative counts as large numbers */
- if (count < 0)
- count &= ~mask;
-
- /* no negative offsets */
- offset &= ~mask;
-
- /* count + offset must be in range */
- while ((offset < 0 || (offset + count < 0)) && mask)
- {
- offset &= ~mask;
- mask = mask >> 1;
- }
-#endif
-
-
- DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type));
-
- lock.l_type = type;
- lock.l_whence = SEEK_SET;
- lock.l_start = (int)offset;
- lock.l_len = (int)count;
- lock.l_pid = 0;
-
- errno = 0;
-
- ret = fcntl(fd,op,&lock);
-
- if (errno != 0)
- DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
-
- /* a lock query */
- if (op == F_GETLK)
- {
- if ((ret != -1) &&
- (lock.l_type != F_UNLCK) &&
- (lock.l_pid != 0) &&
- (lock.l_pid != getpid()))
- {
- DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid));
- return(True);
- }
-
- /* it must be not locked or locked by me */
- return(False);
- }
-
- /* a lock set or unset */
- if (ret == -1)
- {
- DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n",
- offset,count,op,type,strerror(errno)));
-
- /* perhaps it doesn't support this sort of locking?? */
- if (errno == EINVAL)
- {
- DEBUG(3,("locking not supported? returning True\n"));
- return(True);
- }
-
- return(False);
- }
-
- /* everything went OK */
- DEBUG(8,("Lock call successful\n"));
-
- return(True);
-#else
- return(False);
-#endif
-}
-
-/*******************************************************************
-lock a file - returning a open file descriptor or -1 on failure
-The timeout is in seconds. 0 means no timeout
-********************************************************************/
-int file_lock(char *name,int timeout)
-{
- int fd = open(name,O_RDWR|O_CREAT,0666);
- time_t t=0;
- if (fd < 0) return(-1);
-
-#if HAVE_FCNTL_LOCK
- if (timeout) t = time(NULL);
- while (!timeout || (time(NULL)-t < timeout)) {
- if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd);
- msleep(LOCK_RETRY_TIMEOUT);
- }
- return(-1);
-#else
- return(fd);
-#endif
-}
-
-/*******************************************************************
-unlock a file locked by file_lock
-********************************************************************/
-void file_unlock(int fd)
-{
- if (fd<0) return;
-#if HAVE_FCNTL_LOCK
- fcntl_lock(fd,F_SETLK,0,1,F_UNLCK);
-#endif
- close(fd);
-}
-
-/*******************************************************************
-is the name specified one of my netbios names
-returns true is it is equal, false otherwise
-********************************************************************/
-BOOL is_myname(char *s)
-{
- int n;
- BOOL ret = False;
-
- for (n=0; my_netbios_names[n]; n++) {
- if (strequal(my_netbios_names[n], s))
- ret=True;
- }
- DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
- return(ret);
-}
-
-/*******************************************************************
-set the horrid remote_arch string based on an enum.
-********************************************************************/
-void set_remote_arch(enum remote_arch_types type)
-{
- ra_type = type;
- switch( type )
- {
- case RA_WFWG:
- strcpy(remote_arch, "WfWg");
- return;
- case RA_OS2:
- strcpy(remote_arch, "OS2");
- return;
- case RA_WIN95:
- strcpy(remote_arch, "Win95");
- return;
- case RA_WINNT:
- strcpy(remote_arch, "WinNT");
- return;
- case RA_SAMBA:
- strcpy(remote_arch,"Samba");
- return;
- default:
- ra_type = RA_UNKNOWN;
- strcpy(remote_arch, "UNKNOWN");
- break;
- }
-}
-
-/*******************************************************************
- Get the remote_arch type.
-********************************************************************/
-enum remote_arch_types get_remote_arch()
-{
- return ra_type;
-}
-
-
-/*******************************************************************
-skip past some unicode strings in a buffer
-********************************************************************/
-char *skip_unicode_string(char *buf,int n)
-{
- while (n--)
- {
- while (*buf)
- buf += 2;
- buf += 2;
- }
- return(buf);
-}
-
-/*******************************************************************
-Return a ascii version of a unicode string
-Hack alert: uses fixed buffer(s) and only handles ascii strings
-********************************************************************/
-#define MAXUNI 1024
-char *unistr2(uint16 *buf)
-{
- static char lbufs[8][MAXUNI];
- static int nexti;
- char *lbuf = lbufs[nexti];
- char *p;
- nexti = (nexti+1)%8;
- for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf++)
- {
- *p = *buf;
- }
- *p = 0;
- return lbuf;
-}
-
-/*******************************************************************
-Return a ascii version of a unicode string
-Hack alert: uses fixed buffer(s) and only handles ascii strings
-********************************************************************/
-#define MAXUNI 1024
-char *unistr(char *buf)
-{
- static char lbufs[8][MAXUNI];
- static int nexti;
- char *lbuf = lbufs[nexti];
- char *p;
-
- nexti = (nexti+1)%8;
-
- for (p = lbuf; *buf && p-lbuf < MAXUNI-2; p++, buf += 2)
- {
- *p = *buf;
- }
- *p = 0;
- return lbuf;
-}
-
-/*******************************************************************
-strncpy for unicode strings
-********************************************************************/
-int unistrncpy(char *dst, char *src, int len)
-{
- int num_wchars = 0;
-
- while (*src && len > 0)
- {
- *dst++ = *src++;
- *dst++ = *src++;
- len--;
- num_wchars++;
- }
- *dst++ = 0;
- *dst++ = 0;
-
- return num_wchars;
-}
-
-
-/*******************************************************************
-strcpy for unicode strings. returns length (in num of wide chars)
-********************************************************************/
-int unistrcpy(char *dst, char *src)
-{
- int num_wchars = 0;
-
- while (*src)
- {
- *dst++ = *src++;
- *dst++ = *src++;
- num_wchars++;
- }
- *dst++ = 0;
- *dst++ = 0;
-
- return num_wchars;
-}
-
-
-/*******************************************************************
-safe string copy into a fstring
-********************************************************************/
-void fstrcpy(char *dest, char *src)
-{
- int maxlength = sizeof(fstring) - 1;
- if (!dest) {
- DEBUG(0,("ERROR: NULL dest in fstrcpy\n"));
- return;
- }
-
- if (!src) {
- *dest = 0;
- return;
- }
-
- while (maxlength-- && *src)
- *dest++ = *src++;
- *dest = 0;
- if (*src) {
- DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n",
- strlen(src)));
- }
-}
-
-/*******************************************************************
-safe string copy into a pstring
-********************************************************************/
-void pstrcpy(char *dest, char *src)
-{
- int maxlength = sizeof(pstring) - 1;
- if (!dest) {
- DEBUG(0,("ERROR: NULL dest in pstrcpy\n"));
- return;
- }
-
- if (!src) {
- *dest = 0;
- return;
- }
-
- while (maxlength-- && *src)
- *dest++ = *src++;
- *dest = 0;
- if (*src) {
- DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n",
- strlen(src)));
- }
-}
-
-
-/*******************************************************************
-align a pointer to a multiple of 4 bytes
-********************************************************************/
-char *align4(char *q, char *base)
-{
- if ((q - base) & 3)
- {
- q += 4 - ((q - base) & 3);
- }
- return q;
-}
-
-/*******************************************************************
-align a pointer to a multiple of 2 bytes
-********************************************************************/
-char *align2(char *q, char *base)
-{
- if ((q - base) & 1)
- {
- q++;
- }
- return q;
-}
-
-/*******************************************************************
-align a pointer to a multiple of align_offset bytes. looks like it
-will work for offsets of 0, 2 and 4...
-********************************************************************/
-char *align_offset(char *q, char *base, int align_offset_len)
-{
- if (align_offset_len != 0 && ((q - base) & (align_offset_len-1)))
- {
- q += align_offset_len - ((q - base) & (align_offset_len));
- }
- return q;
-}
-
diff --git a/source/libsmb/credentials.c b/source/libsmb/credentials.c
deleted file mode 100644
index 4c81177fb20..00000000000
--- a/source/libsmb/credentials.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- code to manipulate domain credentials
- 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.
-*/
-
-#include "includes.h"
-
-
-/****************************************************************************
- setup the session key.
-Input: 8 byte challenge block
- 8 byte server challenge block
- 16 byte md4 encrypted password
-Output:
- 8 byte session key
-****************************************************************************/
-void cred_session_key(char *challenge, char *srv_challenge, char *pass,
- char *session_key)
-{
- uint32 sum[2];
- char sum2[8];
- char buf[8];
-
- sum[0] = IVAL(challenge, 0) + IVAL(srv_challenge, 0);
- sum[1] = IVAL(challenge, 4) + IVAL(srv_challenge, 4);
-
- SIVAL(sum2,0,sum[0]);
- SIVAL(sum2,4,sum[1]);
-
- E1(pass,sum2,buf);
- E1(pass+9,buf,session_key);
-}
-
-
-/****************************************************************************
-create a credential
-
-Input:
- 8 byte sesssion key
- 8 byte stored credential
- 4 byte timestamp
-
-Output:
- 8 byte credential
-****************************************************************************/
-void cred_create(char *session_key, char *stored_cred, UTIME timestamp,
- char *cred)
-{
- char key2[7];
- char buf[8];
- char timecred[8];
-
- memcpy(timecred, stored_cred, 8);
- SIVAL(timecred, 0, IVAL(stored_cred, 0) + timestamp.time);
-
- E1(session_key, timecred, buf);
- memset(key2, 0, 7);
- key2[0] = session_key[7];
- E1(key2, buf, cred);
-}
-
-
-/****************************************************************************
- check a supplied credential
-
-Input:
- 8 byte received credential
- 8 byte sesssion key
- 8 byte stored credential
- 4 byte timestamp
-
-Output:
- returns 1 if computed credential matches received credential
- returns 0 otherwise
-****************************************************************************/
-int cred_assert(char *cred, char *session_key, char *stored_cred,
- NTTIME timestamp)
-{
- char cred2[8];
-
- cred_create(session_key, stored_cred, timestamp, cred2);
-
- return memcmp(cred, cred2, 8) == 0;
-}
-
diff --git a/source/libsmb/namequery.c b/source/libsmb/namequery.c
deleted file mode 100644
index 55f70be1222..00000000000
--- a/source/libsmb/namequery.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- name query routines
- Copyright (C) Andrew Tridgell 1994-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.
-
-*/
-
-#include "includes.h"
-
-extern pstring scope;
-extern int DEBUGLEVEL;
-
-
-/****************************************************************************
-interpret a node status response
-****************************************************************************/
-static void _interpret_node_status(char *p, char *master,char *rname)
-{
- int numnames = CVAL(p,0);
- DEBUG(1,("received %d names\n",numnames));
-
- if (rname) *rname = 0;
- if (master) *master = 0;
-
- p += 1;
- while (numnames--)
- {
- char qname[17];
- int type;
- fstring flags;
- int i;
- *flags = 0;
- StrnCpy(qname,p,15);
- type = CVAL(p,15);
- p += 16;
-
- strcat(flags, (p[0] & 0x80) ? "<GROUP> " : " ");
- if ((p[0] & 0x60) == 0x00) strcat(flags,"B ");
- if ((p[0] & 0x60) == 0x20) strcat(flags,"P ");
- if ((p[0] & 0x60) == 0x40) strcat(flags,"M ");
- if ((p[0] & 0x60) == 0x60) strcat(flags,"H ");
- if (p[0] & 0x10) strcat(flags,"<DEREGISTERING> ");
- if (p[0] & 0x08) strcat(flags,"<CONFLICT> ");
- if (p[0] & 0x04) strcat(flags,"<ACTIVE> ");
- if (p[0] & 0x02) strcat(flags,"<PERMANENT> ");
-
- if (master && !*master && type == 0x1d) {
- StrnCpy(master,qname,15);
- trim_string(master,NULL," ");
- }
-
- if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) {
- StrnCpy(rname,qname,15);
- trim_string(rname,NULL," ");
- }
-
- for (i = strlen( qname) ; --i >= 0 ; ) {
- if (!isprint(qname[i])) qname[i] = '.';
- }
- DEBUG(1,("\t%-15s <%02x> - %s\n",qname,type,flags));
- p+=2;
- }
- DEBUG(1,("num_good_sends=%d num_good_receives=%d\n",
- IVAL(p,20),IVAL(p,24)));
-}
-
-
-/****************************************************************************
- do a netbios name status query on a host
-
- the "master" parameter is a hack used for finding workgroups.
- **************************************************************************/
-BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
- struct in_addr to_ip,char *master,char *rname,
- void (*fn)())
-{
- BOOL found=False;
- int retries = 2;
- int retry_time = 5000;
- struct timeval tval;
- struct packet_struct p;
- struct packet_struct *p2;
- struct nmb_packet *nmb = &p.packet.nmb;
- static int name_trn_id = 0;
-
- bzero((char *)&p,sizeof(p));
-
- if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) +
- (getpid()%(unsigned)100);
- name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
-
- nmb->header.name_trn_id = name_trn_id;
- nmb->header.opcode = 0;
- nmb->header.response = False;
- nmb->header.nm_flags.bcast = False;
- nmb->header.nm_flags.recursion_available = False;
- nmb->header.nm_flags.recursion_desired = False;
- nmb->header.nm_flags.trunc = False;
- nmb->header.nm_flags.authoritative = False;
- nmb->header.rcode = 0;
- nmb->header.qdcount = 1;
- nmb->header.ancount = 0;
- nmb->header.nscount = 0;
- nmb->header.arcount = 0;
-
- make_nmb_name(&nmb->question.question_name,name,name_type,scope);
-
- nmb->question.question_type = 0x21;
- nmb->question.question_class = 0x1;
-
- p.ip = to_ip;
- p.port = NMB_PORT;
- p.fd = fd;
- p.timestamp = time(NULL);
- p.packet_type = NMB_PACKET;
-
- GetTimeOfDay(&tval);
-
- if (!send_packet(&p))
- return(False);
-
- retries--;
-
- while (1)
- {
- struct timeval tval2;
- GetTimeOfDay(&tval2);
- if (TvalDiff(&tval,&tval2) > retry_time) {
- if (!retries) break;
- if (!found && !send_packet(&p))
- return False;
- GetTimeOfDay(&tval);
- retries--;
- }
-
- if ((p2=receive_packet(fd,NMB_PACKET,90)))
- {
- struct nmb_packet *nmb2 = &p2->packet.nmb;
- debug_nmb_packet(p2);
-
- if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
- !nmb2->header.response) {
- /* its not for us - maybe deal with it later */
- if (fn)
- fn(p2);
- else
- free_packet(p2);
- continue;
- }
-
- if (nmb2->header.opcode != 0 ||
- nmb2->header.nm_flags.bcast ||
- nmb2->header.rcode ||
- !nmb2->header.ancount ||
- nmb2->answers->rr_type != 0x21) {
- /* XXXX what do we do with this? could be a redirect, but
- we'll discard it for the moment */
- free_packet(p2);
- continue;
- }
-
- _interpret_node_status(&nmb2->answers->rdata[0], master,rname);
- free_packet(p2);
- return(True);
- }
- }
-
-
- DEBUG(0,("No status response (this is not unusual)\n"));
-
- return(False);
-}
-
-
-/****************************************************************************
- do a netbios name query to find someones IP
- ****************************************************************************/
-BOOL name_query(int fd,char *name,int name_type,
- BOOL bcast,BOOL recurse,
- struct in_addr to_ip, struct in_addr *ip,void (*fn)())
-{
- BOOL found=False;
- int retries = 3;
- int retry_time = bcast?250:2000;
- struct timeval tval;
- struct packet_struct p;
- struct packet_struct *p2;
- struct nmb_packet *nmb = &p.packet.nmb;
- static int name_trn_id = 0;
-
- bzero((char *)&p,sizeof(p));
-
- if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) +
- (getpid()%(unsigned)100);
- name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
-
- nmb->header.name_trn_id = name_trn_id;
- nmb->header.opcode = 0;
- nmb->header.response = False;
- nmb->header.nm_flags.bcast = bcast;
- nmb->header.nm_flags.recursion_available = False;
- nmb->header.nm_flags.recursion_desired = True;
- nmb->header.nm_flags.trunc = False;
- nmb->header.nm_flags.authoritative = False;
- nmb->header.rcode = 0;
- nmb->header.qdcount = 1;
- nmb->header.ancount = 0;
- nmb->header.nscount = 0;
- nmb->header.arcount = 0;
-
- make_nmb_name(&nmb->question.question_name,name,name_type,scope);
-
- nmb->question.question_type = 0x20;
- nmb->question.question_class = 0x1;
-
- p.ip = to_ip;
- p.port = NMB_PORT;
- p.fd = fd;
- p.timestamp = time(NULL);
- p.packet_type = NMB_PACKET;
-
- GetTimeOfDay(&tval);
-
- if (!send_packet(&p))
- return(False);
-
- retries--;
-
- while (1)
- {
- struct timeval tval2;
- GetTimeOfDay(&tval2);
- if (TvalDiff(&tval,&tval2) > retry_time) {
- if (!retries) break;
- if (!found && !send_packet(&p))
- return False;
- GetTimeOfDay(&tval);
- retries--;
- }
-
- if ((p2=receive_packet(fd,NMB_PACKET,90)))
- {
- struct nmb_packet *nmb2 = &p2->packet.nmb;
- debug_nmb_packet(p2);
-
- if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
- !nmb2->header.response) {
- /* its not for us - maybe deal with it later
- (put it on the queue?) */
- if (fn)
- fn(p2);
- else
- free_packet(p2);
- continue;
- }
-
- if (nmb2->header.opcode != 0 ||
- nmb2->header.nm_flags.bcast ||
- nmb2->header.rcode ||
- !nmb2->header.ancount) {
- /* XXXX what do we do with this? could be a redirect, but
- we'll discard it for the moment */
- free_packet(p2);
- continue;
- }
-
- if (ip) {
- putip((char *)ip,&nmb2->answers->rdata[2]);
- DEBUG(fn?3:2,("Got a positive name query response from %s",
- inet_ntoa(p2->ip)));
- DEBUG(fn?3:2,(" (%s)\n",inet_ntoa(*ip)));
- }
- found=True; retries=0;
- free_packet(p2);
- if (fn) break;
- }
- }
-
- return(found);
-}
diff --git a/source/libsmb/nmblib.c b/source/libsmb/nmblib.c
deleted file mode 100644
index 48f988de2a2..00000000000
--- a/source/libsmb/nmblib.c
+++ /dev/null
@@ -1,731 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios library routines
- Copyright (C) Andrew Tridgell 1994-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.
-
-*/
-
-#include "includes.h"
-
-extern int DEBUGLEVEL;
-
-int num_good_sends = 0;
-int num_good_receives = 0;
-extern pstring scope;
-extern pstring myname;
-extern struct in_addr ipzero;
-
-static struct opcode_names {
- char *nmb_opcode_name;
- int opcode;
-} nmb_header_opcode_names[] = {
- { "Query", 0 },
- {"Registration", 5 },
- {"Release", 6 },
- {"WACK", 7 },
- {"refresh", 8 },
- {0, -1 }
-};
-
-/****************************************************************************
- * Lookup a nmb opcode name.
- ****************************************************************************/
-
-char *lookup_opcode_name( int opcode )
-{
- struct opcode_names *op_namep;
- int i;
-
- for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) {
- op_namep = &nmb_header_opcode_names[i];
- if(opcode == op_namep->opcode)
- return op_namep->nmb_opcode_name;
- }
- return "<unknown opcode>";
-}
-
-/****************************************************************************
- print out a res_rec structure
- ****************************************************************************/
-static void debug_nmb_res_rec(struct res_rec *res, char *hdr)
-{
- int i, j;
-
- DEBUG(4,(" %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n",
- hdr,
- namestr(&res->rr_name),
- res->rr_type,
- res->rr_class,
- res->ttl));
-
- if (res->rdlength == 0 || res->rdata == NULL) return;
-
- for (i = 0; i < res->rdlength; i+= 16)
- {
- DEBUG(4, (" %s %3x char ", hdr, i));
-
- for (j = 0; j < 16; j++)
- {
- unsigned char x = res->rdata[i+j];
- if (x < 32 || x > 127) x = '.';
-
- if (i+j >= res->rdlength) break;
- DEBUG(4, ("%c", x));
- }
-
- DEBUG(4, (" hex ", i));
-
- for (j = 0; j < 16; j++)
- {
- if (i+j >= res->rdlength) break;
- DEBUG(4, ("%02X", (unsigned char)res->rdata[i+j]));
- }
-
- DEBUG(4, ("\n"));
- }
-}
-
-/****************************************************************************
- process a nmb packet
- ****************************************************************************/
-void debug_nmb_packet(struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
-
- DEBUG(4,("nmb packet from %s header: id=%d opcode=%s(%d) response=%s\n",
- inet_ntoa(p->ip),
- nmb->header.name_trn_id,
- lookup_opcode_name(nmb->header.opcode),
- nmb->header.opcode,BOOLSTR(nmb->header.response)));
- DEBUG(4,(" header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n",
- BOOLSTR(nmb->header.nm_flags.bcast),
- BOOLSTR(nmb->header.nm_flags.recursion_available),
- BOOLSTR(nmb->header.nm_flags.recursion_desired),
- BOOLSTR(nmb->header.nm_flags.trunc),
- BOOLSTR(nmb->header.nm_flags.authoritative)));
- DEBUG(4,(" header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n",
- nmb->header.rcode,
- nmb->header.qdcount,
- nmb->header.ancount,
- nmb->header.nscount,
- nmb->header.arcount));
-
- if (nmb->header.qdcount)
- {
- DEBUG(4,(" question: q_name=%s q_type=%d q_class=%d\n",
- namestr(&nmb->question.question_name),
- nmb->question.question_type,
- nmb->question.question_class));
- }
-
- if (nmb->answers && nmb->header.ancount)
- {
- debug_nmb_res_rec(nmb->answers,"answers");
- }
- if (nmb->nsrecs && nmb->header.nscount)
- {
- debug_nmb_res_rec(nmb->nsrecs,"nsrecs");
- }
- if (nmb->additional && nmb->header.arcount)
- {
- debug_nmb_res_rec(nmb->additional,"additional");
- }
-}
-
-/*******************************************************************
- handle "compressed" name pointers
- ******************************************************************/
-static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length,
- BOOL *got_pointer,int *ret)
-{
- int loop_count=0;
-
- while ((ubuf[*offset] & 0xC0) == 0xC0) {
- if (!*got_pointer) (*ret) += 2;
- (*got_pointer)=True;
- (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1];
- if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) {
- return(False);
- }
- }
- return(True);
-}
-
-/*******************************************************************
- parse a nmb name from "compressed" format to something readable
- return the space taken by the name, or 0 if the name is invalid
- ******************************************************************/
-static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *name)
-{
- int m,n=0;
- unsigned char *ubuf = (unsigned char *)inbuf;
- int ret = 0;
- BOOL got_pointer=False;
-
- if (length - offset < 2) return(0);
-
- /* handle initial name pointers */
- if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
-
- m = ubuf[offset];
-
- if (!m) return(0);
- if ((m & 0xC0) || offset+m+2 > length) return(0);
-
- bzero((char *)name,sizeof(*name));
-
- /* the "compressed" part */
- if (!got_pointer) ret += m + 2;
- offset++;
- while (m) {
- unsigned char c1,c2;
- c1 = ubuf[offset++]-'A';
- c2 = ubuf[offset++]-'A';
- if ((c1 & 0xF0) || (c2 & 0xF0)) return(0);
- name->name[n++] = (c1<<4) | c2;
- m -= 2;
- }
- name->name[n] = 0;
-
- if (n==16) {
- /* parse out the name type,
- its always in the 16th byte of the name */
- name->name_type = name->name[15];
-
- /* remove trailing spaces */
- name->name[15] = 0;
- n = 14;
- while (n && name->name[n]==' ') name->name[n--] = 0;
- }
-
- /* now the domain parts (if any) */
- n = 0;
- while ((m=ubuf[offset])) {
- /* we can have pointers within the domain part as well */
- if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
-
- if (!got_pointer) ret += m+1;
- if (n) name->scope[n++] = '.';
- if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0);
- offset++;
- while (m--) name->scope[n++] = (char)ubuf[offset++];
- }
- name->scope[n++] = 0;
-
- return(ret);
-}
-
-
-/*******************************************************************
- put a compressed nmb name into a buffer. return the length of the
- compressed name
-
- compressed names are really weird. The "compression" doubles the
- size. The idea is that it also means that compressed names conform
- to the doman name system. See RFC1002.
- ******************************************************************/
-static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
-{
- int ret,m;
- fstring buf1;
- char *p;
-
- if (name->name[0] == '*') {
- /* special case for wildcard name */
- bzero(buf1,20);
- buf1[0] = '*';
- } else {
- sprintf(buf1,"%-15.15s%c",name->name,name->name_type);
- }
-
- buf[offset] = 0x20;
-
- ret = 34;
-
- for (m=0;m<16;m++) {
- buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF);
- buf[offset+2+2*m] = 'A' + (buf1[m]&0xF);
- }
- offset += 33;
-
- buf[offset] = 0;
-
- if (name->scope[0]) {
- /* XXXX this scope handling needs testing */
- ret += strlen(name->scope) + 1;
- strcpy(&buf[offset+1],name->scope);
-
- p = &buf[offset+1];
- while ((p = strchr(p,'.'))) {
- buf[offset] = PTR_DIFF(p,&buf[offset]);
- offset += buf[offset];
- p = &buf[offset+1];
- }
- buf[offset] = strlen(&buf[offset+1]);
- }
-
- return(ret);
-}
-
-/*******************************************************************
- useful for debugging messages
- ******************************************************************/
-char *namestr(struct nmb_name *n)
-{
- static int i=0;
- static fstring ret[4];
- char *p = ret[i];
-
- if (!n->scope[0])
- sprintf(p,"%s(%x)",n->name,n->name_type);
- else
- sprintf(p,"%s(%x).%s",n->name,n->name_type,n->scope);
-
- i = (i+1)%4;
- return(p);
-}
-
-/*******************************************************************
- allocate and parse some resource records
- ******************************************************************/
-static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
- struct res_rec **recs, int count)
-{
- int i;
- *recs = (struct res_rec *)malloc(sizeof(**recs)*count);
- if (!*recs) return(False);
-
- bzero(*recs,sizeof(**recs)*count);
-
- for (i=0;i<count;i++) {
- int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
- (*offset) += l;
- if (!l || (*offset)+10 > length) {
- free(*recs);
- return(False);
- }
- (*recs)[i].rr_type = RSVAL(inbuf,(*offset));
- (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2);
- (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4);
- (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8);
- (*offset) += 10;
- if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
- (*offset)+(*recs)[i].rdlength > length) {
- free(*recs);
- return(False);
- }
- memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
- (*offset) += (*recs)[i].rdlength;
- }
- return(True);
-}
-
-/*******************************************************************
- put a resource record into a packet
- ******************************************************************/
-static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count)
-{
- int ret=0;
- int i;
-
- for (i=0;i<count;i++) {
- int l = put_nmb_name(buf,offset,&recs[i].rr_name);
- offset += l;
- ret += l;
- RSSVAL(buf,offset,recs[i].rr_type);
- RSSVAL(buf,offset+2,recs[i].rr_class);
- RSIVAL(buf,offset+4,recs[i].ttl);
- RSSVAL(buf,offset+8,recs[i].rdlength);
- memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength);
- offset += 10+recs[i].rdlength;
- ret += 10+recs[i].rdlength;
- }
-
- return(ret);
-}
-
-/*******************************************************************
- parse a dgram packet. Return False if the packet can't be parsed
- or is invalid for some reason, True otherwise
-
- this is documented in section 4.4.1 of RFC1002
- ******************************************************************/
-static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
-{
- int offset;
- int flags;
-
- bzero((char *)dgram,sizeof(*dgram));
-
- if (length < 14) return(False);
-
- dgram->header.msg_type = CVAL(inbuf,0);
- flags = CVAL(inbuf,1);
- dgram->header.flags.node_type = (enum node_type)((flags>>2)&3);
- if (flags & 1) dgram->header.flags.more = True;
- if (flags & 2) dgram->header.flags.first = True;
- dgram->header.dgm_id = RSVAL(inbuf,2);
- putip((char *)&dgram->header.source_ip,inbuf+4);
- dgram->header.source_port = RSVAL(inbuf,8);
- dgram->header.dgm_length = RSVAL(inbuf,10);
- dgram->header.packet_offset = RSVAL(inbuf,12);
-
- offset = 14;
-
- if (dgram->header.msg_type == 0x10 ||
- dgram->header.msg_type == 0x11 ||
- dgram->header.msg_type == 0x12) {
- offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name);
- offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name);
- }
-
- if (offset >= length || (length-offset > sizeof(dgram->data)))
- return(False);
-
- dgram->datasize = length-offset;
- memcpy(dgram->data,inbuf+offset,dgram->datasize);
-
- return(True);
-}
-
-
-/*******************************************************************
- parse a nmb packet. Return False if the packet can't be parsed
- or is invalid for some reason, True otherwise
- ******************************************************************/
-static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
-{
- int nm_flags,offset;
-
- bzero((char *)nmb,sizeof(*nmb));
-
- if (length < 12) return(False);
-
- /* parse the header */
- nmb->header.name_trn_id = RSVAL(inbuf,0);
-
- DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id));
-
- nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF;
- nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False;
- nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4);
- nmb->header.nm_flags.bcast = (nm_flags&1)?True:False;
- nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False;
- nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False;
- nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False;
- nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False;
- nmb->header.rcode = CVAL(inbuf,3) & 0xF;
- nmb->header.qdcount = RSVAL(inbuf,4);
- nmb->header.ancount = RSVAL(inbuf,6);
- nmb->header.nscount = RSVAL(inbuf,8);
- nmb->header.arcount = RSVAL(inbuf,10);
-
- if (nmb->header.qdcount) {
- offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name);
- if (!offset) return(False);
-
- if (length - (12+offset) < 4) return(False);
- nmb->question.question_type = RSVAL(inbuf,12+offset);
- nmb->question.question_class = RSVAL(inbuf,12+offset+2);
-
- offset += 12+4;
- } else {
- offset = 12;
- }
-
- /* and any resource records */
- if (nmb->header.ancount &&
- !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers,
- nmb->header.ancount))
- return(False);
-
- if (nmb->header.nscount &&
- !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs,
- nmb->header.nscount))
- return(False);
-
- if (nmb->header.arcount &&
- !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional,
- nmb->header.arcount))
- return(False);
-
- return(True);
-}
-
-/*******************************************************************
- free up any resources associated with an nmb packet
- ******************************************************************/
-void free_nmb_packet(struct nmb_packet *nmb)
-{
- if (nmb->answers) free(nmb->answers);
- if (nmb->nsrecs) free(nmb->nsrecs);
- if (nmb->additional) free(nmb->additional);
-}
-
-/*******************************************************************
- free up any resources associated with a packet
- ******************************************************************/
-void free_packet(struct packet_struct *packet)
-{
- if (packet->packet_type == NMB_PACKET)
- free_nmb_packet(&packet->packet.nmb);
- free(packet);
-}
-
-/*******************************************************************
- read a packet from a socket and parse it, returning a packet ready
- to be used or put on the queue. This assumes a UDP socket
- ******************************************************************/
-struct packet_struct *read_packet(int fd,enum packet_type packet_type)
-{
- extern struct in_addr lastip;
- extern int lastport;
- struct packet_struct *packet;
- char buf[MAX_DGRAM_SIZE];
- int length;
- BOOL ok=False;
-
- length = read_udp_socket(fd,buf,sizeof(buf));
- if (length < MIN_DGRAM_SIZE) return(NULL);
-
- packet = (struct packet_struct *)malloc(sizeof(*packet));
- if (!packet) return(NULL);
-
- packet->next = NULL;
- packet->prev = NULL;
- packet->ip = lastip;
- packet->port = lastport;
- packet->fd = fd;
- packet->timestamp = time(NULL);
- packet->packet_type = packet_type;
- switch (packet_type)
- {
- case NMB_PACKET:
- ok = parse_nmb(buf,length,&packet->packet.nmb);
- break;
-
- case DGRAM_PACKET:
- ok = parse_dgram(buf,length,&packet->packet.dgram);
- break;
- }
- if (!ok) {
- DEBUG(10,("parse_nmb: discarding packet id = %d\n",
- packet->packet.nmb.header.name_trn_id));
- free(packet);
- return(NULL);
- }
-
- num_good_receives++;
-
- DEBUG(5,("%s received a packet of len %d from (%s) port %d\n",
- timestring(),length,inet_ntoa(packet->ip),packet->port));
-
- return(packet);
-}
-
-
-/*******************************************************************
- send a udp packet on a already open socket
- ******************************************************************/
-static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
-{
- BOOL ret;
- struct sockaddr_in sock_out;
-
- /* set the address and port */
- bzero((char *)&sock_out,sizeof(sock_out));
- putip((char *)&sock_out.sin_addr,(char *)&ip);
- sock_out.sin_port = htons( port );
- sock_out.sin_family = AF_INET;
-
- DEBUG(5,("%s sending a packet of len %d to (%s) on port %d\n",
- timestring(),len,inet_ntoa(ip),port));
-
- ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out,
- sizeof(sock_out)) >= 0);
-
- if (!ret)
- DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n",
- inet_ntoa(ip),port,strerror(errno)));
-
- if (ret)
- num_good_sends++;
-
- return(ret);
-}
-
-/*******************************************************************
- build a dgram packet ready for sending
-
- XXXX This currently doesn't handle packets too big for one
- datagram. It should split them and use the packet_offset, more and
- first flags to handle the fragmentation. Yuck.
- ******************************************************************/
-static int build_dgram(char *buf,struct packet_struct *p)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- unsigned char *ubuf = (unsigned char *)buf;
- int offset=0;
-
- /* put in the header */
- ubuf[0] = dgram->header.msg_type;
- ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
- if (dgram->header.flags.more) ubuf[1] |= 1;
- if (dgram->header.flags.first) ubuf[1] |= 2;
- RSSVAL(ubuf,2,dgram->header.dgm_id);
- putip(ubuf+4,(char *)&dgram->header.source_ip);
- RSSVAL(ubuf,8,dgram->header.source_port);
- RSSVAL(ubuf,12,dgram->header.packet_offset);
-
- offset = 14;
-
- if (dgram->header.msg_type == 0x10 ||
- dgram->header.msg_type == 0x11 ||
- dgram->header.msg_type == 0x12) {
- offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name);
- offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name);
- }
-
- memcpy(ubuf+offset,dgram->data,dgram->datasize);
- offset += dgram->datasize;
-
- /* automatically set the dgm_length */
- dgram->header.dgm_length = offset;
- RSSVAL(ubuf,10,dgram->header.dgm_length);
-
- return(offset);
-}
-
-/*******************************************************************
- build a nmb name
- ******************************************************************/
-void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope)
-{
- fstrcpy(n->name,name);
- strupper(n->name);
- n->name_type = type;
- fstrcpy(n->scope,this_scope);
-}
-
-
-/*******************************************************************
- build a nmb packet ready for sending
-
- XXXX this currently relies on not being passed something that expands
- to a packet too big for the buffer. Eventually this should be
- changed to set the trunc bit so the receiver can request the rest
- via tcp (when that becomes supported)
- ******************************************************************/
-static int build_nmb(char *buf,struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- unsigned char *ubuf = (unsigned char *)buf;
- int offset=0;
-
- /* put in the header */
- RSSVAL(ubuf,offset,nmb->header.name_trn_id);
- ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3;
- if (nmb->header.response) ubuf[offset+2] |= (1<<7);
- if (nmb->header.nm_flags.authoritative &&
- nmb->header.response) ubuf[offset+2] |= 0x4;
- if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2;
- if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1;
- if (nmb->header.nm_flags.recursion_available &&
- nmb->header.response) ubuf[offset+3] |= 0x80;
- if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10;
- ubuf[offset+3] |= (nmb->header.rcode & 0xF);
-
- RSSVAL(ubuf,offset+4,nmb->header.qdcount);
- RSSVAL(ubuf,offset+6,nmb->header.ancount);
- RSSVAL(ubuf,offset+8,nmb->header.nscount);
- RSSVAL(ubuf,offset+10,nmb->header.arcount);
-
- offset += 12;
- if (nmb->header.qdcount) {
- /* XXXX this doesn't handle a qdcount of > 1 */
- offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name);
- RSSVAL(ubuf,offset,nmb->question.question_type);
- RSSVAL(ubuf,offset+2,nmb->question.question_class);
- offset += 4;
- }
-
- if (nmb->header.ancount)
- offset += put_res_rec((char *)ubuf,offset,nmb->answers,
- nmb->header.ancount);
-
- if (nmb->header.nscount)
- offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs,
- nmb->header.nscount);
-
- if (nmb->header.arcount)
- offset += put_res_rec((char *)ubuf,offset,nmb->additional,
- nmb->header.arcount);
-
- return(offset);
-}
-
-
-/*******************************************************************
- send a packet_struct
- ******************************************************************/
-BOOL send_packet(struct packet_struct *p)
-{
- char buf[1024];
- int len=0;
-
- bzero(buf,sizeof(buf));
-
- switch (p->packet_type)
- {
- case NMB_PACKET:
- len = build_nmb(buf,p);
- break;
-
- case DGRAM_PACKET:
- len = build_dgram(buf,p);
- break;
- }
-
- if (!len) return(False);
-
- return(send_udp(p->fd,buf,len,p->ip,p->port));
-}
-
-/****************************************************************************
- receive a packet with timeout on a open UDP filedescriptor
- The timeout is in milliseconds
- ***************************************************************************/
-struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
-{
- fd_set fds;
- struct timeval timeout;
-
- FD_ZERO(&fds);
- FD_SET(fd,&fds);
- timeout.tv_sec = t/1000;
- timeout.tv_usec = 1000*(t%1000);
-
- sys_select(&fds,&timeout);
-
- if (FD_ISSET(fd,&fds))
- return(read_packet(fd,type));
-
- return(NULL);
-}
-
-
diff --git a/source/libsmb/smbdes.c b/source/libsmb/smbdes.c
deleted file mode 100644
index 1c38612b739..00000000000
--- a/source/libsmb/smbdes.c
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
-
- a partial implementation of DES designed for use in the
- SMB authentication protocol
-
- Copyright (C) Andrew Tridgell 1997
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-
-/* NOTES:
-
- This code makes no attempt to be fast! In fact, it is a very
- slow implementation
-
- This code is NOT a complete DES implementation. It implements only
- the minimum necessary for SMB authentication, as used by all SMB
- products (including every copy of Microsoft Windows95 ever sold)
-
- In particular, it can only do a unchained forward DES pass. This
- means it is not possible to use this code for encryption/decryption
- of data, instead it is only useful as a "hash" algorithm.
-
- There is no entry point into this code that allows normal DES operation.
-
- I believe this means that this code does not come under ITAR
- regulations but this is NOT a legal opinion. If you are concerned
- about the applicability of ITAR regulations to this code then you
- should confirm it for yourself (and maybe let me know if you come
- up with a different answer to the one above)
-*/
-
-
-
-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);
-}
-
-
diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c
deleted file mode 100644
index 27172fd4136..00000000000
--- a/source/libsmb/smbencrypt.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- SMB parameters and setup
- Copyright (C) Andrew Tridgell 1992-1997
- Modified by Jeremy Allison 1995.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-extern int DEBUGLEVEL;
-
-#include "byteorder.h"
-
-/*
- 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(uchar *passwd, uchar *c8, uchar *p24)
-{
- uchar 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 *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 *dst, uchar *src, int len)
-{
- int i;
- int16 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(uchar *passwd, uchar *p16)
-{
- int len;
- int16 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);
-
- mdfour(p16, (unsigned char *)wpwd, len);
-}
-
-/* Does the NT MD4 hash then des encryption. */
-
-void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
-{
- uchar p21[21];
-
- memset(p21,'\0',21);
-
- E_md4hash(passwd, p21);
- E_P24(p21, c8, p24);
-}
-
diff --git a/source/locking/locking.c b/source/locking/locking.c
deleted file mode 100644
index 639bc7be0ba..00000000000
--- a/source/locking/locking.c
+++ /dev/null
@@ -1,1535 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Locking functions
- Copyright (C) Andrew Tridgell 1992-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.
-
- Revision History:
-
- 12 aug 96: Erik.Devriendt@te6.siemens.be
- added support for shared memory implementation of share mode locking
-
- May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
- locking to deal with multiple share modes per open file.
-
- September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
- support.
-
-*/
-
-#include "includes.h"
-extern int DEBUGLEVEL;
-extern connection_struct Connections[];
-extern files_struct Files[];
-
-/****************************************************************************
- utility function called to see if a file region is locked
-****************************************************************************/
-BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset)
-{
- int snum = SNUM(cnum);
-
- if (count == 0)
- return(False);
-
- if (!lp_locking(snum) || !lp_strict_locking(snum))
- return(False);
-
- return(fcntl_lock(Files[fnum].fd_ptr->fd,F_GETLK,offset,count,
- (Files[fnum].can_write?F_WRLCK:F_RDLCK)));
-}
-
-
-/****************************************************************************
- utility function called by locking requests
-****************************************************************************/
-BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode)
-{
- BOOL ok = False;
-
- if (!lp_locking(SNUM(cnum)))
- return(True);
-
- if (count == 0) {
- *eclass = ERRDOS;
- *ecode = ERRnoaccess;
- return False;
- }
-
- if (Files[fnum].can_lock && OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
- ok = fcntl_lock(Files[fnum].fd_ptr->fd,F_SETLK,offset,count,
- (Files[fnum].can_write?F_WRLCK:F_RDLCK));
-
- if (!ok) {
- *eclass = ERRDOS;
- *ecode = ERRlock;
- return False;
- }
- return True; /* Got lock */
-}
-
-
-/****************************************************************************
- utility function called by unlocking requests
-****************************************************************************/
-BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode)
-{
- BOOL ok = False;
-
- if (!lp_locking(SNUM(cnum)))
- return(True);
-
- if (Files[fnum].can_lock && OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
- ok = fcntl_lock(Files[fnum].fd_ptr->fd,F_SETLK,offset,count,F_UNLCK);
-
- if (!ok) {
- *eclass = ERRDOS;
- *ecode = ERRlock;
- return False;
- }
- return True; /* Did unlock */
-}
-
-#ifdef FAST_SHARE_MODES
-/*******************************************************************
- initialize the shared memory for share_mode management
- ******************************************************************/
-BOOL start_share_mode_mgmt(void)
-{
- pstring shmem_file_name;
-
- pstrcpy(shmem_file_name,lp_lockdir());
- if (!directory_exist(shmem_file_name,NULL))
- mkdir(shmem_file_name,0755);
- trim_string(shmem_file_name,"","/");
- if (!*shmem_file_name) return(False);
- strcat(shmem_file_name, "/SHARE_MEM_FILE");
- return smb_shm_open(shmem_file_name, lp_shmem_size());
-}
-
-
-/*******************************************************************
- deinitialize the shared memory for share_mode management
- ******************************************************************/
-BOOL stop_share_mode_mgmt(void)
-{
- return smb_shm_close();
-}
-
-/*******************************************************************
- lock a hash bucket entry in shared memory for share_mode management
- ******************************************************************/
-BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok)
-{
- return smb_shm_lock_hash_entry(HASH_ENTRY(dev, inode));
-}
-
-/*******************************************************************
- unlock a hash bucket entry in shared memory for share_mode management
- ******************************************************************/
-BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token token)
-{
- return smb_shm_unlock_hash_entry(HASH_ENTRY(dev, inode));
-}
-
-/*******************************************************************
-get all share mode entries in shared memory for a dev/inode pair.
-********************************************************************/
-int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode,
- min_share_mode_entry **old_shares)
-{
- smb_shm_offset_t *mode_array;
- unsigned int hash_entry = HASH_ENTRY(dev, inode);
- share_mode_record *file_scanner_p;
- share_mode_record *file_prev_p;
- share_mode_entry *entry_scanner_p;
- share_mode_entry *entry_prev_p;
- int num_entries;
- int num_entries_copied;
- BOOL found = False;
- min_share_mode_entry *share_array = (min_share_mode_entry *)0;
-
- *old_shares = 0;
-
- if(hash_entry > lp_shmem_hash_size() )
- {
- DEBUG(0,
- ("PANIC ERROR : get_share_modes (FAST_SHARE_MODES): hash_entry %d too large \
-(max = %d)\n",
- hash_entry, lp_shmem_hash_size() ));
- return 0;
- }
-
- mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off());
-
- if(mode_array[hash_entry] == NULL_OFFSET)
- {
- DEBUG(5,("get_share_modes (FAST_SHARE_MODES): hash bucket %d empty\n", hash_entry));
- return 0;
- }
-
- file_scanner_p = (share_mode_record *)smb_shm_offset2addr(mode_array[hash_entry]);
- file_prev_p = file_scanner_p;
- while(file_scanner_p)
- {
- if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
- {
- found = True;
- break;
- }
- else
- {
- file_prev_p = file_scanner_p ;
- file_scanner_p = (share_mode_record *)smb_shm_offset2addr(
- file_scanner_p->next_offset);
- }
- }
-
- if(!found)
- {
- DEBUG(5,("get_share_modes (FAST_SHARE_MODES): no entry for \
-file dev = %d, ino = %d in hash_bucket %d\n", dev, inode, hash_entry));
- return (0);
- }
-
- if(file_scanner_p->locking_version != LOCKING_VERSION)
- {
- DEBUG(0,("ERROR:get_share_modes (FAST_SHARE_MODES): Deleting old share mode \
-record due to old locking version %d for file dev = %d, inode = %d in hash \
-bucket %d\n", file_scanner_p->locking_version, dev, inode, hash_entry));
- if(file_prev_p == file_scanner_p)
- mode_array[hash_entry] = file_scanner_p->next_offset;
- else
- file_prev_p->next_offset = file_scanner_p->next_offset;
- smb_shm_free(smb_shm_addr2offset(file_scanner_p));
- return (0);
- }
-
- /* Allocate the old_shares array */
- num_entries = file_scanner_p->num_share_mode_entries;
- if(num_entries)
- {
- *old_shares = share_array = (min_share_mode_entry *)
- malloc(num_entries * sizeof(min_share_mode_entry));
- if(*old_shares == 0)
- {
- DEBUG(0,("get_share_modes (FAST_SHARE_MODES): malloc fail !\n"));
- return 0;
- }
- }
-
- num_entries_copied = 0;
-
- entry_scanner_p = (share_mode_entry*)smb_shm_offset2addr(
- file_scanner_p->share_mode_entries);
- entry_prev_p = entry_scanner_p;
- while(entry_scanner_p)
- {
- int pid = entry_scanner_p->pid;
-
- if (pid && !process_exists(pid))
- {
- /* Delete this share mode entry */
- share_mode_entry *delete_entry_p = entry_scanner_p;
- int share_mode = entry_scanner_p->share_mode;
-
- if(entry_prev_p == entry_scanner_p)
- {
- /* We are at start of list */
- file_scanner_p->share_mode_entries = entry_scanner_p->next_share_mode_entry;
- entry_scanner_p = (share_mode_entry*)smb_shm_offset2addr(
- file_scanner_p->share_mode_entries);
- entry_prev_p = entry_scanner_p;
- }
- else
- {
- entry_prev_p->next_share_mode_entry = entry_scanner_p->next_share_mode_entry;
- entry_scanner_p = (share_mode_entry*)
- smb_shm_offset2addr(entry_scanner_p->next_share_mode_entry);
- }
- /* Decrement the number of share mode entries on this share mode record */
- file_scanner_p->num_share_mode_entries -= 1;
-
- /* PARANOIA TEST */
- if(file_scanner_p->num_share_mode_entries < 0)
- {
- DEBUG(0,("PANIC ERROR:get_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \
-for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries,
- dev, inode, hash_entry));
- return 0;
- }
-
- DEBUG(0,("get_share_modes (FAST_SHARE_MODES): process %d no longer exists and \
-it left a share mode entry with mode 0x%X for file dev = %d, ino = %d in hash \
-bucket %d (number of entries now = %d)\n",
- pid, share_mode, dev, inode, hash_entry,
- file_scanner_p->num_share_mode_entries));
-
- smb_shm_free(smb_shm_addr2offset(delete_entry_p));
- }
- else
- {
- /* This is a valid share mode entry and the process that
- created it still exists. Copy it into the output array.
- */
- share_array[num_entries_copied].pid = entry_scanner_p->pid;
- share_array[num_entries_copied].share_mode = entry_scanner_p->share_mode;
- share_array[num_entries_copied].op_port = entry_scanner_p->op_port;
- share_array[num_entries_copied].op_type = entry_scanner_p->op_type;
- memcpy(&share_array[num_entries_copied].time, &entry_scanner_p->time,
- sizeof(struct timeval));
- num_entries_copied++;
- DEBUG(5,("get_share_modes (FAST_SHARE_MODES): Read share mode \
-record mode 0x%X pid=%d\n", entry_scanner_p->share_mode, entry_scanner_p->pid));
- entry_prev_p = entry_scanner_p;
- entry_scanner_p = (share_mode_entry *)
- smb_shm_offset2addr(entry_scanner_p->next_share_mode_entry);
- }
- }
-
- /* If no valid share mode entries were found then this record shouldn't exist ! */
- if(num_entries_copied == 0)
- {
- DEBUG(0,("get_share_modes (FAST_SHARE_MODES): file with dev %d, inode %d in \
-hash bucket %d has a share mode record but no entries - deleting\n",
- dev, inode, hash_entry));
- if(*old_shares)
- free((char *)*old_shares);
- *old_shares = 0;
-
- if(file_prev_p == file_scanner_p)
- mode_array[hash_entry] = file_scanner_p->next_offset;
- else
- file_prev_p->next_offset = file_scanner_p->next_offset;
- smb_shm_free(smb_shm_addr2offset(file_scanner_p));
- }
-
- DEBUG(5,("get_share_modes (FAST_SHARE_MODES): file with dev %d, inode %d in \
-hash bucket %d returning %d entries\n", dev, inode, hash_entry, num_entries_copied));
-
- return(num_entries_copied);
-}
-
-/*******************************************************************
-del the share mode of a file.
-********************************************************************/
-void del_share_mode(share_lock_token token, int fnum)
-{
- uint32 dev, inode;
- smb_shm_offset_t *mode_array;
- unsigned int hash_entry;
- share_mode_record *file_scanner_p;
- share_mode_record *file_prev_p;
- share_mode_entry *entry_scanner_p;
- share_mode_entry *entry_prev_p;
- BOOL found = False;
- int pid = getpid();
-
- dev = Files[fnum].fd_ptr->dev;
- inode = Files[fnum].fd_ptr->inode;
-
- hash_entry = HASH_ENTRY(dev, inode);
-
- if(hash_entry > lp_shmem_hash_size() )
- {
- DEBUG(0,
- ("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): hash_entry %d too large \
-(max = %d)\n",
- hash_entry, lp_shmem_hash_size() ));
- return;
- }
-
- mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off());
-
- if(mode_array[hash_entry] == NULL_OFFSET)
- {
- DEBUG(0,("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): hash bucket %d empty\n",
- hash_entry));
- return;
- }
-
- file_scanner_p = (share_mode_record *)smb_shm_offset2addr(mode_array[hash_entry]);
- file_prev_p = file_scanner_p;
-
- while(file_scanner_p)
- {
- if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
- {
- found = True;
- break;
- }
- else
- {
- file_prev_p = file_scanner_p ;
- file_scanner_p = (share_mode_record *)
- smb_shm_offset2addr(file_scanner_p->next_offset);
- }
- }
-
- if(!found)
- {
- DEBUG(0,("ERROR:del_share_mode (FAST_SHARE_MODES): no entry found for dev %d, \
-inode %d in hash bucket %d\n", dev, inode, hash_entry));
- return;
- }
-
- if(file_scanner_p->locking_version != LOCKING_VERSION)
- {
- DEBUG(0,("ERROR: del_share_modes (FAST_SHARE_MODES): Deleting old share mode \
-record due to old locking version %d for file dev %d, inode %d hash bucket %d\n",
- file_scanner_p->locking_version, dev, inode, hash_entry ));
- if(file_prev_p == file_scanner_p)
- mode_array[hash_entry] = file_scanner_p->next_offset;
- else
- file_prev_p->next_offset = file_scanner_p->next_offset;
- smb_shm_free(smb_shm_addr2offset(file_scanner_p));
- return;
- }
-
- found = False;
- entry_scanner_p = (share_mode_entry*)smb_shm_offset2addr(
- file_scanner_p->share_mode_entries);
- entry_prev_p = entry_scanner_p;
- while(entry_scanner_p)
- {
- if( (pid == entry_scanner_p->pid) &&
- (memcmp(&entry_scanner_p->time,
- &Files[fnum].open_time,sizeof(struct timeval)) == 0) )
- {
- found = True;
- break;
- }
- else
- {
- entry_prev_p = entry_scanner_p;
- entry_scanner_p = (share_mode_entry *)
- smb_shm_offset2addr(entry_scanner_p->next_share_mode_entry);
- }
- }
-
- if (found)
- {
- /* Decrement the number of entries in the record. */
- file_scanner_p->num_share_mode_entries -= 1;
-
- DEBUG(2,("del_share_modes (FAST_SHARE_MODES): \
-Deleting share mode entry dev = %d, inode = %d in hash bucket %d (num entries now = %d)\n",
- dev, inode, hash_entry, file_scanner_p->num_share_mode_entries));
- if(entry_prev_p == entry_scanner_p)
- /* We are at start of list */
- file_scanner_p->share_mode_entries = entry_scanner_p->next_share_mode_entry;
- else
- entry_prev_p->next_share_mode_entry = entry_scanner_p->next_share_mode_entry;
- smb_shm_free(smb_shm_addr2offset(entry_scanner_p));
-
- /* PARANOIA TEST */
- if(file_scanner_p->num_share_mode_entries < 0)
- {
- DEBUG(0,("PANIC ERROR:del_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \
-for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries,
- dev, inode, hash_entry));
- return;
- }
-
- /* If we deleted the last share mode entry then remove the share mode record. */
- if(file_scanner_p->num_share_mode_entries == 0)
- {
- DEBUG(2,("del_share_modes (FAST_SHARE_MODES): num entries = 0, deleting share_mode \
-record dev = %d, inode = %d in hash bucket %d\n", dev, inode, hash_entry));
- if(file_prev_p == file_scanner_p)
- mode_array[hash_entry] = file_scanner_p->next_offset;
- else
- file_prev_p->next_offset = file_scanner_p->next_offset;
- smb_shm_free(smb_shm_addr2offset(file_scanner_p));
- }
- }
- else
- {
- DEBUG(0,("ERROR: del_share_modes (FAST_SHARE_MODES): No share mode record found \
-dev = %d, inode = %d in hash bucket %d\n", dev, inode, hash_entry));
- }
-}
-
-/*******************************************************************
-set the share mode of a file. Return False on fail, True on success.
-********************************************************************/
-BOOL set_share_mode(share_lock_token token, int fnum, uint16 port, uint16 op_type)
-{
- files_struct *fs_p = &Files[fnum];
- int32 dev, inode;
- smb_shm_offset_t *mode_array;
- unsigned int hash_entry;
- share_mode_record *file_scanner_p;
- share_mode_record *file_prev_p;
- share_mode_entry *new_entry_p;
- smb_shm_offset_t new_entry_offset;
- BOOL found = False;
-
- dev = fs_p->fd_ptr->dev;
- inode = fs_p->fd_ptr->inode;
-
- hash_entry = HASH_ENTRY(dev, inode);
- if(hash_entry > lp_shmem_hash_size() )
- {
- DEBUG(0,
- ("PANIC ERROR:set_share_mode (FAST_SHARE_MODES): hash_entry %d too large \
-(max = %d)\n",
- hash_entry, lp_shmem_hash_size() ));
- return False;
- }
-
- mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off());
-
- file_scanner_p = (share_mode_record *)smb_shm_offset2addr(mode_array[hash_entry]);
- file_prev_p = file_scanner_p;
-
- while(file_scanner_p)
- {
- if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
- {
- found = True;
- break;
- }
- else
- {
- file_prev_p = file_scanner_p ;
- file_scanner_p = (share_mode_record *)
- smb_shm_offset2addr(file_scanner_p->next_offset);
- }
- }
-
- if(!found)
- {
- /* We must create a share_mode_record */
- share_mode_record *new_mode_p = NULL;
- smb_shm_offset_t new_offset = smb_shm_alloc( sizeof(share_mode_record) +
- strlen(fs_p->name) + 1);
- if(new_offset == NULL_OFFSET)
- {
- DEBUG(0,("ERROR:set_share_mode (FAST_SHARE_MODES): smb_shm_alloc fail !\n"));
- return False;
- }
- new_mode_p = smb_shm_offset2addr(new_offset);
- new_mode_p->locking_version = LOCKING_VERSION;
- new_mode_p->st_dev = dev;
- new_mode_p->st_ino = inode;
- new_mode_p->num_share_mode_entries = 0;
- new_mode_p->share_mode_entries = NULL_OFFSET;
- strcpy(new_mode_p->file_name, fs_p->name);
-
- /* Chain onto the start of the hash chain (in the hope we will be used first). */
- new_mode_p->next_offset = mode_array[hash_entry];
- mode_array[hash_entry] = new_offset;
-
- file_scanner_p = new_mode_p;
-
- DEBUG(3,("set_share_mode (FAST_SHARE_MODES): Created share record for %s (dev %d \
-inode %d in hash bucket %d\n", fs_p->name, dev, inode, hash_entry));
- }
-
- /* Now create the share mode entry */
- new_entry_offset = smb_shm_alloc( sizeof(share_mode_entry));
- if(new_entry_offset == NULL_OFFSET)
- {
- smb_shm_offset_t delete_offset = mode_array[hash_entry];
- DEBUG(0,("ERROR:set_share_mode (FAST_SHARE_MODES): smb_shm_alloc fail 1!\n"));
- /* Unlink the damaged record */
- mode_array[hash_entry] = file_scanner_p->next_offset;
- /* And delete it */
- smb_shm_free( delete_offset );
- return False;
- }
-
- new_entry_p = smb_shm_offset2addr(new_entry_offset);
-
- new_entry_p->pid = getpid();
- new_entry_p->share_mode = fs_p->share_mode;
- new_entry_p->op_port = port;
- new_entry_p->op_type = op_type;
- memcpy( (char *)&new_entry_p->time, (char *)&fs_p->open_time, sizeof(struct timeval));
-
- /* Chain onto the share_mode_record */
- new_entry_p->next_share_mode_entry = file_scanner_p->share_mode_entries;
- file_scanner_p->share_mode_entries = new_entry_offset;
-
- /* PARANOIA TEST */
- if(file_scanner_p->num_share_mode_entries < 0)
- {
- DEBUG(0,("PANIC ERROR:set_share_mode (FAST_SHARE_MODES): num_share_mode_entries < 0 (%d) \
-for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries,
- dev, inode, hash_entry));
- return False;
- }
-
- /* Increment the share_mode_entries counter */
- file_scanner_p->num_share_mode_entries += 1;
-
- DEBUG(3,("set_share_mode (FAST_SHARE_MODES): Created share entry for %s with mode \
-0x%X pid=%d (num_entries now = %d)\n",fs_p->name, fs_p->share_mode, new_entry_p->pid,
- file_scanner_p->num_share_mode_entries));
-
- return(True);
-}
-
-/*******************************************************************
-Remove an oplock port and mode entry from a share mode.
-********************************************************************/
-BOOL remove_share_oplock(int fnum, share_lock_token token)
-{
- uint32 dev, inode;
- smb_shm_offset_t *mode_array;
- unsigned int hash_entry;
- share_mode_record *file_scanner_p;
- share_mode_record *file_prev_p;
- share_mode_entry *entry_scanner_p;
- share_mode_entry *entry_prev_p;
- BOOL found = False;
- int pid = getpid();
-
- dev = Files[fnum].fd_ptr->dev;
- inode = Files[fnum].fd_ptr->inode;
-
- hash_entry = HASH_ENTRY(dev, inode);
-
- if(hash_entry > lp_shmem_hash_size() )
- {
- DEBUG(0,
- ("PANIC ERROR:remove_share_oplock (FAST_SHARE_MODES): hash_entry %d too large \
-(max = %d)\n",
- hash_entry, lp_shmem_hash_size() ));
- return False;
- }
-
- mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off());
-
- if(mode_array[hash_entry] == NULL_OFFSET)
- {
- DEBUG(0,("PANIC ERROR:remove_share_oplock (FAST_SHARE_MODES): hash bucket %d empty\n",
- hash_entry));
- return False;
- }
-
- file_scanner_p = (share_mode_record *)smb_shm_offset2addr(mode_array[hash_entry]);
- file_prev_p = file_scanner_p;
-
- while(file_scanner_p)
- {
- if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
- {
- found = True;
- break;
- }
- else
- {
- file_prev_p = file_scanner_p ;
- file_scanner_p = (share_mode_record *)
- smb_shm_offset2addr(file_scanner_p->next_offset);
- }
- }
-
- if(!found)
- {
- DEBUG(0,("ERROR:remove_share_oplock (FAST_SHARE_MODES): no entry found for dev %d, \
-inode %d in hash bucket %d\n", dev, inode, hash_entry));
- return False;
- }
-
- if(file_scanner_p->locking_version != LOCKING_VERSION)
- {
- DEBUG(0,("ERROR: remove_share_oplock (FAST_SHARE_MODES): Deleting old share mode \
-record due to old locking version %d for file dev %d, inode %d hash bucket %d\n",
- file_scanner_p->locking_version, dev, inode, hash_entry ));
- if(file_prev_p == file_scanner_p)
- mode_array[hash_entry] = file_scanner_p->next_offset;
- else
- file_prev_p->next_offset = file_scanner_p->next_offset;
- smb_shm_free(smb_shm_addr2offset(file_scanner_p));
- return False;
- }
-
- found = False;
- entry_scanner_p = (share_mode_entry*)smb_shm_offset2addr(
- file_scanner_p->share_mode_entries);
- entry_prev_p = entry_scanner_p;
- while(entry_scanner_p)
- {
- if( (pid == entry_scanner_p->pid) &&
- (entry_scanner_p->share_mode == Files[fnum].share_mode) &&
- (memcmp(&entry_scanner_p->time,
- &Files[fnum].open_time,sizeof(struct timeval)) == 0) )
- {
- /* Delete the oplock info. */
- entry_scanner_p->op_port = 0;
- entry_scanner_p->op_type = 0;
- found = True;
- break;
- }
- else
- {
- entry_prev_p = entry_scanner_p;
- entry_scanner_p = (share_mode_entry *)
- smb_shm_offset2addr(entry_scanner_p->next_share_mode_entry);
- }
- }
-
- if(!found)
- {
- DEBUG(0,("ERROR: remove_share_oplock (FAST_SHARE_MODES): No oplock granted share \
-mode record found dev = %d, inode = %d in hash bucket %d\n", dev, inode, hash_entry));
- return False;
- }
-
- return True;
-}
-
-#else /* FAST_SHARE_MODES */
-
-/* SHARE MODE LOCKS USING SLOW DESCRIPTION FILES */
-
-/*******************************************************************
- name a share file
- ******************************************************************/
-static BOOL share_name(int cnum, uint32 dev, uint32 inode, char *name)
-{
- strcpy(name,lp_lockdir());
- standard_sub(cnum,name);
- trim_string(name,"","/");
- if (!*name) return(False);
- name += strlen(name);
-
- sprintf(name,"/share.%u.%u",dev,inode);
- return(True);
-}
-
-/*******************************************************************
- lock a share mode file.
- ******************************************************************/
-BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok)
-{
- pstring fname;
- int fd;
-
- *ptok = (share_lock_token)-1;
-
- if(!share_name(cnum, dev, inode, fname))
- return False;
-
- {
- int old_umask;
- BOOL gotlock = False;
- unbecome_user();
- old_umask = umask(0);
-
- /*
- * There was a race condition in the original slow share mode code.
- * A smbd could open a share mode file, and before getting
- * the lock, another smbd could delete the last entry for
- * the share mode file and delete the file entry from the
- * directory. Thus this smbd would be left with a locked
- * share mode fd attached to a file that no longer had a
- * directory entry. Thus another smbd would think that
- * there were no outstanding opens on the file. To fix
- * this we now check we can do a stat() call on the filename
- * before allowing the lock to proceed, and back out completely
- * and try the open again if we cannot.
- * Jeremy Allison (jallison@whistle.com).
- */
-
- do
- {
- struct stat dummy_stat;
-
-#ifdef SECURE_SHARE_MODES
- fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0600);
-#else /* SECURE_SHARE_MODES */
- fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0666);
-#endif /* SECURE_SHARE_MODES */
-
- /* At this point we have an open fd to the share mode file.
- Lock the first byte exclusively to signify a lock. */
- if(fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False)
- {
- DEBUG(0,("ERROR lock_share_entry: fcntl_lock on file %s failed with %s\n",
- fname, strerror(errno)));
- close(fd);
- return False;
- }
-
- /*
- * If we cannot stat the filename, the file was deleted between
- * the open and the lock call. Back out and try again.
- */
-
- if(stat(fname, &dummy_stat)!=0)
- {
- DEBUG(2,("lock_share_entry: Re-issuing open on %s to fix race. Error was %s\n",
- fname, strerror(errno)));
- close(fd);
- }
- else
- gotlock = True;
- } while(!gotlock);
-
- umask(old_umask);
- if(!become_user(cnum,Connections[cnum].vuid))
- {
- DEBUG(0,("lock_share_entry: Can't become connected user!\n"));
- close(fd);
- return False;
- }
- /* We need to change directory back to the connection root. */
- if (ChDir(Connections[cnum].connectpath) != 0)
- {
- DEBUG(0,("lock_share_entry: Can't change directory to %s (%s)\n",
- Connections[cnum].connectpath, strerror(errno)));
- close(fd);
- return False;
- }
- }
-
- *ptok = (share_lock_token)fd;
- return True;
-}
-
-/*******************************************************************
- unlock a share mode file.
- ******************************************************************/
-BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token token)
-{
- int fd = (int)token;
- int ret = True;
-
- /* token is the fd of the open share mode file. */
- /* Unlock the first byte. */
- if(fcntl_lock(fd, F_SETLKW, 0, 1, F_UNLCK) == False)
- {
- DEBUG(0,("ERROR unlock_share_entry: fcntl_lock failed with %s\n",
- strerror(errno)));
- ret = False;
- }
-
- close(fd);
- return ret;
-}
-
-/*******************************************************************
-Force a share file to be deleted.
-********************************************************************/
-
-static int delete_share_file( int cnum, char *fname )
-{
- unbecome_user();
- if(unlink(fname) != 0)
- {
- DEBUG(0,("delete_share_file: Can't delete share file %s (%s)\n",
- fname, strerror(errno)));
- }
-
- DEBUG(5,("delete_share_file: Deleted share file %s\n", fname));
-
- if(!become_user(cnum,Connections[cnum].vuid))
- {
- DEBUG(0,("delete_share_file: Can't become connected user!\n"));
- return -1;
- }
- /* We need to change directory back to the connection root. */
- if (ChDir(Connections[cnum].connectpath) != 0)
- {
- DEBUG(0,("delete_share_file: Can't change directory to %s (%s)\n",
- Connections[cnum].connectpath, strerror(errno)));
- return -1;
- }
- return 0;
-}
-
-/*******************************************************************
-Read a share file into a buffer.
-********************************************************************/
-
-static int read_share_file(int cnum, int fd, char *fname, char **out, BOOL *p_new_file)
-{
- struct stat sb;
- char *buf;
- int size;
-
- *out = 0;
- *p_new_file = False;
-
- if(fstat(fd, &sb) != 0)
- {
- DEBUG(0,("ERROR: read_share_file: Failed to do stat on share file %s (%s)\n",
- fname, strerror(errno)));
- return -1;
- }
-
- if(sb.st_size == 0)
- {
- *p_new_file = True;
- return 0;
- }
-
- /* Allocate space for the file */
- if((buf = (char *)malloc(sb.st_size)) == NULL)
- {
- DEBUG(0,("read_share_file: malloc for file size %d fail !\n", sb.st_size));
- return -1;
- }
-
- if(lseek(fd, 0, SEEK_SET) != 0)
- {
- DEBUG(0,("ERROR: read_share_file: Failed to reset position to 0 \
-for share file %s (%s)\n", fname, strerror(errno)));
- if(buf)
- free(buf);
- return -1;
- }
-
- if (read(fd,buf,sb.st_size) != sb.st_size)
- {
- DEBUG(0,("ERROR: read_share_file: Failed to read share file %s (%s)\n",
- fname, strerror(errno)));
- if(buf)
- free(buf);
- return -1;
- }
-
- if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION) {
- DEBUG(0,("ERROR: read_share_file: share file %s has incorrect \
-locking version (was %d, should be %d).\n",fname,
- IVAL(buf,SMF_VERSION_OFFSET), LOCKING_VERSION));
- if(buf)
- free(buf);
- delete_share_file(cnum, fname);
- return -1;
- }
-
- /* Sanity check for file contents */
- size = sb.st_size;
- size -= SMF_HEADER_LENGTH; /* Remove the header */
-
- /* Remove the filename component. */
- size -= SVAL(buf, SMF_FILENAME_LEN_OFFSET);
-
- /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */
- if((size % SMF_ENTRY_LENGTH) != 0)
- {
- DEBUG(0,("ERROR: read_share_file: share file %s is an incorrect length - \
-deleting it.\n", fname));
- if(buf)
- free(buf);
- delete_share_file(cnum, fname);
- return -1;
- }
-
- *out = buf;
- return 0;
-}
-
-/*******************************************************************
-get all share mode entries in a share file for a dev/inode pair.
-********************************************************************/
-int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode,
- min_share_mode_entry **old_shares)
-{
- int fd = (int)token;
- pstring fname;
- int i;
- int num_entries;
- int num_entries_copied;
- int newsize;
- min_share_mode_entry *share_array;
- char *buf = 0;
- char *base = 0;
- BOOL new_file;
-
- *old_shares = 0;
-
- /* Read the share file header - this is of the form:
- 0 - locking version.
- 4 - number of share mode entries.
- 8 - 2 byte name length
- [n bytes] file name (zero terminated).
-
- Followed by <n> share mode entries of the form :
-
- 0 - tv_sec
- 4 - tv_usec
- 8 - share_mode
- 12 - pid
- 16 - oplock port (if oplocks in use) - 2 bytes.
- */
-
- share_name(cnum, dev, inode, fname);
-
- if(read_share_file( cnum, fd, fname, &buf, &new_file) != 0)
- {
- DEBUG(0,("ERROR: get_share_modes: Failed to read share file %s\n",
- fname));
- return 0;
- }
-
- if(new_file == True)
- return 0;
-
- num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
-
- DEBUG(5,("get_share_modes: share file %s has %d share mode entries.\n",
- fname, num_entries));
-
- /* PARANOIA TEST */
- if(num_entries < 0)
- {
- DEBUG(0,("PANIC ERROR:get_share_mode: num_share_mode_entries < 0 (%d) \
-for share file %d\n", num_entries, fname));
- return 0;
- }
-
- if(num_entries)
- {
- *old_shares = share_array = (min_share_mode_entry *)
- malloc(num_entries * sizeof(min_share_mode_entry));
- if(*old_shares == 0)
- {
- DEBUG(0,("get_share_modes: malloc fail !\n"));
- return 0;
- }
- }
- else
- {
- /* No entries - just delete the file. */
- DEBUG(0,("get_share_modes: share file %s has no share mode entries - deleting.\n",
- fname));
- if(buf)
- free(buf);
- delete_share_file(cnum, fname);
- return 0;
- }
-
- num_entries_copied = 0;
- base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
-
- for( i = 0; i < num_entries; i++)
- {
- int pid;
- char *p = base + (i*SMF_ENTRY_LENGTH);
-
- pid = IVAL(p,SME_PID_OFFSET);
-
- if(!process_exists(pid))
- {
- DEBUG(0,("get_share_modes: process %d no longer exists and \
-it left a share mode entry with mode 0x%X in share file %s\n",
- pid, IVAL(p,SME_SHAREMODE_OFFSET), fname));
- continue;
- }
- share_array[num_entries_copied].time.tv_sec = IVAL(p,SME_SEC_OFFSET);
- share_array[num_entries_copied].time.tv_usec = IVAL(p,SME_USEC_OFFSET);
- share_array[num_entries_copied].share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
- share_array[num_entries_copied].pid = pid;
- share_array[num_entries_copied].op_port = SVAL(p,SME_PORT_OFFSET);
- share_array[num_entries_copied].op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
-
- num_entries_copied++;
- }
-
- if(num_entries_copied == 0)
- {
- /* Delete the whole file. */
- DEBUG(0,("get_share_modes: share file %s had no valid entries - deleting it !\n",
- fname));
- if(*old_shares)
- free((char *)*old_shares);
- *old_shares = 0;
- if(buf)
- free(buf);
- delete_share_file(cnum, fname);
- return 0;
- }
-
- /* If we deleted some entries we need to re-write the whole number of
- share mode entries back into the file. */
-
- if(num_entries_copied != num_entries)
- {
- if(lseek(fd, 0, SEEK_SET) != 0)
- {
- DEBUG(0,("ERROR: get_share_modes: lseek failed to reset to \
-position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
- if(*old_shares)
- free((char *)*old_shares);
- *old_shares = 0;
- if(buf)
- free(buf);
- return 0;
- }
-
- SIVAL(buf, SMF_NUM_ENTRIES_OFFSET, num_entries_copied);
- for( i = 0; i < num_entries_copied; i++)
- {
- char *p = base + (i*SMF_ENTRY_LENGTH);
-
- SIVAL(p,SME_PID_OFFSET,share_array[i].pid);
- SIVAL(p,SME_SHAREMODE_OFFSET,share_array[i].share_mode);
- SIVAL(p,SME_SEC_OFFSET,share_array[i].time.tv_sec);
- SIVAL(p,SME_USEC_OFFSET,share_array[i].time.tv_usec);
- SSVAL(p,SME_PORT_OFFSET,share_array[i].op_port);
- SSVAL(p,SME_OPLOCK_TYPE_OFFSET,share_array[i].op_type);
- }
-
- newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries_copied);
- if(write(fd, buf, newsize) != newsize)
- {
- DEBUG(0,("ERROR: get_share_modes: failed to re-write share \
-mode file %s (%s)\n", fname, strerror(errno)));
- if(*old_shares)
- free((char *)*old_shares);
- *old_shares = 0;
- if(buf)
- free(buf);
- return 0;
- }
- /* Now truncate the file at this point. */
- if(ftruncate(fd, newsize)!= 0)
- {
- DEBUG(0,("ERROR: get_share_modes: failed to ftruncate share \
-mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
- if(*old_shares)
- free((char *)*old_shares);
- *old_shares = 0;
- if(buf)
- free(buf);
- return 0;
- }
- }
-
- if(buf)
- free(buf);
-
- DEBUG(5,("get_share_modes: Read share file %s returning %d entries\n",fname,
- num_entries_copied));
-
- return num_entries_copied;
-}
-
-/*******************************************************************
-del a share mode from a share mode file.
-********************************************************************/
-void del_share_mode(share_lock_token token, int fnum)
-{
- pstring fname;
- int fd = (int)token;
- char *buf = 0;
- char *base = 0;
- int num_entries;
- int newsize;
- int i;
- files_struct *fs_p = &Files[fnum];
- int pid;
- BOOL deleted = False;
- BOOL new_file;
-
- share_name(fs_p->cnum, fs_p->fd_ptr->dev,
- fs_p->fd_ptr->inode, fname);
-
- if(read_share_file( fs_p->cnum, fd, fname, &buf, &new_file) != 0)
- {
- DEBUG(0,("ERROR: del_share_mode: Failed to read share file %s\n",
- fname));
- return;
- }
-
- if(new_file == True)
- {
- DEBUG(0,("ERROR:del_share_mode: share file %s is new (size zero), deleting it.\n",
- fname));
- delete_share_file(fs_p->cnum, fname);
- return;
- }
-
- num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
-
- DEBUG(5,("del_share_mode: share file %s has %d share mode entries.\n",
- fname, num_entries));
-
- /* PARANOIA TEST */
- if(num_entries < 0)
- {
- DEBUG(0,("PANIC ERROR:del_share_mode: num_share_mode_entries < 0 (%d) \
-for share file %d\n", num_entries, fname));
- return;
- }
-
- if(num_entries == 0)
- {
- /* No entries - just delete the file. */
- DEBUG(0,("del_share_mode: share file %s has no share mode entries - deleting.\n",
- fname));
- if(buf)
- free(buf);
- delete_share_file(fs_p->cnum, fname);
- return;
- }
-
- pid = getpid();
-
- /* Go through the entries looking for the particular one
- we have set - delete it.
- */
-
- base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
-
- for(i = 0; i < num_entries; i++)
- {
- char *p = base + (i*SMF_ENTRY_LENGTH);
-
- if((IVAL(p,SME_SEC_OFFSET) != fs_p->open_time.tv_sec) ||
- (IVAL(p,SME_USEC_OFFSET) != fs_p->open_time.tv_usec) ||
- (IVAL(p,SME_SHAREMODE_OFFSET) != fs_p->share_mode) ||
- (IVAL(p,SME_PID_OFFSET) != pid))
- continue;
-
- DEBUG(5,("del_share_mode: deleting entry number %d (of %d) from the share file %s\n",
- i, num_entries, fname));
-
- /* Remove this entry. */
- if(i != num_entries - 1)
- memcpy(p, p + SMF_ENTRY_LENGTH, (num_entries - i - 1)*SMF_ENTRY_LENGTH);
-
- deleted = True;
- break;
- }
-
- if(!deleted)
- {
- DEBUG(0,("del_share_mode: entry not found in share file %s\n", fname));
- if(buf)
- free(buf);
- return;
- }
-
- num_entries--;
- SIVAL(buf,SMF_NUM_ENTRIES_OFFSET, num_entries);
-
- if(num_entries == 0)
- {
- /* Deleted the last entry - remove the file. */
- DEBUG(5,("del_share_mode: removed last entry in share file - deleting share file %s\n",
- fname));
- if(buf)
- free(buf);
- delete_share_file(fs_p->cnum,fname);
- return;
- }
-
- /* Re-write the file - and truncate it at the correct point. */
- if(lseek(fd, 0, SEEK_SET) != 0)
- {
- DEBUG(0,("ERROR: del_share_mode: lseek failed to reset to \
-position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
- if(buf)
- free(buf);
- return;
- }
-
- newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries);
- if(write(fd, buf, newsize) != newsize)
- {
- DEBUG(0,("ERROR: del_share_mode: failed to re-write share \
-mode file %s (%s)\n", fname, strerror(errno)));
- if(buf)
- free(buf);
- return;
- }
- /* Now truncate the file at this point. */
- if(ftruncate(fd, newsize) != 0)
- {
- DEBUG(0,("ERROR: del_share_mode: failed to ftruncate share \
-mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
- if(buf)
- free(buf);
- return;
- }
-}
-
-/*******************************************************************
-set the share mode of a file
-********************************************************************/
-BOOL set_share_mode(share_lock_token token,int fnum, uint16 port, uint16 op_type)
-{
- files_struct *fs_p = &Files[fnum];
- pstring fname;
- int fd = (int)token;
- int pid = (int)getpid();
- struct stat sb;
- char *buf;
- int num_entries;
- int header_size;
- char *p;
-
- share_name(fs_p->cnum, fs_p->fd_ptr->dev,
- fs_p->fd_ptr->inode, fname);
-
- if(fstat(fd, &sb) != 0)
- {
- DEBUG(0,("ERROR: set_share_mode: Failed to do stat on share file %s\n",
- fname));
- return False;
- }
-
- /* Sanity check for file contents (if it's not a new share file). */
- if(sb.st_size != 0)
- {
- int size = sb.st_size;
-
- /* Allocate space for the file plus one extra entry */
- if((buf = (char *)malloc(sb.st_size + SMF_ENTRY_LENGTH)) == NULL)
- {
- DEBUG(0,("set_share_mode: malloc for file size %d fail !\n",
- sb.st_size + SMF_ENTRY_LENGTH));
- return False;
- }
-
- if(lseek(fd, 0, SEEK_SET) != 0)
- {
- DEBUG(0,("ERROR: set_share_mode: Failed to reset position \
-to 0 for share file %s (%s)\n", fname, strerror(errno)));
- if(buf)
- free(buf);
- return False;
- }
-
- if (read(fd,buf,sb.st_size) != sb.st_size)
- {
- DEBUG(0,("ERROR: set_share_mode: Failed to read share file %s (%s)\n",
- fname, strerror(errno)));
- if(buf)
- free(buf);
- return False;
- }
-
- if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION)
- {
- DEBUG(0,("ERROR: set_share_mode: share file %s has incorrect \
-locking version (was %d, should be %d).\n",fname, IVAL(buf,SMF_VERSION_OFFSET),
- LOCKING_VERSION));
- if(buf)
- free(buf);
- delete_share_file(fs_p->cnum, fname);
- return False;
- }
-
- size -= (SMF_HEADER_LENGTH + SVAL(buf, SMF_FILENAME_LEN_OFFSET)); /* Remove the header */
-
- /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */
- if((size % SMF_ENTRY_LENGTH) != 0)
- {
- DEBUG(0,("ERROR: set_share_mode: share file %s is an incorrect length - \
-deleting it.\n", fname));
- if(buf)
- free(buf);
- delete_share_file(fs_p->cnum, fname);
- return False;
- }
-
- }
- else
- {
- /* New file - just use a single_entry. */
- if((buf = (char *)malloc(SMF_HEADER_LENGTH +
- strlen(fs_p->name) + 1 + SMF_ENTRY_LENGTH)) == NULL)
- {
- DEBUG(0,("ERROR: set_share_mode: malloc failed for single entry.\n"));
- return False;
- }
- SIVAL(buf,SMF_VERSION_OFFSET,LOCKING_VERSION);
- SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,0);
- SSVAL(buf,SMF_FILENAME_LEN_OFFSET,strlen(fs_p->name) + 1);
- strcpy(buf + SMF_HEADER_LENGTH, fs_p->name);
- }
-
- num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
- header_size = SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
- p = buf + header_size + (num_entries * SMF_ENTRY_LENGTH);
- SIVAL(p,SME_SEC_OFFSET,fs_p->open_time.tv_sec);
- SIVAL(p,SME_USEC_OFFSET,fs_p->open_time.tv_usec);
- SIVAL(p,SME_SHAREMODE_OFFSET,fs_p->share_mode);
- SIVAL(p,SME_PID_OFFSET,pid);
- SSVAL(p,SME_PORT_OFFSET,port);
- SSVAL(p,SME_OPLOCK_TYPE_OFFSET,op_type);
-
- num_entries++;
-
- SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,num_entries);
-
- if(lseek(fd, 0, SEEK_SET) != 0)
- {
- DEBUG(0,("ERROR: set_share_mode: (1) Failed to reset position to \
-0 for share file %s (%s)\n", fname, strerror(errno)));
- if(buf)
- free(buf);
- return False;
- }
-
- if (write(fd,buf,header_size + (num_entries*SMF_ENTRY_LENGTH)) !=
- (header_size + (num_entries*SMF_ENTRY_LENGTH)))
- {
- DEBUG(2,("ERROR: set_share_mode: Failed to write share file %s - \
-deleting it (%s).\n",fname, strerror(errno)));
- delete_share_file(fs_p->cnum, fname);
- if(buf)
- free(buf);
- return False;
- }
-
- /* Now truncate the file at this point - just for safety. */
- if(ftruncate(fd, header_size + (SMF_ENTRY_LENGTH*num_entries))!= 0)
- {
- DEBUG(0,("ERROR: set_share_mode: failed to ftruncate share \
-mode file %s to size %d (%s)\n", fname, header_size + (SMF_ENTRY_LENGTH*num_entries),
- strerror(errno)));
- if(buf)
- free(buf);
- return False;
- }
-
- if(buf)
- free(buf);
-
- DEBUG(3,("set_share_mode: Created share file %s with \
-mode 0x%X pid=%d\n",fname,fs_p->share_mode,pid));
-
- return True;
-}
-
-/*******************************************************************
-Remove an oplock port and mode entry from a share mode.
-********************************************************************/
-BOOL remove_share_oplock(int fnum, share_lock_token token)
-{
- pstring fname;
- int fd = (int)token;
- char *buf = 0;
- char *base = 0;
- int num_entries;
- int fsize;
- int i;
- files_struct *fs_p = &Files[fnum];
- int pid;
- BOOL found = False;
- BOOL new_file;
-
- share_name(fs_p->cnum, fs_p->fd_ptr->dev,
- fs_p->fd_ptr->inode, fname);
-
- if(read_share_file( fs_p->cnum, fd, fname, &buf, &new_file) != 0)
- {
- DEBUG(0,("ERROR: remove_share_oplock: Failed to read share file %s\n",
- fname));
- return False;
- }
-
- if(new_file == True)
- {
- DEBUG(0,("ERROR: remove_share_oplock: share file %s is new (size zero), \
-deleting it.\n", fname));
- delete_share_file(fs_p->cnum, fname);
- return False;
- }
-
- num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
-
- DEBUG(5,("remove_share_oplock: share file %s has %d share mode entries.\n",
- fname, num_entries));
-
- /* PARANOIA TEST */
- if(num_entries < 0)
- {
- DEBUG(0,("PANIC ERROR:remove_share_oplock: num_share_mode_entries < 0 (%d) \
-for share file %d\n", num_entries, fname));
- return False;
- }
-
- if(num_entries == 0)
- {
- /* No entries - just delete the file. */
- DEBUG(0,("remove_share_oplock: share file %s has no share mode entries - deleting.\n",
- fname));
- if(buf)
- free(buf);
- delete_share_file(fs_p->cnum, fname);
- return False;
- }
-
- pid = getpid();
-
- /* Go through the entries looking for the particular one
- we have set - remove the oplock settings on it.
- */
-
- base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
-
- for(i = 0; i < num_entries; i++)
- {
- char *p = base + (i*SMF_ENTRY_LENGTH);
-
- if((IVAL(p,SME_SEC_OFFSET) != fs_p->open_time.tv_sec) ||
- (IVAL(p,SME_USEC_OFFSET) != fs_p->open_time.tv_usec) ||
- (IVAL(p,SME_SHAREMODE_OFFSET) != fs_p->share_mode) ||
- (IVAL(p,SME_PID_OFFSET) != pid))
- continue;
-
- DEBUG(5,("remove_share_oplock: clearing oplock on entry number %d (of %d) \
-from the share file %s\n", i, num_entries, fname));
-
- SSVAL(p,SME_PORT_OFFSET,0);
- SSVAL(p,SME_OPLOCK_TYPE_OFFSET,0);
- found = True;
- break;
- }
-
- if(!found)
- {
- DEBUG(0,("remove_share_oplock: entry not found in share file %s\n", fname));
- if(buf)
- free(buf);
- return False;
- }
-
- /* Re-write the file - and truncate it at the correct point. */
- if(lseek(fd, 0, SEEK_SET) != 0)
- {
- DEBUG(0,("ERROR: remove_share_oplock: lseek failed to reset to \
-position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
- if(buf)
- free(buf);
- return False;
- }
-
- fsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries);
- if(write(fd, buf, fsize) != fsize)
- {
- DEBUG(0,("ERROR: remove_share_oplock: failed to re-write share \
-mode file %s (%s)\n", fname, strerror(errno)));
- if(buf)
- free(buf);
- return False;
- }
-
- return True;
-
-}
-#endif /* FAST_SHARE_MODES */
diff --git a/source/locking/shmem.c b/source/locking/shmem.c
deleted file mode 100644
index bbb11f215a0..00000000000
--- a/source/locking/shmem.c
+++ /dev/null
@@ -1,844 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Shared memory functions
- Copyright (C) Erik Devriendt 1996-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.
-
-*/
-
-#include "includes.h"
-
-
-#ifdef FAST_SHARE_MODES
-
-
-extern int DEBUGLEVEL;
-
-
-#define SMB_SHM_MAGIC 0x53484100
-/* = "SHM" in hex */
-
-#define SMB_SHM_VERSION 2
-
-/* WARNING : offsets are used because mmap() does not guarantee that all processes have the
- shared memory mapped to the same address */
-
-struct SmbShmHeader
-{
- int smb_shm_magic;
- int smb_shm_version;
- int total_size; /* in bytes */
- BOOL consistent;
- smb_shm_offset_t first_free_off;
- smb_shm_offset_t userdef_off; /* a userdefined offset. can be used to store root of tree or list */
- struct { /* a cell is a range of bytes of sizeof(struct SmbShmBlockDesc) size */
- int cells_free;
- int cells_used;
- int cells_system; /* number of cells used as allocated block descriptors */
- } statistics;
-};
-
-#define SMB_SHM_NOT_FREE_OFF (-1)
-struct SmbShmBlockDesc
-{
- smb_shm_offset_t next; /* offset of next block in the free list or SMB_SHM_NOT_FREE_OFF when block in use */
- int size; /* user size in BlockDescSize units */
-};
-
-#define EOList_Addr (struct SmbShmBlockDesc *)( 0 )
-#define EOList_Off (NULL_OFFSET)
-
-#define CellSize sizeof(struct SmbShmBlockDesc)
-
-/* HeaderSize aligned on 8 byte boundary */
-#define AlignedHeaderSize ((sizeof(struct SmbShmHeader)+7) & ~7)
-
-static int smb_shm_fd = -1;
-static pstring smb_shm_processreg_name = "";
-
-static struct SmbShmHeader *smb_shm_header_p = (struct SmbShmHeader *)0;
-static int smb_shm_times_locked = 0;
-
-static BOOL smb_shm_initialize_called = False;
-
-static BOOL smb_shm_global_lock(void)
-{
- if (smb_shm_fd < 0)
- {
- DEBUG(0,("ERROR smb_shm_global_lock : bad smb_shm_fd (%d)\n",smb_shm_fd));
- return False;
- }
-
- smb_shm_times_locked++;
-
- if(smb_shm_times_locked > 1)
- {
- DEBUG(5,("smb_shm_global_lock : locked %d times\n",smb_shm_times_locked));
- return True;
- }
-
- /* Do an exclusive wait lock on the first byte of the file */
- if (fcntl_lock(smb_shm_fd, F_SETLKW, 0, 1, F_WRLCK) == False)
- {
- DEBUG(0,("ERROR smb_shm_global_lock : fcntl_lock failed with code %s\n",strerror(errno)));
- smb_shm_times_locked--;
- return False;
- }
-
- return True;
-
-}
-
-static BOOL smb_shm_global_unlock(void)
-{
- if (smb_shm_fd < 0)
- {
- DEBUG(0,("ERROR smb_shm_global_unlock : bad smb_shm_fd (%d)\n",smb_shm_fd));
- return False;
- }
-
- if(smb_shm_times_locked == 0)
- {
- DEBUG(0,("ERROR smb_shm_global_unlock : shmem not locked\n",smb_shm_fd));
- return False;
- }
-
- smb_shm_times_locked--;
-
- if(smb_shm_times_locked > 0)
- {
- DEBUG(5,("smb_shm_global_unlock : still locked %d times\n",smb_shm_times_locked));
- return True;
- }
-
- /* Do a wait unlock on the first byte of the file */
- if (fcntl_lock(smb_shm_fd, F_SETLKW, 0, 1, F_UNLCK) == False)
- {
- DEBUG(0,("ERROR smb_shm_global_unlock : fcntl_lock failed with code %s\n",strerror(errno)));
- smb_shm_times_locked++;
- return False;
- }
-
- return True;
-
-}
-
-/*
- * Function to create the hash table for the share mode entries. Called
- * when smb shared memory is global locked.
- */
-
-BOOL smb_shm_create_hash_table( unsigned int size )
-{
- size *= sizeof(smb_shm_offset_t);
-
- smb_shm_global_lock();
- smb_shm_header_p->userdef_off = smb_shm_alloc( size );
-
- if(smb_shm_header_p->userdef_off == NULL_OFFSET)
- {
- DEBUG(0,("smb_shm_create_hash_table: Failed to create hash table of size %d\n",size));
- smb_shm_global_unlock();
- return False;
- }
-
- /* Clear hash buckets. */
- memset( smb_shm_offset2addr(smb_shm_header_p->userdef_off), '\0', size);
- smb_shm_global_unlock();
- return True;
-}
-
-static BOOL smb_shm_register_process(char *processreg_file, pid_t pid, BOOL *other_processes)
-{
- int smb_shm_processes_fd = -1;
- int nb_read;
- pid_t other_pid;
- int seek_back = -((int)sizeof(other_pid));
- int free_slot = -1;
- int erased_slot;
-
-#ifndef SECURE_SHARE_MODES
- smb_shm_processes_fd = open(processreg_file, O_RDWR | O_CREAT, 0666);
-#else /* SECURE_SHARE_MODES */
- smb_shm_processes_fd = open(processreg_file, O_RDWR | O_CREAT, 0600);
-#endif /* SECURE_SHARE_MODES */
- if ( smb_shm_processes_fd < 0 )
- {
- DEBUG(0,("ERROR smb_shm_register_process : processreg_file open failed with code %s\n",strerror(errno)));
- return False;
- }
-
- *other_processes = False;
-
- while ((nb_read = read(smb_shm_processes_fd, &other_pid, sizeof(other_pid))) > 0)
- {
- if(other_pid)
- {
- if(process_exists(other_pid))
- *other_processes = True;
- else
- {
- /* erase old pid */
- DEBUG(5,("smb_shm_register_process : erasing stale record for pid %d (seek_back = %d)\n",
- other_pid, seek_back));
- other_pid = (pid_t)0;
- erased_slot = lseek(smb_shm_processes_fd, seek_back, SEEK_CUR);
- write(smb_shm_processes_fd, &other_pid, sizeof(other_pid));
- if(free_slot < 0)
- free_slot = erased_slot;
- }
- }
- else
- if(free_slot < 0)
- free_slot = lseek(smb_shm_processes_fd, seek_back, SEEK_CUR);
- }
- if (nb_read < 0)
- {
- DEBUG(0,("ERROR smb_shm_register_process : processreg_file read failed with code %s\n",strerror(errno)));
- close(smb_shm_processes_fd);
- return False;
- }
-
- if(free_slot < 0)
- free_slot = lseek(smb_shm_processes_fd, 0, SEEK_END);
-
- DEBUG(5,("smb_shm_register_process : writing record for pid %d at offset %d\n",pid,free_slot));
- lseek(smb_shm_processes_fd, free_slot, SEEK_SET);
- if(write(smb_shm_processes_fd, &pid, sizeof(pid)) < 0)
- {
- DEBUG(0,("ERROR smb_shm_register_process : processreg_file write failed with code %s\n",strerror(errno)));
- close(smb_shm_processes_fd);
- return False;
- }
-
- close(smb_shm_processes_fd);
-
- return True;
-}
-
-static BOOL smb_shm_unregister_process(char *processreg_file, pid_t pid)
-{
- int old_umask;
- int smb_shm_processes_fd = -1;
- int nb_read;
- pid_t other_pid;
- int seek_back = -((int)sizeof(other_pid));
- int erased_slot;
- BOOL found = False;
-
-
- old_umask = umask(0);
- smb_shm_processes_fd = open(processreg_file, O_RDWR);
- umask(old_umask);
- if ( smb_shm_processes_fd < 0 )
- {
- DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file open failed with code %s\n",strerror(errno)));
- return False;
- }
-
- while ((nb_read = read(smb_shm_processes_fd, &other_pid, sizeof(other_pid))) > 0)
- {
- DEBUG(5,("smb_shm_unregister_process : read record for pid %d\n",other_pid));
- if(other_pid == pid)
- {
- /* erase pid */
- DEBUG(5,("smb_shm_unregister_process : erasing record for pid %d (seek_val = %d)\n",
- other_pid, seek_back));
- other_pid = (pid_t)0;
- erased_slot = lseek(smb_shm_processes_fd, seek_back, SEEK_CUR);
- if(write(smb_shm_processes_fd, &other_pid, sizeof(other_pid)) < 0)
- {
- DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file write failed with code %s\n",strerror(errno)));
- close(smb_shm_processes_fd);
- return False;
- }
-
- found = True;
- break;
- }
- }
- if (nb_read < 0)
- {
- DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file read failed with code %s\n",strerror(errno)));
- close(smb_shm_processes_fd);
- return False;
- }
-
- if(!found)
- {
- DEBUG(0,("ERROR smb_shm_unregister_process : couldn't find pid %d in file %s\n",pid,processreg_file));
- close(smb_shm_processes_fd);
- return False;
- }
-
-
- close(smb_shm_processes_fd);
-
- return True;
-}
-
-
-static BOOL smb_shm_validate_header(int size)
-{
- if( !smb_shm_header_p )
- {
- /* not mapped yet */
- DEBUG(0,("ERROR smb_shm_validate_header : shmem not mapped\n"));
- return False;
- }
-
- if(smb_shm_header_p->smb_shm_magic != SMB_SHM_MAGIC)
- {
- DEBUG(0,("ERROR smb_shm_validate_header : bad magic\n"));
- return False;
- }
- if(smb_shm_header_p->smb_shm_version != SMB_SHM_VERSION)
- {
- DEBUG(0,("ERROR smb_shm_validate_header : bad version %X\n",smb_shm_header_p->smb_shm_version));
- return False;
- }
-
- if(smb_shm_header_p->total_size != size)
- {
- DEBUG(0,("ERROR smb_shm_validate_header : shmem size mismatch (old = %d, new = %d)\n",smb_shm_header_p->total_size,size));
- return False;
- }
-
- if(!smb_shm_header_p->consistent)
- {
- DEBUG(0,("ERROR smb_shm_validate_header : shmem not consistent\n"));
- return False;
- }
- return True;
-}
-
-static BOOL smb_shm_initialize(int size)
-{
- struct SmbShmBlockDesc * first_free_block_p;
-
- DEBUG(5,("smb_shm_initialize : initializing shmem file of size %d\n",size));
-
- if( !smb_shm_header_p )
- {
- /* not mapped yet */
- DEBUG(0,("ERROR smb_shm_initialize : shmem not mapped\n"));
- return False;
- }
-
- smb_shm_header_p->smb_shm_magic = SMB_SHM_MAGIC;
- smb_shm_header_p->smb_shm_version = SMB_SHM_VERSION;
- smb_shm_header_p->total_size = size;
- smb_shm_header_p->first_free_off = AlignedHeaderSize;
- smb_shm_header_p->userdef_off = NULL_OFFSET;
-
- first_free_block_p = (struct SmbShmBlockDesc *)smb_shm_offset2addr(smb_shm_header_p->first_free_off);
- first_free_block_p->next = EOList_Off;
- first_free_block_p->size = ( size - AlignedHeaderSize - CellSize ) / CellSize ;
-
- smb_shm_header_p->statistics.cells_free = first_free_block_p->size;
- smb_shm_header_p->statistics.cells_used = 0;
- smb_shm_header_p->statistics.cells_system = 1;
-
- smb_shm_header_p->consistent = True;
-
- smb_shm_initialize_called = True;
-
- return True;
-}
-
-static void smb_shm_solve_neighbors(struct SmbShmBlockDesc *head_p )
-{
- struct SmbShmBlockDesc *next_p;
-
- /* Check if head_p and head_p->next are neighbors and if so join them */
- if ( head_p == EOList_Addr ) return ;
- if ( head_p->next == EOList_Off ) return ;
-
- next_p = (struct SmbShmBlockDesc *)smb_shm_offset2addr(head_p->next);
- if ( ( head_p + head_p->size + 1 ) == next_p)
- {
- head_p->size += next_p->size +1 ; /* adapt size */
- head_p->next = next_p->next ; /* link out */
-
- smb_shm_header_p->statistics.cells_free += 1;
- smb_shm_header_p->statistics.cells_system -= 1;
- }
-}
-
-
-
-BOOL smb_shm_open( char *file_name, int size)
-{
- int filesize;
- BOOL created_new = False;
- BOOL other_processes = True;
- int old_umask;
-
- DEBUG(5,("smb_shm_open : using shmem file %s to be of size %d\n",file_name,size));
-
- old_umask = umask(0);
-#ifndef SECURE_SHARE_MODES
- smb_shm_fd = open(file_name, O_RDWR | O_CREAT, 0666);
-#else /* SECURE_SHARE_MODES */
- smb_shm_fd = open(file_name, O_RDWR | O_CREAT, 0600);
-#endif /* SECURE_SHARE_MODE */
- umask(old_umask);
- if ( smb_shm_fd < 0 )
- {
- DEBUG(0,("ERROR smb_shm_open : open failed with code %s\n",strerror(errno)));
- return False;
- }
-
- if (!smb_shm_global_lock())
- {
- DEBUG(0,("ERROR smb_shm_open : can't do smb_shm_global_lock\n"));
- return False;
- }
-
- if( (filesize = lseek(smb_shm_fd, 0, SEEK_END)) < 0)
- {
- DEBUG(0,("ERROR smb_shm_open : lseek failed with code %s\n",strerror(errno)));
- smb_shm_global_unlock();
- close(smb_shm_fd);
- return False;
- }
-
- /* return the file offset to 0 to save on later seeks */
- lseek(smb_shm_fd,0,SEEK_SET);
-
- if (filesize == 0)
- {
- /* we just created a new one */
- created_new = True;
- }
-
- /* to find out if some other process is already mapping the file,
- we use a registration file containing the processids of the file mapping processes
- */
-
- /* construct processreg file name */
- strcpy(smb_shm_processreg_name, file_name);
- strcat(smb_shm_processreg_name, ".processes");
-
- if (! smb_shm_register_process(smb_shm_processreg_name, getpid(), &other_processes))
- {
- smb_shm_global_unlock();
- close(smb_shm_fd);
- return False;
- }
-
- if (created_new || !other_processes)
- {
- /* we just created a new one, or are the first opener, lets set it size */
- if( ftruncate(smb_shm_fd, size) <0)
- {
- DEBUG(0,("ERROR smb_shm_open : ftruncate failed with code %s\n",strerror(errno)));
- smb_shm_unregister_process(smb_shm_processreg_name, getpid());
- smb_shm_global_unlock();
- close(smb_shm_fd);
- return False;
- }
-
- /* paranoia */
- lseek(smb_shm_fd,0,SEEK_SET);
-
- filesize = size;
- }
-
- if (size != filesize )
- {
- /* the existing file has a different size and we are not the first opener.
- Since another process is still using it, we will use the file size */
- DEBUG(0,("WARNING smb_shm_open : filesize (%d) != expected size (%d), using filesize\n",filesize,size));
- size = filesize;
- }
-
- smb_shm_header_p = (struct SmbShmHeader *)mmap( NULL, size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, smb_shm_fd, 0);
- /* WARNING, smb_shm_header_p can be different for different processes mapping the same file ! */
- if (smb_shm_header_p == (struct SmbShmHeader *)(-1))
- {
- DEBUG(0,("ERROR smb_shm_open : mmap failed with code %s\n",strerror(errno)));
- smb_shm_unregister_process(smb_shm_processreg_name, getpid());
- smb_shm_global_unlock();
- close(smb_shm_fd);
- return False;
- }
-
-
- if (created_new || !other_processes)
- {
- smb_shm_initialize(size);
- /* Create the hash buckets for the share file entries. */
- smb_shm_create_hash_table( lp_shmem_hash_size() );
- }
- else if (!smb_shm_validate_header(size) )
- {
- /* existing file is corrupt, samba admin should remove it by hand */
- DEBUG(0,("ERROR smb_shm_open : corrupt shared mem file, remove it manually\n"));
- munmap((caddr_t)smb_shm_header_p, size);
- smb_shm_unregister_process(smb_shm_processreg_name, getpid());
- smb_shm_global_unlock();
- close(smb_shm_fd);
- return False;
- }
-
- smb_shm_global_unlock();
- return True;
-
-}
-
-
-BOOL smb_shm_close( void )
-{
-
- if(smb_shm_initialize_called == False)
- return True;
-
- DEBUG(5,("smb_shm_close\n"));
- if(smb_shm_times_locked > 0)
- DEBUG(0,("WARNING smb_shm_close : shmem was still locked %d times\n",smb_shm_times_locked));;
- if ((smb_shm_header_p != NULL) &&
- (munmap((caddr_t)smb_shm_header_p, smb_shm_header_p->total_size) < 0))
- {
- DEBUG(0,("ERROR smb_shm_close : munmap failed with code %s\n",strerror(errno)));
- }
-
- smb_shm_global_lock();
- DEBUG(5,("calling smb_shm_unregister_process(%s, %d)\n", smb_shm_processreg_name, getpid()));
- smb_shm_unregister_process(smb_shm_processreg_name, getpid());
- smb_shm_global_unlock();
-
- close(smb_shm_fd);
-
- smb_shm_fd = -1;
- smb_shm_processreg_name[0] = '\0';
-
- smb_shm_header_p = (struct SmbShmHeader *)0;
- smb_shm_times_locked = 0;
-
- return True;
-}
-
-smb_shm_offset_t smb_shm_alloc(int size)
-{
- unsigned num_cells ;
- struct SmbShmBlockDesc *scanner_p;
- struct SmbShmBlockDesc *prev_p;
- struct SmbShmBlockDesc *new_p;
- smb_shm_offset_t result_offset;
-
-
- if( !smb_shm_header_p )
- {
- /* not mapped yet */
- DEBUG(0,("ERROR smb_shm_alloc : shmem not mapped\n"));
- return NULL_OFFSET;
- }
-
- smb_shm_global_lock();
-
- if( !smb_shm_header_p->consistent)
- {
- DEBUG(0,("ERROR smb_shm_alloc : shmem not consistent\n"));
- smb_shm_global_unlock();
- return NULL_OFFSET;
- }
-
-
- /* calculate the number of cells */
- num_cells = (size + CellSize -1) / CellSize;
-
- /* set start of scan */
- prev_p = (struct SmbShmBlockDesc *)smb_shm_offset2addr(smb_shm_header_p->first_free_off);
- scanner_p = prev_p ;
-
- /* scan the free list to find a matching free space */
- while ( ( scanner_p != EOList_Addr ) && ( scanner_p->size < num_cells ) )
- {
- prev_p = scanner_p;
- scanner_p = (struct SmbShmBlockDesc *)smb_shm_offset2addr(scanner_p->next);
- }
-
- /* at this point scanner point to a block header or to the end of the list */
- if ( scanner_p == EOList_Addr )
- {
- DEBUG(0,("ERROR smb_shm_alloc : alloc of %d bytes failed, no free space found\n",size));
- smb_shm_global_unlock();
- return (NULL_OFFSET);
- }
-
- /* going to modify shared mem */
- smb_shm_header_p->consistent = False;
-
- /* if we found a good one : scanner == the good one */
- if ( scanner_p->size <= num_cells + 2 )
- {
- /* there is no use in making a new one, it will be too small anyway
- * we will link out scanner
- */
- if ( prev_p == scanner_p )
- {
- smb_shm_header_p->first_free_off = scanner_p->next ;
- }
- else
- {
- prev_p->next = scanner_p->next ;
- }
- smb_shm_header_p->statistics.cells_free -= scanner_p->size;
- smb_shm_header_p->statistics.cells_used += scanner_p->size;
- }
- else
- {
- /* Make a new one */
- new_p = scanner_p + 1 + num_cells;
- new_p->size = scanner_p->size - num_cells - 1;
- new_p->next = scanner_p->next;
- scanner_p->size = num_cells;
- scanner_p->next = smb_shm_addr2offset(new_p);
-
- if ( prev_p != scanner_p )
- {
- prev_p->next = smb_shm_addr2offset(new_p) ;
- }
- else
- {
- smb_shm_header_p->first_free_off = smb_shm_addr2offset(new_p) ;
- }
- smb_shm_header_p->statistics.cells_free -= num_cells+1;
- smb_shm_header_p->statistics.cells_used += num_cells;
- smb_shm_header_p->statistics.cells_system += 1;
- }
-
- result_offset = smb_shm_addr2offset( &(scanner_p[1]) );
- scanner_p->next = SMB_SHM_NOT_FREE_OFF ;
-
- /* end modification of shared mem */
- smb_shm_header_p->consistent = True;
-
- DEBUG(6,("smb_shm_alloc : request for %d bytes, allocated %d bytes at offset %d\n",size,scanner_p->size*CellSize,result_offset ));
-
- smb_shm_global_unlock();
- return ( result_offset );
-}
-
-
-
-BOOL smb_shm_free(smb_shm_offset_t offset)
-{
- struct SmbShmBlockDesc *header_p ; /* pointer to header of block to free */
- struct SmbShmBlockDesc *scanner_p ; /* used to scan the list */
- struct SmbShmBlockDesc *prev_p ; /* holds previous in the list */
-
- if( !smb_shm_header_p )
- {
- /* not mapped yet */
- DEBUG(0,("ERROR smb_shm_free : shmem not mapped\n"));
- return False;
- }
-
- smb_shm_global_lock();
-
- if( !smb_shm_header_p->consistent)
- {
- DEBUG(0,("ERROR smb_shm_free : shmem not consistent\n"));
- smb_shm_global_unlock();
- return False;
- }
-
- header_p = ( (struct SmbShmBlockDesc *)smb_shm_offset2addr(offset) - 1); /* make pointer to header of block */
-
- if (header_p->next != SMB_SHM_NOT_FREE_OFF)
- {
- DEBUG(0,("ERROR smb_shm_free : bad offset (%d)\n",offset));
- smb_shm_global_unlock();
- return False;
- }
-
- /* find a place in the free_list to put the header in */
-
- /* set scanner and previous pointer to start of list */
- prev_p = (struct SmbShmBlockDesc *)smb_shm_offset2addr(smb_shm_header_p->first_free_off);
- scanner_p = prev_p ;
-
- while ( ( scanner_p != EOList_Addr) && (scanner_p < header_p) ) /* while we didn't scan past its position */
- {
- prev_p = scanner_p ;
- scanner_p = (struct SmbShmBlockDesc *)smb_shm_offset2addr(scanner_p->next);
- }
-
- smb_shm_header_p->consistent = False;
-
- DEBUG(6,("smb_shm_free : freeing %d bytes at offset %d\n",header_p->size*CellSize,offset));
-
- if ( scanner_p == prev_p )
- {
- smb_shm_header_p->statistics.cells_free += header_p->size;
- smb_shm_header_p->statistics.cells_used -= header_p->size;
-
- /* we must free it at the beginning of the list */
- smb_shm_header_p->first_free_off = smb_shm_addr2offset(header_p); /* set the free_list_pointer to this block_header */
-
- /* scanner is the one that was first in the list */
- header_p->next = smb_shm_addr2offset(scanner_p);
- smb_shm_solve_neighbors( header_p ); /* if neighbors then link them */
-
- smb_shm_header_p->consistent = True;
- smb_shm_global_unlock();
- return True;
- }
- else
- {
- smb_shm_header_p->statistics.cells_free += header_p->size;
- smb_shm_header_p->statistics.cells_used -= header_p->size;
-
- prev_p->next = smb_shm_addr2offset(header_p);
- header_p->next = smb_shm_addr2offset(scanner_p);
- smb_shm_solve_neighbors(header_p) ;
- smb_shm_solve_neighbors(prev_p) ;
-
- smb_shm_header_p->consistent = True;
- smb_shm_global_unlock();
- return True;
- }
-}
-
-smb_shm_offset_t smb_shm_get_userdef_off(void)
-{
- if (!smb_shm_header_p)
- return NULL_OFFSET;
- else
- return smb_shm_header_p->userdef_off;
-}
-
-BOOL smb_shm_set_userdef_off(smb_shm_offset_t userdef_off)
-{
- if (!smb_shm_header_p)
- return False;
- else
- smb_shm_header_p->userdef_off = userdef_off;
- return True;
-}
-
-void *smb_shm_offset2addr(smb_shm_offset_t offset)
-{
- if (offset == NULL_OFFSET )
- return (void *)(0);
-
- if (!smb_shm_header_p)
- return (void *)(0);
-
- return (void *)((char *)smb_shm_header_p + offset );
-}
-
-smb_shm_offset_t smb_shm_addr2offset(void *addr)
-{
- if (!addr)
- return NULL_OFFSET;
-
- if (!smb_shm_header_p)
- return NULL_OFFSET;
-
- return (smb_shm_offset_t)((char *)addr - (char *)smb_shm_header_p);
-}
-
-/*******************************************************************
- Lock a particular hash bucket entry.
- ******************************************************************/
-
-BOOL smb_shm_lock_hash_entry( unsigned int entry)
-{
- int start = (smb_shm_header_p->userdef_off + (entry * sizeof(smb_shm_offset_t)));
-
- if (smb_shm_fd < 0)
- {
- DEBUG(0,("ERROR smb_shm_lock_hash_entry : bad smb_shm_fd (%d)\n",smb_shm_fd));
- return False;
- }
-
- if(entry >= lp_shmem_hash_size())
- {
- DEBUG(0,("ERROR smb_shm_lock_hash_entry : hash entry size too big (%d)\n", entry));
- return False;
- }
-
- /* Do an exclusive wait lock on the 4 byte region mapping into this entry */
- if (fcntl_lock(smb_shm_fd, F_SETLKW, start, sizeof(smb_shm_offset_t), F_WRLCK) == False)
- {
- DEBUG(0,("ERROR smb_shm_lock_hash_entry : fcntl_lock failed with code %s\n",strerror(errno)));
- return False;
- }
-
- DEBUG(9,("smb_shm_lock_hash_entry: locked hash bucket %d\n", entry));
- return True;
-}
-
-/*******************************************************************
- Unlock a particular hash bucket entry.
- ******************************************************************/
-
-BOOL smb_shm_unlock_hash_entry( unsigned int entry )
-{
- int start = (smb_shm_header_p->userdef_off + (entry * sizeof(smb_shm_offset_t)));
-
- if (smb_shm_fd < 0)
- {
- DEBUG(0,("ERROR smb_shm_unlock_hash_entry : bad smb_shm_fd (%d)\n",smb_shm_fd));
- return False;
- }
-
- if(entry >= lp_shmem_hash_size())
- {
- DEBUG(0,("ERROR smb_shm_unlock_hash_entry : hash entry size too big (%d)\n", entry));
- return False;
- }
-
- /* Do a wait lock on the 4 byte region mapping into this entry */
- if (fcntl_lock(smb_shm_fd, F_SETLKW, start, sizeof(smb_shm_offset_t), F_UNLCK) == False)
- {
- DEBUG(0,("ERROR smb_shm_unlock_hash_entry : fcntl_lock failed with code %s\n",strerror(errno)));
- return False;
- }
-
- DEBUG(9,("smb_shm_unlock_hash_entry: unlocked hash bucket %d\n", entry));
- return True;
-}
-
-/*******************************************************************
- Gather statistics on shared memory usage.
- ******************************************************************/
-
-BOOL smb_shm_get_usage(int *bytes_free,
- int *bytes_used,
- int *bytes_overhead)
-{
- if( !smb_shm_header_p )
- {
- /* not mapped yet */
- DEBUG(0,("ERROR smb_shm_free : shmem not mapped\n"));
- return False;
- }
- *bytes_free = smb_shm_header_p->statistics.cells_free * CellSize;
- *bytes_used = smb_shm_header_p->statistics.cells_used * CellSize;
- *bytes_overhead = smb_shm_header_p->statistics.cells_system * CellSize + AlignedHeaderSize;
-
- return True;
-}
-
-#else /* FAST_SHARE_MODES */
- int shmem_dummy_procedure(void)
-{return 0;}
-#endif /* FAST_SHARE_MODES */
diff --git a/source/lsaparse.c b/source/lsaparse.c
deleted file mode 100644
index 9ea6f566b23..00000000000
--- a/source/lsaparse.c
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Samba utility functions
- Copyright (C) Luke Leighton 1996 - 1997 Paul Ashton 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.
-*/
-
-#include "includes.h"
-
-extern int DEBUGLEVEL;
-
-
-/*******************************************************************
-reads or writes an LSA_R_OPEN_POL structure.
-********************************************************************/
-char* lsa_io_r_open_pol(BOOL io, LSA_R_OPEN_POL *r_p, char *q, char *base, int align)
-{
- if (r_p == NULL) return NULL;
-
- q = smb_io_pol_hnd(io, &(r_p->pol), q, base, align);
-
- RW_IVAL(io, q, r_p->status, 0); q += 4;
-
- return q;
-}
-
-/*******************************************************************
-reads or writes an LSA_Q_QUERY_INFO structure.
-********************************************************************/
-char* lsa_io_q_query(BOOL io, LSA_Q_QUERY_INFO *q_q, char *q, char *base, int align)
-{
- if (q_q == NULL) return NULL;
-
- q = smb_io_pol_hnd(io, &(q_q->pol), q, base, align);
-
- RW_SVAL(io, q, q_q->info_class, 0); q += 2;
-
- return q;
-}
-
-/*******************************************************************
-reads or writes an LSA_Q_QUERY_INFO structure.
-********************************************************************/
-char* lsa_io_r_query(BOOL io, LSA_R_QUERY_INFO *r_q, char *q, char *base, int align)
-{
- if (r_q == NULL) return NULL;
-
- RW_IVAL(io, q, r_q->undoc_buffer, 0); q += 4;
-
- if (r_q->undoc_buffer != 0)
- {
- RW_SVAL(io, q, r_q->info_class, 0); q += 2;
-
- switch (r_q->info_class)
- {
- case 3:
- {
- q = smb_io_dom_query_3(io, &(r_q->dom.id3), q, base, align);
- break;
- }
- case 5:
- {
- q = smb_io_dom_query_5(io, &(r_q->dom.id3), q, base, align);
- break;
- }
- default:
- {
- /* PANIC! */
- break;
- }
- }
- }
-
- RW_IVAL(io, q, r_q->status, 0); q += 4;
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-char* lsa_io_q_lookup_sids(BOOL io, LSA_Q_LOOKUP_SIDS *q_s, char *q, char *base, int align)
-{
- int i;
-
- if (q_s == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- q = smb_io_pol_hnd(io, &(q_s->pol_hnd), q, base, align); /* policy handle */
-
- RW_IVAL(io, q, q_s->num_entries, 0); q += 4;
- RW_IVAL(io, q, q_s->buffer_dom_sid, 0); q += 4; /* undocumented domain SID buffer pointer */
- RW_IVAL(io, q, q_s->buffer_dom_name, 0); q += 4; /* undocumented domain name buffer pointer */
-
- for (i = 0; i < q_s->num_entries; i++)
- {
- RW_IVAL(io, q, q_s->buffer_lookup_sids[i], 0); q += 4; /* undocumented domain SID pointers to be looked up. */
- }
-
- for (i = 0; i < q_s->num_entries; i++)
- {
- q = smb_io_dom_sid(io, &(q_s->dom_sids[i]), q, base, align); /* domain SIDs to be looked up. */
- }
-
- RW_PCVAL(io, q, q_s->undoc, 16); q += 16; /* completely undocumented 16 bytes */
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-char* lsa_io_r_lookup_sids(BOOL io, LSA_R_LOOKUP_SIDS *r_s, char *q, char *base, int align)
-{
- int i;
-
- if (r_s == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- q = smb_io_dom_r_ref(io, &(r_s->dom_ref), q, base, align); /* domain reference info */
-
- RW_IVAL(io, q, r_s->num_entries, 0); q += 4;
- RW_IVAL(io, q, r_s->undoc_buffer, 0); q += 4;
- RW_IVAL(io, q, r_s->num_entries2, 0); q += 4;
-
- for (i = 0; i < r_s->num_entries2; i++)
- {
- q = smb_io_dom_sid2(io, &(r_s->dom_sid[i]), q, base, align); /* domain SIDs being looked up */
- }
-
- RW_IVAL(io, q, r_s->num_entries3, 0); q += 4;
-
- RW_IVAL(io, q, r_s->status, 0); q += 4;
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-char* lsa_io_q_lookup_rids(BOOL io, LSA_Q_LOOKUP_RIDS *q_r, char *q, char *base, int align)
-{
- int i;
-
- if (q_r == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- q = smb_io_pol_hnd(io, &(q_r->pol_hnd), q, base, align); /* policy handle */
-
- RW_IVAL(io, q, q_r->num_entries, 0); q += 4;
- RW_IVAL(io, q, q_r->num_entries2, 0); q += 4;
- RW_IVAL(io, q, q_r->buffer_dom_sid, 0); q += 4; /* undocumented domain SID buffer pointer */
- RW_IVAL(io, q, q_r->buffer_dom_name, 0); q += 4; /* undocumented domain name buffer pointer */
-
- for (i = 0; i < q_r->num_entries; i++)
- {
- q = smb_io_dom_name(io, &(q_r->lookup_name[i]), q, base, 0); /* names to be looked up */
- }
-
- RW_PCVAL(io, q, q_r->undoc, UNKNOWN_LEN); q += UNKNOWN_LEN; /* completely undocumented bytes of unknown length */
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-char* lsa_io_r_lookup_rids(BOOL io, LSA_R_LOOKUP_RIDS *r_r, char *q, char *base, int align)
-{
- int i;
-
- if (r_r == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- q = smb_io_dom_r_ref(io, &(r_r->dom_ref), q, base, align); /* domain reference info */
-
- RW_IVAL(io, q, r_r->num_entries, 0); q += 4;
- RW_IVAL(io, q, r_r->undoc_buffer, 0); q += 4;
- RW_IVAL(io, q, r_r->num_entries2, 0); q += 4;
-
- for (i = 0; i < r_r->num_entries2; i++)
- {
- q = smb_io_dom_rid2(io, &(r_r->dom_rid[i]), q, base, align); /* domain RIDs being looked up */
- }
-
- RW_IVAL(io, q, r_r->num_entries3, 0); q += 4;
-
- RW_IVAL(io, q, r_r->status, 0); q += 4;
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-char* lsa_io_q_req_chal(BOOL io, LSA_Q_REQ_CHAL *q_c, char *q, char *base, int align)
-{
- if (q_c == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- q = smb_io_unistr2(io, &(q_c->uni_logon_srv), q, base, align); /* logon server unicode string */
- q = smb_io_unistr2(io, &(q_c->uni_logon_clnt), q, base, align); /* logon client unicode string */
- q = smb_io_chal(io, &(q_c->clnt_chal), q, base, align); /* client challenge */
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-char* lsa_io_r_req_chal(BOOL io, LSA_R_REQ_CHAL *r_c, char *q, char *base, int align)
-{
- if (r_c == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- q = smb_io_chal(io, &(r_c->srv_chal), q, base, align); /* server challenge */
-
- RW_IVAL(io, q, r_c->status, 0); q += 4;
-
- return q;
-}
-
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-char* lsa_io_q_auth2(BOOL io, LSA_Q_AUTH_2 *q_a, char *q, char *base, int align)
-{
- if (q_a == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- q = smb_io_log_info (io, &(q_a->clnt_id), q, base, align); /* client identification info */
- q = smb_io_chal (io, &(q_a->clnt_chal), q, base, align); /* client-calculated credentials */
- q = smb_io_neg_flags(io, &(q_a->clnt_flgs), q, base, align);
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-char* lsa_io_r_auth_2(BOOL io, LSA_R_AUTH_2 *r_a, char *q, char *base, int align)
-{
- if (r_a == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- q = smb_io_chal (io, &(r_a->srv_chal), q, base, align); /* server challenge */
- q = smb_io_neg_flags(io, &(r_a->srv_flgs), q, base, align);
-
- RW_IVAL(io, q, r_a->status, 0); q += 4;
-
- return q;
-}
-
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-char* lsa_io_q_srv_pwset(BOOL io, LSA_Q_SRV_PWSET *q_s, char *q, char *base, int align)
-{
- if (q_s == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- q = smb_io_clnt_info(io, &(q_s->clnt_id), q, base, align); /* client identification/authentication info */
- RW_PCVAL(io, q, q_s->pwd, 16); q += 16; /* new password - undocumented */
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-char* lsa_io_r_srv_pwset(BOOL io, LSA_R_SRV_PWSET *r_s, char *q, char *base, int align)
-{
- if (r_s == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- q = smb_io_cred(io, &(r_s->srv_cred), q, base, align); /* server challenge */
-
- RW_IVAL(io, q, r_s->status, 0); q += 4;
-
- return q;
-}
-
-/* LSA_USER_INFO */
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-char* lsa_io_user_info(BOOL io, LSA_USER_INFO *usr, char *q, char *base, int align)
-{
- int i;
-
- if (usr == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- RW_IVAL(io, q, usr->undoc_buffer, 0); q += 4;
-
- q = smb_io_time(io, &(usr->logon_time) , q, base, align); /* logon time */
- q = smb_io_time(io, &(usr->logoff_time) , q, base, align); /* logoff time */
- q = smb_io_time(io, &(usr->kickoff_time) , q, base, align); /* kickoff time */
- q = smb_io_time(io, &(usr->pass_last_set_time) , q, base, align); /* password last set time */
- q = smb_io_time(io, &(usr->pass_can_change_time) , q, base, align); /* password can change time */
- q = smb_io_time(io, &(usr->pass_must_change_time), q, base, align); /* password must change time */
-
- q = smb_io_unihdr(io, &(usr->hdr_user_name) , q, base, align); /* username unicode string header */
- q = smb_io_unihdr(io, &(usr->hdr_full_name) , q, base, align); /* user's full name unicode string header */
- q = smb_io_unihdr(io, &(usr->hdr_logon_script), q, base, align); /* logon script unicode string header */
- q = smb_io_unihdr(io, &(usr->hdr_profile_path), q, base, align); /* profile path unicode string header */
- q = smb_io_unihdr(io, &(usr->hdr_home_dir) , q, base, align); /* home directory unicode string header */
- q = smb_io_unihdr(io, &(usr->hdr_dir_drive) , q, base, align); /* home directory drive unicode string header */
-
- RW_SVAL(io, q, usr->logon_count , 0); q += 2; /* logon count */
- RW_SVAL(io, q, usr->bad_pw_count, 0); q += 2; /* bad password count */
-
- RW_IVAL(io, q, usr->user_id , 0); q += 4; /* User ID */
- RW_IVAL(io, q, usr->group_id , 0); q += 4; /* Group ID */
- RW_IVAL(io, q, usr->num_groups , 0); q += 4; /* num groups */
- RW_IVAL(io, q, usr->buffer_groups, 0); q += 4; /* undocumented buffer pointer to groups. */
- RW_IVAL(io, q, usr->user_flgs , 0); q += 4; /* user flags */
-
- RW_PCVAL(io, q, usr->sess_key, 16); q += 16; /* unused user session key */
-
- q = smb_io_unihdr(io, &(usr->hdr_logon_srv), q, base, align); /* logon server unicode string header */
- q = smb_io_unihdr(io, &(usr->hdr_logon_dom), q, base, align); /* logon domain unicode string header */
-
- RW_IVAL(io, q, usr->buffer_dom_id, 0); q += 4; /* undocumented logon domain id pointer */
- RW_PCVAL(io, q, usr->padding, 40); q += 40; /* unused padding bytes? */
-
- RW_IVAL(io, q, usr->num_other_sids, 0); q += 4; /* 0 - num_sids */
- RW_IVAL(io, q, usr->buffer_other_sids, 0); q += 4; /* NULL - undocumented pointer to SIDs. */
-
- q = smb_io_unistr2(io, &(usr->uni_user_name) , q, base, align); /* username unicode string */
- q = smb_io_unistr2(io, &(usr->uni_full_name) , q, base, align); /* user's full name unicode string */
- q = smb_io_unistr2(io, &(usr->uni_logon_script), q, base, align); /* logon script unicode string */
- q = smb_io_unistr2(io, &(usr->uni_profile_path), q, base, align); /* profile path unicode string */
- q = smb_io_unistr2(io, &(usr->uni_home_dir) , q, base, align); /* home directory unicode string */
- q = smb_io_unistr2(io, &(usr->uni_dir_drive) , q, base, align); /* home directory drive unicode string */
-
- RW_IVAL(io, q, usr->num_groups2, 0); q += 4; /* num groups */
- for (i = 0; i < usr->num_groups2; i++)
- {
- q = smb_io_gid(io, &(usr->gids[i]), q, base, align); /* group info */
- }
-
- q = smb_io_unistr2(io, &( usr->uni_logon_srv), q, base, align); /* logon server unicode string */
- q = smb_io_unistr2(io, &( usr->uni_logon_dom), q, base, align); /* logon domain unicode string */
-
- q = smb_io_dom_sid(io, &(usr->dom_sid), q, base, align); /* domain SID */
-
- for (i = 0; i < usr->num_other_sids; i++)
- {
- q = smb_io_dom_sid(io, &(usr->other_sids[i]), q, base, align); /* other domain SIDs */
- }
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-char* lsa_io_q_sam_logon(BOOL io, LSA_Q_SAM_LOGON *q_l, char *q, char *base, int align)
-{
- if (q_l == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- q = smb_io_sam_info(io, &(q_l->sam_id), q, base, align); /* domain SID */
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-char* lsa_io_r_sam_logon(BOOL io, LSA_R_SAM_LOGON *r_l, char *q, char *base, int align)
-{
- if (r_l == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- RW_IVAL(io, q, r_l->buffer_creds, 0); q += 4; /* undocumented buffer pointer */
- q = smb_io_cred(io, &(r_l->srv_creds), q, base, align); /* server credentials. server time stamp appears to be ignored. */
-
- RW_IVAL(io, q, r_l->buffer_user, 0); q += 4;
- if (r_l->buffer_user != 0)
- {
- q = lsa_io_user_info(io, r_l->user, q, base, align);
- }
-
- RW_IVAL(io, q, r_l->auth_resp, 0); q += 4; /* 1 - Authoritative response; 0 - Non-Auth? */
-
- RW_IVAL(io, q, r_l->status, 0); q += 4;
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-char* lsa_io_q_sam_logoff(BOOL io, LSA_Q_SAM_LOGOFF *q_l, char *q, char *base, int align)
-{
- if (q_l == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- q = smb_io_sam_info(io, &(q_l->sam_id), q, base, align); /* domain SID */
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-char* lsa_io_r_sam_logoff(BOOL io, LSA_R_SAM_LOGOFF *r_l, char *q, char *base, int align)
-{
- if (r_l == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- RW_IVAL(io, q, r_l->buffer_creds, 0); q += 4; /* undocumented buffer pointer */
- q = smb_io_cred(io, &(r_l->srv_creds), q, base, align); /* server credentials. server time stamp appears to be ignored. */
-
- RW_IVAL(io, q, r_l->status, 0); q += 4;
-
- return q;
-}
-
-#if 0
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
- char* lsa_io_(BOOL io, *, char *q, char *base, int align)
-{
- if (== NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- RW_IVAL(io, q, , 0); q += 4;
-
- return q;
-}
-#endif
diff --git a/source/nameannounce.c b/source/nameannounce.c
deleted file mode 100644
index d3344ebd478..00000000000
--- a/source/nameannounce.c
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1997
-
- SMB Version handling
- Copyright (C) John H Terpstra 1995-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.
-
- Revision History:
-
- 14 jan 96: lkcl@pires.co.uk
- added multiple workgroup domain master support
-
-*/
-
-#include "includes.h"
-
-#define TEST_CODE
-
-extern int DEBUGLEVEL;
-extern BOOL CanRecurse;
-
-extern struct in_addr ipzero;
-
-extern pstring myname;
-extern fstring myworkgroup;
-extern char **my_netbios_names;
-
-extern int ClientDGRAM;
-extern int ClientNMB;
-
-/* this is our domain/workgroup/server database */
-extern struct subnet_record *subnetlist;
-
-extern int updatecount;
-extern int workgroup_count;
-
-extern struct in_addr wins_ip;
-
-extern pstring scope;
-
-/****************************************************************************
- send a announce request to the local net
- **************************************************************************/
-void announce_request(struct work_record *work, struct in_addr ip)
-{
- pstring outbuf;
- char *p;
-
- if (!work) return;
-
- work->needannounce = True;
-
- DEBUG(2,("sending announce request to %s for workgroup %s\n",
- inet_ntoa(ip),work->work_group));
-
- bzero(outbuf,sizeof(outbuf));
- p = outbuf;
- CVAL(p,0) = ANN_AnnouncementRequest;
- p++;
-
- CVAL(p,0) = work->token; /* (local) unique workgroup token id */
- p++;
- StrnCpy(p,myname,16);
- strupper(p);
- p = skip_string(p,1);
-
- /* XXXX note: if we sent the announcement request to 0x1d instead
- of 0x1e, then we could get the master browser to announce to
- us instead of the members of the workgroup. wha-hey! */
-
- send_mailslot_reply(False, BROWSE_MAILSLOT,ClientDGRAM,
- outbuf,PTR_DIFF(p,outbuf),
- myname,work->work_group,0x20,0x1e,ip,*iface_ip(ip));
-}
-
-
-/****************************************************************************
- request an announcement
- **************************************************************************/
-void do_announce_request(char *info, char *to_name, int announce_type,
- int from,
- int to, struct in_addr dest_ip)
-{
- pstring outbuf;
- char *p;
-
- bzero(outbuf,sizeof(outbuf));
- p = outbuf;
- CVAL(p,0) = announce_type;
- p++;
-
- DEBUG(2,("sending announce type %d: info %s to %s - server %s(%x)\n",
- announce_type, info, inet_ntoa(dest_ip),to_name,to));
-
- StrnCpy(p,info,16);
- strupper(p);
- p = skip_string(p,1);
-
- send_mailslot_reply(False,BROWSE_MAILSLOT,ClientDGRAM,
- outbuf,PTR_DIFF(p,outbuf),
- myname,to_name,from,to,dest_ip,*iface_ip(dest_ip));
-}
-
-
-/****************************************************************************
- find a server responsible for a workgroup, and sync browse lists
- control ends up back here via response_name_query.
- **************************************************************************/
-void sync_server(enum state_type state, char *serv_name, char *work_name,
- int name_type,
- struct subnet_record *d,
- struct in_addr ip)
-{
- /* with a domain master we can get the whole list (not local only list) */
- BOOL local_only = (state != NAME_STATUS_DOM_SRV_CHK);
-
- add_browser_entry(serv_name, name_type, work_name, 0, d, ip, local_only);
-
- if (state == NAME_STATUS_DOM_SRV_CHK)
- {
- /* announce ourselves as a master browser to serv_name */
- do_announce_request(myname, serv_name, ANN_MasterAnnouncement,
- 0x20, 0, ip);
- }
-}
-
-
-/****************************************************************************
- send a host announcement packet
- **************************************************************************/
-void do_announce_host(int command,
- char *from_name, int from_type, struct in_addr from_ip,
- char *to_name , int to_type , struct in_addr to_ip,
- time_t announce_interval,
- char *server_name, int server_type, char *server_comment)
-{
- pstring outbuf;
- char *p;
-
- bzero(outbuf,sizeof(outbuf));
- p = outbuf+1;
-
- /* command type */
- CVAL(outbuf,0) = command;
-
- /* announcement parameters */
- CVAL(p,0) = updatecount;
- SIVAL(p,1,announce_interval*1000); /* ms - despite the spec */
-
- StrnCpy(p+5,server_name,16);
- strupper(p+5);
-
- CVAL(p,21) = lp_major_announce_version(); /* major version */
- CVAL(p,22) = lp_minor_announce_version(); /* minor version */
-
- SIVAL(p,23,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
- /* browse version: got from NT/AS 4.00 - Value defined in smb.h (JHT)*/
- SSVAL(p,27,BROWSER_ELECTION_VERSION);
- SSVAL(p,29,BROWSER_CONSTANT); /* browse signature */
-
- pstrcpy(p+31,server_comment);
- p += 31;
- p = skip_string(p,1);
-
- debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
-
- /* send the announcement */
- send_mailslot_reply(False,BROWSE_MAILSLOT,ClientDGRAM,outbuf,
- PTR_DIFF(p,outbuf),
- from_name, to_name,
- from_type, to_type,
- to_ip, from_ip);
-}
-
-
-/****************************************************************************
-announce all samba's server entries as 'gone'.
-****************************************************************************/
-void announce_my_servers_removed(void)
-{
- struct subnet_record *d;
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
- {
- struct work_record *work;
- for (work = d->workgrouplist; work; work = work->next)
- {
- struct server_record *s;
- for (s = work->serverlist; s; s = s->next)
- {
- if (!is_myname(s->serv.name)) continue;
- announce_server(d, work, s->serv.name, s->serv.comment, 0, 0);
- }
- }
- }
-}
-
-
-/****************************************************************************
- announce a server entry
- ****************************************************************************/
-void announce_server(struct subnet_record *d, struct work_record *work,
- char *name, char *comment, time_t ttl, int server_type)
-{
- /* domain type cannot have anything in it that might confuse
- a client into thinking that the domain is in fact a server.
- (SV_TYPE_SERVER_UNIX, for example)
- */
- uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT;
- BOOL wins_iface = ip_equal(d->bcast_ip, wins_ip);
-
- if(wins_iface)
- {
- DEBUG(0,("announce_server: error - announcement requested on WINS \
-interface for workgroup %s, name %s\n", work->work_group, name));
- return;
- }
-
- /* Only do domain announcements if we are a master and it's
- our name we're being asked to announce. */
- if (AM_MASTER(work) && strequal(myname,name))
- {
- DEBUG(3,("sending local master announce to %s for %s(1e)\n",
- inet_ntoa(d->bcast_ip),work->work_group));
-
- do_announce_host(ANN_LocalMasterAnnouncement,
- name , 0x00, d->myip,
- work->work_group, 0x1e, d->bcast_ip,
- ttl,
- name, server_type, comment);
-
- DEBUG(3,("sending domain announce to %s for %s\n",
- inet_ntoa(d->bcast_ip),work->work_group));
-
- /* XXXX should we do a domain-announce-kill? */
- if (server_type != 0)
- {
- do_announce_host(ANN_DomainAnnouncement,
- name , 0x00, d->myip,
- MSBROWSE, 0x01, d->bcast_ip,
- ttl,
- work->work_group, server_type ? domain_type : 0,
- name);
- }
- }
- else
- {
- DEBUG(3,("sending host announce to %s for %s(1d)\n",
- inet_ntoa(d->bcast_ip),work->work_group));
-
- do_announce_host(ANN_HostAnnouncement,
- name , 0x00, d->myip,
- work->work_group, 0x1d, d->bcast_ip,
- ttl,
- name, server_type, comment);
- }
-}
-
-/****************************************************************************
- construct a host announcement unicast
- **************************************************************************/
-void announce_host(time_t t)
-{
- struct subnet_record *d;
- pstring comment;
- char *my_name;
-
- StrnCpy(comment, lp_serverstring(), 43);
-
- my_name = *myname ? myname : "NoName";
-
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
- {
- struct work_record *work;
-
- for (work = d->workgrouplist; work; work = work->next)
- {
- uint32 stype = work->ServerType;
- struct server_record *s;
-
- /* must work on the code that does announcements at up to
- 30 seconds later if a master browser sends us a request
- announce.
- */
-
- if (work->needannounce) {
- /* drop back to a max 3 minute announce - this is to prevent a
- single lost packet from stuffing things up for too long */
- work->announce_interval = MIN(work->announce_interval,
- CHECK_TIME_MIN_HOST_ANNCE*60);
- work->lastannounce_time = t - (work->announce_interval+1);
- }
-
- /* announce every minute at first then progress to every 12 mins */
- if (work->lastannounce_time &&
- (t - work->lastannounce_time) < work->announce_interval)
- continue;
-
- if (work->announce_interval < CHECK_TIME_MAX_HOST_ANNCE * 60)
- work->announce_interval += 60;
-
- work->lastannounce_time = t;
-
- for (s = work->serverlist; s; s = s->next) {
- if (is_myname(s->serv.name)) {
- /* If we are any kind of browser or logon server, only
- announce it for our primary name, not our aliases. */
- if(!strequal(myname, s->serv.name))
- stype &= ~(SV_TYPE_MASTER_BROWSER|SV_TYPE_POTENTIAL_BROWSER|
- SV_TYPE_DOMAIN_MASTER|SV_TYPE_DOMAIN_MEMBER);
- announce_server(d,work,s->serv.name,comment,
- work->announce_interval,stype);
- }
- }
-
- if (work->needannounce)
- {
- work->needannounce = False;
- break;
- /* sorry: can't do too many announces. do some more later */
- }
- }
- }
-}
-
-/* Announce timer. Moved into global static so it can be reset
- when a machine becomes a master browser. */
-static time_t announce_timer_last=0;
-
-/****************************************************************************
- Reset the announce_timer so that a master browser announce will be done
- immediately.
- ****************************************************************************/
-
-void reset_announce_timer()
-{
- announce_timer_last = time(NULL) - (CHECK_TIME_MST_ANNOUNCE * 60);
-}
-
-/****************************************************************************
- announce myself as a master to all other domain master browsers.
-
- this actually gets done in search_and_sync_workgroups() via the
- NAME_QUERY_DOM_SRV_CHK command, if there is a response from the
- name query initiated here. see response_name_query()
- **************************************************************************/
-void announce_master(time_t t)
-{
- struct subnet_record *d;
- struct work_record *work;
- BOOL am_master = False; /* are we a master of some sort? :-) */
-
- if (!announce_timer_last) announce_timer_last = t;
- if (t-announce_timer_last < CHECK_TIME_MST_ANNOUNCE * 60)
- {
- DEBUG(10,("announce_master: t (%d) - last(%d) < %d\n",
- t, announce_timer_last, CHECK_TIME_MST_ANNOUNCE * 60 ));
- return;
- }
-
- if(wins_subnet == NULL)
- {
- DEBUG(10,("announce_master: no wins subnet, ignoring.\n"));
- return;
- }
-
- announce_timer_last = t;
-
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
- {
- for (work = d->workgrouplist; work; work = work->next)
- {
- if (AM_MASTER(work))
- {
- am_master = True;
- DEBUG(4,( "announce_master: am_master = %d for \
-workgroup %s\n", am_master, work->work_group));
- }
- }
- }
-
- if (!am_master) return; /* only proceed if we are a master browser */
-
- /* Note that we don't do this if we are domain master browser
- and that we *only* do this on the WINS subnet. */
-
- /* Try and find our workgroup on the WINS subnet */
- work = find_workgroupstruct(wins_subnet, myworkgroup, False);
-
- if (work)
- {
- char *name;
- int type;
-
- {
- /* assume that the domain master browser we want to sync
- with is our own domain.
- */
- name = work->work_group;
- type = 0x1b;
- }
-
- /* check the existence of a dmb for this workgroup, and if
- one exists at the specified ip, sync with it and announce
- ourselves as a master browser to it
- */
-
- if (!lp_wins_support() && *lp_wins_server() )
- {
- DEBUG(4, ("Local Announce: find %s<%02x> from WINS server %s\n",
- name, type, lp_wins_server()));
-
- queue_netbios_pkt_wins(ClientNMB,
- NMB_QUERY,NAME_QUERY_DOM_SRV_CHK,
- name, type, 0,0,0,
- work->work_group,NULL,
- ipzero, ipzero);
- }
- else if(lp_wins_support())
- {
- /* We are the WINS server - query ourselves for the dmb name. */
-
- struct nmb_name netb_name;
- struct name_record *nr = 0;
-
- d = NULL;
-
- make_nmb_name(&netb_name, name, type, scope);
-
- if ((nr = find_name_search(&d, &netb_name, FIND_WINS, ipzero)) == 0)
- {
- DEBUG(0, ("announce_master: unable to find domain master browser for workgroup %s \
-in our own WINS database.\n", work->work_group));
- return;
- }
-
- /* Check that this isn't one of our addresses (ie. we are not domain master
- ourselves) */
- if(ismyip(nr->ip_flgs[0].ip) || ip_equal(nr->ip_flgs[0].ip, ipzero))
- {
- DEBUG(4, ("announce_master: domain master ip found (%s) for workgroup %s \
-is one of our interfaces.\n", work->work_group, inet_ntoa(nr->ip_flgs[0].ip) ));
- return;
- }
-
- /* Issue a NAME_STATUS_DOM_SRV_CHK immediately - short circuit the
- NAME_QUERY_DOM_SRV_CHK which is done only if we are talking to a
- remote WINS server. */
-
- DEBUG(4, ("announce_master: doing name status for %s<%02x> to domain master ip %s \
-for workgroup %s\n", name, type, inet_ntoa(nr->ip_flgs[0].ip), work->work_group ));
-
- queue_netbios_packet(wins_subnet, ClientNMB,
- NMB_QUERY,NAME_STATUS_DOM_SRV_CHK,
- name, type, 0,0,0,
- work->work_group,NULL,
- False, False, nr->ip_flgs[0].ip, nr->ip_flgs[0].ip);
- }
-
- }
-}
-
-/****************************************************************************
- do all the "remote" announcements. These are used to put ourselves
- on a remote browse list. They are done blind, no checking is done to
- see if there is actually a browse master at the other end.
- **************************************************************************/
-void announce_remote(time_t t)
-{
- char *s,*ptr;
- static time_t last_time = 0;
- pstring s2;
- struct in_addr addr;
- char *comment,*workgroup;
- int stype = lp_default_server_announce();
-
- if (last_time && t < last_time + REMOTE_ANNOUNCE_INTERVAL)
- return;
-
- last_time = t;
-
- s = lp_remote_announce();
- if (!*s) return;
-
- comment = lp_serverstring();
- workgroup = myworkgroup;
-
- for (ptr=s; next_token(&ptr,s2,NULL); )
- {
- /* the entries are of the form a.b.c.d/WORKGROUP with
- WORKGROUP being optional */
- char *wgroup;
- int n;
-
- wgroup = strchr(s2,'/');
- if (wgroup) *wgroup++ = 0;
- if (!wgroup || !*wgroup)
- wgroup = workgroup;
-
- addr = *interpret_addr2(s2);
-
- /* Announce all our names including aliases */
- for (n=0; my_netbios_names[n]; n++)
- {
- char *name = my_netbios_names[n];
- do_announce_host(ANN_HostAnnouncement,name,0x20,*iface_ip(addr),
- wgroup,0x1e,addr,
- REMOTE_ANNOUNCE_INTERVAL,
- name,stype,comment);
- }
- }
-
-}
diff --git a/source/nameannounce.doc b/source/nameannounce.doc
deleted file mode 100644
index e04a59209a1..00000000000
--- a/source/nameannounce.doc
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- Unix SMB/Netbios documentation.
- Version 0.2
- Copyright (C) Luke Leighton Andrew Tridgell 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.
-
- Document name: nameannounce.doc
-
- Revision History:
-
- 0.0 - 02jul96 : lkcl@pires.co.uk
- created
-
- 0.1 - 22jul96 : Andrew.Tridgell@anu.edu.au
- tridge's comments on first revision
-
- 0.2 - 05aug96 : lkcl@pires.co.uk
- actioned tridge comments about pdc -> domain master
- documented NAME_QUERY_ANNOUNCE_HOST
-
-*/
-
-
-this module deals with announcements: the sending of announcement requests
-and the sending of announcements either to refresh other servers' records
-or as a response to announcement requests.
-
-
-/*************************************************************************
- announce_master()
- *************************************************************************/
-
-this function is responsible for announcing samba as a master browser
-to all known domain masters.
-
-this announcement is sent out at CHECK_TIME_MST_ANNOUNCE minute
-intervals, only if samba is a master browser on one or more of
-its local interfaces.
-
-if no domain controller has been specified (lp_domain_controller())
-samba goes through its list of servers looking for domain master
-browsers. when it finds one (other than itself) it will either
-initiate a NAME_QUERY_PDC_SRV_CHK by broadcast or with a WINS
-server. this will result in a NAME_STATUS_PDC_SRV_CHK, which
-will result in a sync browse list and an announcement
-ANN_MasterAnnounce being sent (see sync_server()).
-
-if a domain controller has been specified, samba will search for
-a domain master browser for its workgroup (either by directed
-packet or by broadcast if it cannot resolve the domain controller
-name using DNS), which results in the same action as listed above.
-
-------------
-NOTE FROM TRIDGE:
-
-PDC in the above should really be DMB (domain master browser). They
-might be separate entities.
-
-I also propose a simpler scheme :-)
-
-If a DMB is not configured with lp_domain_controller() (perhaps
-renamed to lp_domain_master()?) then just don't do master
-announcements. Remember that most peoples networks are very simple and
-don't need DMB capabilities. Those that do need them will have more
-complex network topologies and they really need to choose themselves
-which box will act as the "hub" for netbios name resolution. Doing it
-via name queries will just lead to lag and propogation delays, because
-if two parts of the net choose different DMBs then the data will be
-very slow to propoogate.
-
-If a DMB is configured then just send the master announcemnt to that
-box! Thats all that needs to be done. Just send a udp 138 packet and
-forget it. If the recipient is indeed a DMB (as it should be if the
-config file is correct) then it should initiate a browse list sync
-with us at some later time, but that is take care of by smbd and nmbd
-doesn't even need to know it happened.
-
-Additionally, if a DMB is configured we need to sync our workgroup
-list and server list with them occasionally. Note that this is only
-time a non-DMB should do a browse sync, and it should only do it with
-a DMB. Essentially WAN based netbios is just a simple star. There is a
-DMB in the centre, and the individual master browsers for each subnet
-talk to it, but never talk to each other. If they start talking to
-each other then the network load will go as the square of the number
-of machines, which will result in meltdown :-)
--------------
-
-
-/*************************************************************************
- announce_host()
- *************************************************************************/
-
-this complex-looking function is responsible for announcing samba's
-existence to other servers by broadcast. the actual announcement
-is carried out by announce_server().
-
-the time period between samba's announcement will stretch from one
-minute to twelve minutes by one minute. if samba has received an
-announce request from a master browser, then it should answer at
-any random interval between zero and thirty seconds after the
-request is received. this is to ensure that the master browser
-does not get overloaded with responses!
-
-
-/*************************************************************************
- announce_server()
- *************************************************************************/
-
-this function is responsible for sending announcement packets.
-these packets are received by other servers, which will then
-update their records accordingly: what services we have, our
-name, our comment field and our time to live (to name a few).
-
-if samba is a non-master then we need to see if there is a
-domain master (on a remote subnet) that we need to announce to
-it.
-
-if samba is not the WINS server (and it is using another
-WINS server) then we need to do a name query to the WINS
-server to ask it what the domain controller is. this is done
-using a samba 'state' NAME_QUERY_ANNOUNCE_HOST, which passes
-sufficient information on to be able to carry out the
-host announcement using a unicasted do_announce_host() if and
-when a reply comes back. if there is no reply to the name query,
-this is not necessarily an error - there may genuinely be no
-domain master currently up and running for samba's workgroup.
-
-if samba is a WINS server, then samba will need to look up the
-domain controller for its workgroup in its WINS records. an
-over-cautious samba could carry out a name query on that
-domain controller to make sure that it is alive and that samba's
-WINS records are up-to-date. in any event, it will send a unicast
-do_announce_host() to inform the domain master browser, if one
-exists, of samba's server status.
-
-if we are a master browser, then using do_announce_host() we
-must send a broadcast announcement on the local interface
-notifying members of that workgroup that we are their master
-browser, and another announcement indicating to all backup
-browsers and master browsers that we are a master browser.
-
-(note: if another master browser receives this broadcasted
-announcement and thinks that it is also the master browser
-for this workgroup, it stops being a master browser and forces
-an election).
-
-if we are not a master browser, then we send a broacast
-announcement notifying the master browser that we are a member
-of its workgroup, on the local interface.
-
-
-/*************************************************************************
- remove_my_servers()
- *************************************************************************/
-
-this function is responsible for informing other servers that
-samba is about to go down. it announces, on all subnets, that
-samba's time to live is zero and that it has no services.
-
-
-/*************************************************************************
- do_announce_host()
- *************************************************************************/
-
-this function is responsible for sending out an announcement
-MAILSLOT browse packet. it contains information such as the
-time to live, name of the server, services that the server
-offers etc.
-
-the format of this MAILSLOT browse packet is described in
-draft-heizer-cifs-v1-spec-00.txt 3.9.50.4.1 page 165-6.
-
-
-/*************************************************************************
- announce_backup()
- *************************************************************************/
-
-this function is responsible for getting master browsers and domain
-controllers to send us lists of backup servers. this is done by
-sending an ANN_GetBackupListReq browse mailslot.
-
-the local master browser, or domain master browser, should respond
-with an ANN_GetBackupListResp browse mailslot containing the list
-of backup servers.
-
---------------
-NOTE FROM TRIDGE: I don't see why nmbd should ever send one of
-these. The only reason I can see for any part of Samba sending one of
-these is if we implement it in smbclient.
-
-This packet is used to request a list of backup master browsers from
-the master browser. It is used by clients (not servers!) to spread the
-browse load over more than one server. The only server that needs to
-know what the list of backups is is the master browser, and as it is
-also responsible for generating this list it will never ask anyone
-else for it.
---------------
-
-
-/*************************************************************************
- sync_server()
- *************************************************************************/
-
-this function is responsible for initiating a sync browse list
-sequence and, if necessary, carrying out an ANN_MasterAnnouncement
-to the domain master browser (that we are also sync'ing browse lists
-with).
-
-see nameservresp.c:response_name_status_check().
-
-
-/*************************************************************************
- announce_request()
- *************************************************************************/
-
-this function is responsible for sending an announcement request to
-another server. this server should respond with an announcement.
-
-if the announce request is sent to WORKGROUP(0x1e) then members of
-the workgroup will respond (with ANN_HostAnnounce packets)
-
-if the announce request is sent to WORKGROUP(0x1d) then the master
-browser of the workgroup should respond (ANN_LocalMasterAnnounce).
-this is untested.
-
-if the announce request is sent to ^1^2__MSBROWSE__^2(0x1) then
-(and this is pure speculation), all backup browsers and master
-browsers should respond with ANN_DomainAnnounce packets.
-this is untested.
-
------------
-NOTE FROM TRIDGE:
-
-I had great trouble getting machines to actually respond to this
-packet. Either we have the format wrong or MS chose not to implement
-it.
-
-Not implementing it doesn't break anything, it just means a new master
-browser won't get a complete server list as quickly.
-
-Also note that this packet should be used as little as possible as it
-could easily cause meltdown if too many servers used it. Imagine a
-dozen samba servers on a net all sending this packet! You will get 244
-responses all within 30 seconds. now imagine 50 samba servers ....
-
-So I think we should restrict ourselves to sending this packet only if
-we are already the master browser for a workgroup. We could send a
-single "announce request" when we become the master, just to prime our
-server lists. From then on the normal announce cycles should take care
-of keeping it uptodate.
------------
-
diff --git a/source/namebrowse.c b/source/namebrowse.c
deleted file mode 100644
index 1dd293d27be..00000000000
--- a/source/namebrowse.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-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.
-
- Revision History:
-
- 14 jan 96: lkcl@pires.co.uk
- added multiple workgroup domain master support
-
-*/
-
-#include "includes.h"
-#include "smb.h"
-
-extern int ClientNMB;
-
-extern int DEBUGLEVEL;
-
-extern struct in_addr wins_ip;
-
-/* this is our browse master/backup cache database */
-static struct browse_cache_record *browserlist = NULL;
-
-
-/***************************************************************************
- add a browser into the list
- **************************************************************************/
-static void add_browse_cache(struct browse_cache_record *b)
-{
- struct browse_cache_record *b2;
-
- if (!browserlist)
- {
- browserlist = b;
- b->prev = NULL;
- b->next = NULL;
- return;
- }
-
- for (b2 = browserlist; b2->next; b2 = b2->next) ;
-
- b2->next = b;
- b->next = NULL;
- b->prev = b2;
-}
-
-
-/*******************************************************************
- remove old browse entries
- ******************************************************************/
-void expire_browse_cache(time_t t)
-{
- struct browse_cache_record *b;
- struct browse_cache_record *nextb;
-
- /* expire old entries in the serverlist */
- for (b = browserlist; b; b = nextb)
- {
- if (b->synced && b->sync_time < t)
- {
- DEBUG(3,("Removing dead cached browser %s\n",b->name));
- nextb = b->next;
-
- if (b->prev) b->prev->next = b->next;
- if (b->next) b->next->prev = b->prev;
-
- if (browserlist == b) browserlist = b->next;
-
- free(b);
- }
- else
- {
- nextb = b->next;
- }
- }
-}
-
-/****************************************************************************
- add a browser entry
- ****************************************************************************/
-struct browse_cache_record *add_browser_entry(char *name, int type, char *wg,
- time_t ttl, struct subnet_record *d,
- struct in_addr ip, BOOL local)
-{
- BOOL newentry=False;
-
- struct browse_cache_record *b;
-
- /* search for the entry: if it's already in the cache, update that entry */
- for (b = browserlist; b; b = b->next)
- {
- if (ip_equal(ip,b->ip) && strequal(b->group, wg)) break;
- }
-
- if (b && b->synced)
- {
- /* entries get left in the cache for a while. this stops sync'ing too
- often if the network is large */
- DEBUG(4, ("browser %s %s %s already sync'd at time %d\n",
- b->name, b->group, inet_ntoa(b->ip), b->sync_time));
- return NULL;
- }
-
- if (!b)
- {
- newentry = True;
- b = (struct browse_cache_record *)malloc(sizeof(*b));
-
- if (!b) return(NULL);
-
- bzero((char *)b,sizeof(*b));
- }
-
- /* update the entry */
- ttl = time(NULL)+ttl;
-
- StrnCpy(b->name ,name,sizeof(b->name )-1);
- StrnCpy(b->group,wg ,sizeof(b->group)-1);
- strupper(b->name);
- strupper(b->group);
-
- b->ip = ip;
- b->type = type;
- b->local = local; /* local server list sync or complete sync required */
- b->subnet = d;
-
- if (newentry || ttl < b->sync_time)
- b->sync_time = ttl;
-
- if (newentry)
- {
- b->synced = False;
- add_browse_cache(b);
-
- DEBUG(3,("Added cache entry %s %s(%2x) %s ttl %d\n",
- wg, name, type, inet_ntoa(ip),ttl));
- }
- else
- {
- DEBUG(3,("Updated cache entry %s %s(%2x) %s ttl %d\n",
- wg, name, type, inet_ntoa(ip),ttl));
- }
-
- return(b);
-}
-
-
-/****************************************************************************
-find a server responsible for a workgroup, and sync browse lists
-**************************************************************************/
-static void start_sync_browse_entry(struct browse_cache_record *b)
-{
- struct subnet_record *d = b->subnet;
- struct work_record *work;
-
- /* Check panic conditions - these should not be true. */
- if(b->subnet != wins_subnet) {
- DEBUG(0,
- ("start_sync_browse_entry: ERROR sync requested on non-WINS subnet.\n"));
- return;
- }
-
- if (!(work = find_workgroupstruct(d, b->group, False))) {
- DEBUG(0, ("start_sync_browse_entry: failed to get a \
-workgroup for a browse cache entry workgroup %s, server %s\n",
- b->group, b->name));
- return;
- }
-
- DEBUG(4, ("start_sync_browse_entry: Initiating %s sync with %s<0x20>, \
-workgroup %s\n",
- b->local ? "local" : "remote", b->name, b->group));
-
- /* first check whether the server we intend to sync with exists. if it
- doesn't, the server must have died. o dear. */
-
- /* see response_netbios_packet() or expire_netbios_response_entries() */
- /* We cheat here by using the my_comment field of the response_record
- struct as the workgroup name we are going to do the sync for.
- This is because the reply packet doesn't include the workgroup, but
- we need it when the reply comes back.
- */
- queue_netbios_packet(d,ClientNMB,NMB_QUERY,
- b->local?NAME_QUERY_SYNC_LOCAL:NAME_QUERY_SYNC_REMOTE,
- b->name,0x20,0,0,0,NULL,b->group,
- False,False,b->ip,b->ip);
-
- b->synced = True;
-}
-
-
-/****************************************************************************
- search through browser list for an entry to sync with
- **************************************************************************/
-void do_browser_lists(time_t t)
-{
- struct browse_cache_record *b;
- static time_t last = 0;
-
- if (t-last < 20)
- {
- DEBUG(9,("do_browser_lists: returning due to t(%d) - last(%d) < 20\n",
- t, last));
- return; /* don't do too many of these at once! */
- /* XXXX equally this period should not be too long
- the server may die in the intervening gap */
- }
- last = t;
-
- /* pick any entry in the list, preferably one whose time is up */
- for (b = browserlist; b && b->next; b = b->next)
- {
- if (b->sync_time < t && b->synced == False) break;
- }
-
- if (b && !b->synced)
- {
- /* sync with the selected entry then remove some dead entries */
- DEBUG(4,("do_browser_lists: Initiating sync with %s, workgroup %s\n",
- b->name, b->group));
- start_sync_browse_entry(b);
- }
- else
- {
- DEBUG(9, ("do_browser_lists: no entries to sync.\n"));
- }
-
- expire_browse_cache(t - 60);
-}
-
diff --git a/source/namebrowse.doc b/source/namebrowse.doc
deleted file mode 100644
index 82713d85708..00000000000
--- a/source/namebrowse.doc
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- Unix SMB/Netbios documentation.
- Version 0.1
- Copyright (C) Luke Leighton Andrew Tridgell 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.
-
- Document name: namebrowse.doc
-
- Revision History:
-
- 0.0 - 02jul96 : lkcl@pires.co.uk
- created
-
- 0.1 - 22jul96 Andrew.Tridgell@anu.edu.au
- tridge's comments on first revision
-*/
-
-this module deals with queueing servers that samba must sync browse
-lists with. it will always issue a name query immediately before
-actually carrying out the NetServerEnum call, to ensure that time
-is not wasted by a remote server's failure.
-
-this module was created to minimise the amount of NetServerEnum calls
-that samba may be asked to perform, by maintaining the name of a server
-for up to a minute after the NetServerEnum call was issued, and
-disallowing further NetServerEnum calls to this remote server until
-the entry is removed.
-
-samba can ask for a NetServerEnum call to be issued to grab a remote
-server's list of servers and workgroups either in its capacity as
-a domain master browser, as a local master browser.
-
-samba does not deal with becoming a backup master browser properly
-at present.
-
--------------
-NOTE FROM TRIDGE:
-
-Yes, samba can send these either in its capacity as a DMB or as a
-MB. There are only two situations:
-
-- If samba is a DMB then it should sync with the "local only" bit set
-with any master browser that has sent it a "master announce".
-
-- if samba is not a DMB then it can only sync with the DMB, and should
-not set the "local only" bit.
-
-Note that samba should never sync with other non-DMB servers when it
-is not a DMB.
-
-Try to do a sync under any other circumstances is dangerous without a
-multi-threaded nmbd. I have a print server at home that knows some SMB
-and NBT, but if you try to sync browse lists with it then it clogs up,
-and also clogs up nmbd while it times out the connection. If we
-follow the above two rules then we can't get into this sort of
-trouble as:
-
-- if we are a DMB and a master browser sends us a "master announce"
-then it is expecting to receive a NetServerEnum SMB connection soon,
-and must be capabable of handling it.
-
-- if we are not a DMB then we will only sync with the DMB, which must
-be capable of doing this stuff or things are really in a mess :-)
---------------
-
-
-/*************************************************************************
- do_browser_lists()
- *************************************************************************/
-
-this function is responsible for finding an appropriate entry in the
-sync browser cache, initiating a name query (which results in a
-NetServerEnum call if there is a positive response), and then
-removing all entries that have been actioned and have been around
-for over a minute.
-
-
-/*************************************************************************
- start_sync_browse_entry()
- *************************************************************************/
-
-this function is responsible for initiating a name query. if a
-positive response is received, then this will result in a
-NetServerEnum api call.
-
-samba will only initiate this process if it is a master browser
-for this workgroup.
-
------------
-NOTE FROM TRIDGE:
-
-I'd actually prefer to skip the name query completely if we can
-resolve the DMBs name via gethostbyname(). For the name query to work
-we either have to have WINS working, or we need to know the broadcast
-address of the network that the DMB is on. This makes us too dependent
-on too many thing being right.
-
-If the gethostbyname() fails then sure, go for a normal name query,
-but if it works then we have saved ourselves a lot of trouble and
-gained a lot of robustness.
-
-This is best handled by a generic "resolve netbios name" routine that
-tries DNS first then resorts to WINS or bcast if that fails. It also
-needs to cache the results.
--------------
-
-
-/*************************************************************************
- add_browser_entry()
- *************************************************************************/
-
-this function is responsible for adding a browser into the list of
-servers to sync browse lists with. if the server entry has already
-been added and syncing browse lists has already been initiated, it
-will not be added again.
-
-
-/*************************************************************************
- expire_browse_cache()
- *************************************************************************/
-
-this function is responsible for removing entries that have had the
-sync browse list initiated (whether that succeeded or not is beyond
-this function's scope) and have been in the cache for a while.
-
-
-/*************************************************************************
- add_browse_entry()
- *************************************************************************/
-
-this function is responsible for adding a new entry into the list
-of servers to sync browse lists with at some point in the near future.
-
-
-
-
diff --git a/source/nameconf.c b/source/nameconf.c
deleted file mode 100644
index 19068780611..00000000000
--- a/source/nameconf.c
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines and daemon - version 2
- Copyright (C) David Chappell 1996-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.
-
- Revision History:
-
- 30 July 96: David.Chappell@mail.trincoll.edu
- Expanded multiple workgroup domain master browser support.
-
-*/
-
-/*
-** nameconf.c
-** These functions dispense information from smbbrowse.conf.
-**
-**
-*/
-
-#include "includes.h"
-extern int DEBUGLEVEL;
-
-extern fstring myworkgroup;
-
-#if 0
-struct smbbrowse_parms
- {
- char *name;
- BOOL (*reader)(char *string, void *toset);
- } smbbrowse_table[] =
-{
- {"preferred master", NULL},
- {"local master", NULL},
- {"domain master", NULL}
-} ;
-#endif
-
-/*
-** Structure for the list of workgroups from smbbrowse.conf. This
-** structure should only be manipulated thru the functions in this file.
-** That is why it is not defined in a header file.
-*/
-struct smbbrowse
-{
- char work_name[16]; /* workgroup name */
- char browsing_alias[16]; /* alias for our role in this workgroup */
- struct server_identity *my_names; /* a list of server name we should appear here as */
- BOOL should_workgroup_member; /* should we try to become a member of this workgroup? */
- BOOL should_local_master; /* should we try to become a master browser? */
- BOOL should_domain_master; /* should we try to become the domain master browser? */
-} ;
-
-/* The whole list */
-static struct smbbrowse *smbbrowse_workgroups = (struct smbbrowse*)NULL;
-
-/* The size of the list */
-static int array_size = 0;
-
-/* The next available space in the list */
-static int nexttoken = 0;
-
-int get_num_workgroups(void)
-{
- return nexttoken;
-}
-
-/*
-** This makes a new workgroup structure, possibly taking an
-** old one as a model.
-*/
-static struct smbbrowse *new_workgroup(struct smbbrowse *model,
- char *workgroup_name,
- char *default_name)
-{
- struct smbbrowse *new;
-
- if( ! (array_size > nexttoken) )
- {
- array_size += 10;
- smbbrowse_workgroups = (struct smbbrowse*)realloc(smbbrowse_workgroups,
- array_size * sizeof(struct smbbrowse));
- }
-
- new = &smbbrowse_workgroups[nexttoken];
-
- if(model != (struct smbbrowse *)NULL )
- memcpy(new, model, sizeof(struct smbbrowse));
- else
- memset(new, 0, sizeof(struct smbbrowse));
-
- StrnCpy(new->work_name, workgroup_name, 15);
- strupper(new->work_name);
-
- if (strequal(myworkgroup, workgroup_name))
- StrnCpy(new->browsing_alias, default_name, 15);
- else
- sprintf(new->browsing_alias, "%.14s%x", default_name, nexttoken);
- strupper(new->browsing_alias);
-
- DEBUG(4,("wg: %s alias: %s token: %x\n",
- new->work_name, new->browsing_alias, nexttoken));
-
- nexttoken++;
- return new;
-}
-
-/*
-** If fed a workgroup name, this function returns its token number.
-** If the workgroup does not exist a new token is assigned unless
-** new workgroups are not allowed.
-*/
-int conf_workgroup_name_to_token(char *workgroup_name,char *default_name)
-{
- int idx;
-
- /* Look for an existing instance. */
- for(idx=0; idx < nexttoken; idx++)
- {
- if(strequal(workgroup_name, smbbrowse_workgroups[idx].work_name))
- {
- return idx;
- }
- }
-
- /* See if creating new ones in admissable. */
- for(idx=0; idx < nexttoken; idx++)
- {
- if(strequal("*", smbbrowse_workgroups[idx].work_name))
- {
- struct smbbrowse *w = new_workgroup(&smbbrowse_workgroups[idx],
- workgroup_name, default_name);
- w->should_workgroup_member = False;
-
- return (nexttoken - 1);
- }
- }
-
- /* Not allowed */
- DEBUG(4, ("refusing to allow new workgroup\n"));
- return -1;
-}
-
-/*
-** This is a workgroups array bounds checker.
-*/
-static int range_check(int token)
-{
- if(token < 0 || token >= nexttoken)
- {
- DEBUG(0, ("range_check(): failed\n"));
- return True;
- }
-
- return False;
-}
-
-/*
-** Given a token, return the name.
-*/
-char *conf_workgroup_name(int token)
-{
- if(range_check(token))
- return (char*)NULL;
-
- return smbbrowse_workgroups[token].work_name;
-}
-
-/*
-** Given a token, return True if we should try
-** to become a master browser.
-*/
-int conf_should_workgroup_member(int token)
- {
-
- if(range_check(token))
- return False;
-
- return smbbrowse_workgroups[token].should_workgroup_member;
- }
-
-/*
-** Given a token, return True if we should try
-** to become a master browser.
-*/
-int conf_should_local_master(int token)
- {
- if(range_check(token))
- return False;
-
- return smbbrowse_workgroups[token].should_local_master;
- }
-
-/*
-** Given a token, return True if we should try
-** to become a domain master browser.
-*/
-int conf_should_domain_master(int token)
- {
- if(range_check(token))
- return False;
-
- return smbbrowse_workgroups[token].should_domain_master;
- }
-
-/*
-** Given a token, return the name.
-*/
-char *conf_browsing_alias(int token)
- {
- if(range_check(token))
- return (char*)NULL;
-
- return smbbrowse_workgroups[token].browsing_alias;
- }
-
-/*
-** Return the server comment which should be used with the
-** browsing alias.
-*/
-char *conf_browsing_alias_comment(int token)
-{
- if(range_check(token))
- return (char*) NULL;
-
- return "Browser";
- }
-
-/*
-** Given an alias name for this server, return the name of the workgroup
-** for which it is the browsing alias.
-*/
-char *conf_alias_to_workgroup(char *alias)
-{
- int x;
-
- DEBUG(4,("alias_to_workgroup: %s", alias));
-
- for(x=0; x < nexttoken; x++)
- {
- DEBUG(4,("%s ", smbbrowse_workgroups[x].browsing_alias));
-
- if(strequal(alias, smbbrowse_workgroups[x].browsing_alias))
- {
- DEBUG(4,("OK\n"));
- return smbbrowse_workgroups[x].work_name;
- }
- }
- DEBUG(4,("not found\n"));
- return (char*)NULL;
-}
-
-/*
-** Given an alias name for this server, return the name of the workgroup
-** for which it is the browsing alias.
-*/
-int conf_alias_to_token(char *alias)
-{
- int x;
-
- for(x=0; x < nexttoken; x++)
- {
- if(strequal(alias, smbbrowse_workgroups[x].browsing_alias))
- {
- return x;
- }
- }
- return -1;
-}
-
-/*
-** Since there is no smbbrowse.conf file, we will fill in
-** the structures with information from the smb.conf file.
-*/
-static void default_smbbrowse_conf(char *default_name)
-{
- struct smbbrowse *w;
-
- /* The workgroup specified in smb.conf */
- w = new_workgroup((struct smbbrowse *)NULL, myworkgroup, default_name);
- w->should_local_master = lp_preferred_master();
- w->should_domain_master = lp_domain_master();
- w->should_workgroup_member = True;
-
- /* default action: allow any new workgroup to be added */
- w = new_workgroup((struct smbbrowse *)NULL, "*", default_name);
- w->should_local_master = False;
- w->should_domain_master = False;
- w->should_workgroup_member = False;
-}
-
-/*
-** This function is called from main().
-*/
-void read_smbbrowse_conf(char *default_name)
-{
- FILE *f = fopen(BROWSEFILE,"r");
- if (f)
- {
- while (!feof(f))
- {
- pstring line;
- char *ptr;
- int count = 0;
-
- pstring work_name;
- struct smbbrowse *w;
-
- if (!fgets_slash(line,sizeof(pstring),f)) continue;
-
- if (*line == '#') continue;
-
- strcpy(work_name,"");
-
- ptr = line;
-
- if (next_token(&ptr, work_name, NULL)) ++count;
-
- if (count <= 0) continue;
-
- w = new_workgroup((struct smbbrowse *)NULL, work_name, default_name);
- w->should_local_master = lp_local_master();
- w->should_domain_master = lp_domain_master();
- w->should_workgroup_member = True;
- }
-
- fclose(f);
- }
- else
- {
- DEBUG(2,("Can't open browse configuration file %s\n",BROWSEFILE));
- }
- default_smbbrowse_conf(default_name);
-}
-
-
diff --git a/source/namedbname.c b/source/namedbname.c
deleted file mode 100644
index 51571d786a8..00000000000
--- a/source/namedbname.c
+++ /dev/null
@@ -1,601 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-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.
-
- Module name: namedbname.c
-
- Revision History:
-
- 14 jan 96: lkcl@pires.co.uk
- added multiple workgroup domain master support
-
- 04 jul 96: lkcl@pires.co.uk
- created module namedbname containing name database functions
-*/
-
-#include "includes.h"
-
-extern int DEBUGLEVEL;
-
-extern pstring scope;
-extern struct in_addr ipzero;
-extern struct in_addr wins_ip;
-extern BOOL updatedlists;
-
-extern struct subnet_record *subnetlist;
-
-#define WINS_LIST "wins.dat"
-
-uint16 nb_type = 0; /* samba's NetBIOS name type */
-
-
-/****************************************************************************
- samba's NetBIOS name type
-
- XXXX maybe functionality could be set: B, M, P or H name registration
- and resolution could be set through nb_type. just a thought.
- ****************************************************************************/
-void set_samba_nb_type(void)
-{
- if (lp_wins_support() || (*lp_wins_server()))
- {
- nb_type = NB_MFLAG; /* samba is a 'hybrid' node type */
- }
- else
- {
- nb_type = NB_BFLAG; /* samba is broadcast-only node type */
- }
-}
-
-
-/****************************************************************************
- true if two netbios names are equal
-****************************************************************************/
-BOOL name_equal(struct nmb_name *n1,struct nmb_name *n2)
-{
- return n1->name_type == n2->name_type &&
- strequal(n1->name ,n2->name ) &&
- strequal(n1->scope,n2->scope);
-}
-
-
-/****************************************************************************
- true if the netbios name is ^1^2__MSBROWSE__^2^1
-
- note: this name is registered if as a master browser or backup browser
- you are responsible for a workgroup (when you announce a domain by
- broadcasting on your local subnet, you announce it as coming from this
- name: see announce_host()).
-
- **************************************************************************/
-BOOL ms_browser_name(char *name, int type)
-{
- return strequal(name,MSBROWSE) && type == 0x01;
-}
-
-
-/****************************************************************************
- add a netbios name into the namelist
- **************************************************************************/
-static void add_name(struct subnet_record *d, struct name_record *n)
-{
- struct name_record *n2;
-
- if (!d) return;
-
- if (!d->namelist)
- {
- d->namelist = n;
- n->prev = NULL;
- n->next = NULL;
- return;
- }
-
- for (n2 = d->namelist; n2->next; n2 = n2->next) ;
-
- n2->next = n;
- n->next = NULL;
- n->prev = n2;
-
- if((d == wins_subnet) && lp_wins_support())
- updatedlists = True;
-}
-
-
-/****************************************************************************
- remove a name from the namelist. The pointer must be an element just
- retrieved
- **************************************************************************/
-void remove_name(struct subnet_record *d, struct name_record *n)
-{
- struct name_record *nlist;
- if (!d) return;
-
- nlist = d->namelist;
-
- while (nlist && nlist != n) nlist = nlist->next;
-
- if (nlist)
- {
- if (nlist->next) nlist->next->prev = nlist->prev;
- if (nlist->prev) nlist->prev->next = nlist->next;
-
- if(nlist == d->namelist)
- d->namelist = nlist->next;
-
- if(nlist->ip_flgs != NULL)
- free(nlist->ip_flgs);
- free(nlist);
- }
-
- if((d == wins_subnet) && lp_wins_support())
- updatedlists = True;
-}
-
-
-/****************************************************************************
- find a name in a namelist.
- **************************************************************************/
-struct name_record *find_name(struct name_record *n,
- struct nmb_name *name, int search)
-{
- struct name_record *ret;
-
- for (ret = n; ret; ret = ret->next)
- {
- if (name_equal(&ret->name,name))
- {
- /* self search: self names only */
- if ((search&FIND_SELF) == FIND_SELF && ret->source != SELF)
- {
- continue;
- }
- DEBUG(9,("find_name: found name %s(%02x)\n",
- name->name, name->name_type));
- return ret;
- }
- }
- DEBUG(9,("find_name: name %s(%02x) NOT FOUND\n", name->name,
- name->name_type));
- return NULL;
-}
-
-
-/****************************************************************************
- find a name in the domain database namelist
- search can be any of:
- FIND_SELF - look exclusively for names the samba server has added for itself
- FIND_LOCAL - look for names in the local subnet record.
- FIND_WINS - look for names in the WINS record
- **************************************************************************/
-struct name_record *find_name_search(struct subnet_record **d,
- struct nmb_name *name,
- int search, struct in_addr ip)
-{
- if (d == NULL) return NULL; /* bad error! */
-
- if (search & FIND_LOCAL) {
- if (*d != NULL) {
- struct name_record *n = find_name((*d)->namelist, name, search);
- DEBUG(4,("find_name on local: %s %s search %x\n",
- namestr(name),inet_ntoa(ip), search));
- if (n) return n;
- }
- }
-
- if (!(search & FIND_WINS)) return NULL;
-
- /* find WINS subnet record. */
- *d = wins_subnet;
-
- if (*d == NULL) return NULL;
-
- DEBUG(4,("find_name on WINS: %s %s search %x\n",
- namestr(name),inet_ntoa(ip), search));
- return find_name((*d)->namelist, name, search);
-}
-
-
-/****************************************************************************
- dump a copy of the name table
- **************************************************************************/
-void dump_names(void)
-{
- struct name_record *n;
- fstring fname, fnamenew;
- time_t t = time(NULL);
-
- FILE *f;
-
- if(lp_wins_support() == False || wins_subnet == 0)
- return;
-
- fstrcpy(fname,lp_lockdir());
- trim_string(fname,NULL,"/");
- strcat(fname,"/");
- strcat(fname,WINS_LIST);
- fstrcpy(fnamenew,fname);
- strcat(fnamenew,".");
-
- f = fopen(fnamenew,"w");
-
- if (!f)
- {
- DEBUG(3,("Can't open %s - %s\n",fnamenew,strerror(errno)));
- return;
- }
-
- DEBUG(4,("Dump of WINS name table:\n"));
-
- for (n = wins_subnet->namelist; n; n = n->next)
- {
- int i;
-
- DEBUG(4,("%15s ", inet_ntoa(wins_subnet->bcast_ip)));
- DEBUG(4,("%15s ", inet_ntoa(wins_subnet->mask_ip)));
- DEBUG(4,("%-19s TTL=%ld ",
- namestr(&n->name),
- n->death_time?n->death_time-t:0));
-
- for (i = 0; i < n->num_ips; i++)
- {
- DEBUG(4,("%15s NB=%2x source=%d",
- inet_ntoa(n->ip_flgs[i].ip),
- n->ip_flgs[i].nb_flags,n->source));
-
- }
- DEBUG(4,("\n"));
-
- if (f && ((n->source == REGISTER) || (n->source == SELF)))
- {
- /* XXXX i have little imagination as to how to output nb_flags as
- anything other than as a hexadecimal number :-) */
-
- fprintf(f, "%s#%02x %ld ",
- n->name.name,n->name.name_type, /* XXXX ignore scope for now */
- n->death_time);
-
- for (i = 0; i < n->num_ips; i++)
- {
- fprintf(f, "%s %2x%c ",
- inet_ntoa(n->ip_flgs[i].ip),
- n->ip_flgs[i].nb_flags, (n->source == REGISTER ? 'R' : 'S'));
- }
- fprintf(f, "\n");
- }
-
- }
-
- fclose(f);
- unlink(fname);
- chmod(fnamenew,0644);
- rename(fnamenew,fname);
-
- DEBUG(3,("Wrote wins database %s\n",fname));
-}
-
-
-/****************************************************************************
- load a netbios name database file
-
- XXXX we cannot cope with loading Internet Group names, yet
- ****************************************************************************/
-void load_netbios_names(void)
-{
- struct subnet_record *d = wins_subnet;
- fstring fname;
-
- FILE *f;
- pstring line;
-
- if (!d) return;
-
- fstrcpy(fname,lp_lockdir());
- trim_string(fname,NULL,"/");
- strcat(fname,"/");
- strcat(fname,WINS_LIST);
-
- f = fopen(fname,"r");
-
- if (!f) {
- DEBUG(2,("Can't open wins database file %s\n",fname));
- return;
- }
-
- while (!feof(f))
- {
- pstring name_str, ip_str, ttd_str, nb_flags_str;
-
- pstring name;
- int type = 0;
- unsigned int nb_flags;
- time_t ttd;
- struct in_addr ipaddr;
-
- enum name_source source;
-
- char *ptr;
- int count = 0;
-
- char *p;
-
- if (!fgets_slash(line,sizeof(pstring),f)) continue;
-
- if (*line == '#') continue;
-
- ptr = line;
-
- if (next_token(&ptr,name_str ,NULL)) ++count;
- if (next_token(&ptr,ttd_str ,NULL)) ++count;
- if (next_token(&ptr,ip_str ,NULL)) ++count;
- if (next_token(&ptr,nb_flags_str,NULL)) ++count;
-
- if (count <= 0) continue;
-
- if (count != 4) {
- DEBUG(0,("Ill formed wins line"));
- DEBUG(0,("[%s]: name#type abs_time ip nb_flags\n",line));
- continue;
- }
-
- /* Deal with SELF or REGISTER name encoding. Default is REGISTER
- for compatibility with old nmbds. */
- if(nb_flags_str[strlen(nb_flags_str)-1] == 'S')
- {
- DEBUG(5,("Ignoring SELF name %s\n", line));
- continue;
- }
-
- if(nb_flags_str[strlen(nb_flags_str)-1] == 'R')
- nb_flags_str[strlen(nb_flags_str)-1] = '\0';
-
- /* netbios name. # divides the name from the type (hex): netbios#xx */
- pstrcpy(name,name_str);
-
- p = strchr(name,'#');
-
- if (p) {
- *p = 0;
- sscanf(p+1,"%x",&type);
- }
-
- /* decode the netbios flags (hex) and the time-to-die (seconds) */
- sscanf(nb_flags_str,"%x",&nb_flags);
- sscanf(ttd_str,"%ld",&ttd);
-
- ipaddr = *interpret_addr2(ip_str);
-
- if (ip_equal(ipaddr,ipzero)) {
- source = SELF;
- }
- else
- {
- source = REGISTER;
- }
-
- DEBUG(4, ("add WINS line: %s#%02x %ld %s %2x\n",
- name,type, ttd, inet_ntoa(ipaddr), nb_flags));
-
- /* add all entries that have 60 seconds or more to live */
- if (ttd - 60 > time(NULL) || ttd == 0)
- {
- time_t t = (ttd?ttd-time(NULL):0) / 3;
-
- /* add netbios entry read from the wins.dat file. IF it's ok */
- add_netbios_entry(d,name,type,nb_flags,t,source,ipaddr,True,True);
- }
- }
-
- fclose(f);
-}
-
-
-/****************************************************************************
- remove an entry from the name list
- ****************************************************************************/
-void remove_netbios_name(struct subnet_record *d,
- char *name,int type, enum name_source source,
- struct in_addr ip)
-{
- struct nmb_name nn;
- struct name_record *n;
-
- make_nmb_name(&nn, name, type, scope);
- n = find_name_search(&d, &nn, FIND_LOCAL, ip);
-
- if (n && n->source == source) remove_name(d,n);
-}
-
-
-/****************************************************************************
- add an entry to the name list.
-
- this is a multi-purpose function.
-
- it adds samba's own names in to its records on each interface, keeping a
- record of whether it is a master browser, domain master, or WINS server.
-
- it also keeps a record of WINS entries.
-
- ****************************************************************************/
-struct name_record *add_netbios_entry(struct subnet_record *d,
- char *name, int type, int nb_flags,
- int ttl, enum name_source source, struct in_addr ip,
- BOOL new_only,BOOL wins)
-{
- struct name_record *n;
- struct name_record *n2=NULL;
- struct subnet_record *found_subnet = 0;
- int search = 0;
- BOOL self = (source == SELF);
-
- /* add the name to the WINS list if the name comes from a directed query */
- search |= wins ? FIND_WINS : FIND_LOCAL;
-
- /* If it's a local search then we need to set the subnet
- we are looking at. */
- if(search & FIND_LOCAL)
- found_subnet = d;
-
- /* search for SELF names only */
- search |= self ? FIND_SELF : 0;
-
- if (!self)
- {
- if (!wins && (type != 0x1b))
- {
- /* the only broadcast (non-WINS) names we are adding are ours
- (SELF) and Domain Master type names */
- return NULL;
- }
- if(wins && (type == 0x1d))
- {
- /* Do not allow any 0x1d names to be registered in a WINS,
- database although we return success for them.
- */
- return NULL;
- }
- }
-
- n = (struct name_record *)malloc(sizeof(*n));
- if (!n) return(NULL);
-
- bzero((char *)n,sizeof(*n));
-
- n->num_ips = 1; /* XXXX ONLY USE THIS FUNCTION FOR ONE ENTRY */
- n->ip_flgs = (struct nmb_ip*)malloc(sizeof(*n->ip_flgs) * n->num_ips);
- if (!n->ip_flgs)
- {
- free(n);
- return NULL;
- }
-
- bzero((char *)n->ip_flgs, sizeof(*n->ip_flgs) * n->num_ips);
-
- make_nmb_name(&n->name,name,type,scope);
-
- if ((n2 = find_name_search(&found_subnet, &n->name, search, new_only?ipzero:ip)))
- {
- free(n->ip_flgs);
- free(n);
- if (new_only || (n2->source==SELF && source!=SELF)) return n2;
- n = n2;
- d = found_subnet;
- }
-
- if (ttl)
- n->death_time = time(NULL)+ttl*3;
- n->refresh_time = time(NULL)+GET_TTL(ttl);
-
- /* XXXX only one entry expected with this function */
- n->ip_flgs[0].ip = ip;
- n->ip_flgs[0].nb_flags = nb_flags;
-
- n->source = source;
-
- if (!n2) add_name(d,n);
-
- DEBUG(3,("Added netbios name %s at %s ttl=%d nb_flags=%2x to interface %s\n",
- namestr(&n->name),inet_ntoa(ip),ttl,nb_flags,
- ip_equal(d->bcast_ip, wins_ip) ? "WINS" : (char *)inet_ntoa(d->bcast_ip)));
-
- return(n);
-}
-
-
-/*******************************************************************
- expires old names in the namelist
- ******************************************************************/
-void expire_names(time_t t)
-{
- struct name_record *n;
- struct name_record *next;
- struct subnet_record *d;
-
- /* expire old names */
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d))
- {
- for (n = d->namelist; n; n = next)
- {
- next = n->next;
- if (n->death_time && n->death_time < t)
- {
- if (n->source == SELF)
- {
- DEBUG(3,("not expiring SELF name %s\n", namestr(&n->name)));
- n->death_time += 300;
- continue;
- }
- DEBUG(3,("Removing dead name %s\n", namestr(&n->name)));
-
- if (n->prev) n->prev->next = n->next;
- if (n->next) n->next->prev = n->prev;
-
- if (d->namelist == n) d->namelist = n->next;
-
- if(n->ip_flgs != NULL)
- free(n->ip_flgs);
- free(n);
- }
- }
- }
-}
-
-
-/***************************************************************************
- assume a WINS name is a dns name, and do a gethostbyname() on it.
- ****************************************************************************/
-struct name_record *dns_name_search(struct nmb_name *question, int Time)
-{
- int name_type = question->name_type;
- char *qname = question->name;
- BOOL dns_type = (name_type == 0x20 || name_type == 0);
- struct in_addr dns_ip;
-
- if (wins_subnet == NULL)
- return NULL;
-
- DEBUG(3,("Search for %s - ", namestr(question)));
-
- /* only do DNS lookups if the query is for type 0x20 or type 0x0 */
- if (!dns_type)
- {
- DEBUG(3,("types 0x20 0x0 only: name not found\n"));
- return NULL;
- }
-
- /* look it up with DNS */
- dns_ip.s_addr = interpret_addr(qname);
-
- if (!dns_ip.s_addr)
- {
- /* no luck with DNS. We could possibly recurse here XXXX */
- DEBUG(3,("not found. no recursion.\n"));
- /* add the fail to WINS cache of names. give it 1 hour in the cache */
- add_netbios_entry(wins_subnet,qname,name_type,NB_ACTIVE,60*60,DNSFAIL,dns_ip,
- True, True);
- return NULL;
- }
-
- DEBUG(3,("found with DNS: %s\n", inet_ntoa(dns_ip)));
-
- /* add it to our WINS cache of names. give it 2 hours in the cache */
- return add_netbios_entry(wins_subnet,qname,name_type,NB_ACTIVE,2*60*60,DNS,dns_ip,
- True,True);
-}
diff --git a/source/namedbname.doc b/source/namedbname.doc
deleted file mode 100644
index 34a791dbb89..00000000000
--- a/source/namedbname.doc
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- Unix SMB/Netbios documentation.
- Version 0.0
- Copyright (C) Luke Leighton Andrew Tridgell 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.
-
- Document name: namedbname.doc
-
- Revision History:
-
- 0.0 - 02jul96 : lkcl@pires.co.uk
- created
-*/
-
-this module deals with the NetBIOS name database for samba. it deals
-directly with adding, removing, finding, loading and saving of names.
-
-/*************************************************************************
- search_for_name()
- *************************************************************************/
-
-this function is responsible for finding a name in the appropriate part
-of samba's NetBIOS name database. if the name cannot be found, then it
-should look the name up using DNS. later modifications will be to
-forward the request on to another WINS server, should samba not be able
-to find out about the requested name (this will be implemented through
-issuing a new type of samba 'state').
-
-the name is first searched for in the NetBIOS cache. if it cannot be
-found, then it if the name looks like it's a server-type name (0x20
-0x0 or 0x1b) then DNS is used to look for the name.
-
-if DNS fails, then a record of this failure is kept. if it succeeds, then
-a new NetBIOS entry is added.
-
-the successfully found name is returned. on failure, NULL is returned.
-
-
-/*************************************************************************
- expire_names()
- *************************************************************************/
-
-this function is responsible for removing old NetBIOS names from its
-database. no further action is required.
-
-for over-zealous WINS systems, the use of query_refresh_names() is
-recommended. this function initiates polling of hosts that have
-registered with samba in its capacity as a WINS server. an alternative
-means to achieve the same end as query_refresh_names() is to
-reduce the time to live when the name is registered with samba,
-except that in this instance the responsibility for refreshing the
-name is with the owner of the name, not the server with which the name
-is registered.
-
-
-/*************************************************************************
- add_netbios_entry()
- *************************************************************************/
-
-this function is responsible for adding or updating a NetBIOS name
-in the database. into the local interface records, the only names
-that will be added are those of domain master browsers and
-samba's own names. into the WINS records, all names are added.
-
-the name to be added / updated will be looked up in the records.
-if it is found, then we will not overwrite the entry if the flag
-'newonly' is True, or if the name is being added as a non-SELF
-(non-samba) name and the records indicate that samba owns the
-name.
-
-otherwise, the name is added or updated with the new details.
-
-
-/*************************************************************************
- remove_netbios_entry()
- *************************************************************************/
-
-this function is responsible for removing a NetBIOS entry from
-the database. the name is searched for in the records using
-find_name_search(). if the ip is zero, then the ip is ignored.
-
-the name is removed if the expected source (e.g SELF, REGISTER)
-matches that in the database.
-
-
-/*************************************************************************
- load_netbios_names()
- *************************************************************************/
-
-this function is responsible for loading any NetBIOS names that samba,
-in its WINS capacity, has written out to disk. all the relevant details
-are recorded in this file, including the time-to-live. should the
-time left to live be small, the name is not added back in to samba's
-WINS database.
-
-
-/*************************************************************************
- dump_names()
- *************************************************************************/
-
-this function is responsible for outputting NetBIOS names in two formats.
-firstly, as debugging information, and secondly, all names that have been
-registered with samba in its capacity as a WINS server are written to
-disk.
-
-writing all WINS names allows two things. firstly, if samba's NetBIOS
-daemon dies or is terminated, on restarting the daemon most if not all
-of the registered WINS names will be preserved (which is a good reason
-why query_netbios_names() should be used).
-
-
-/*************************************************************************
- find_name_search()
- *************************************************************************/
-
-this function is a wrapper around find_name(). find_name_search() can
-be told whether to search for the name in a local subnet structure or
-in the WINS database. on top of this, it can be told to search only
-for samba's SELF names.
-
-if it finds the name in the WINS database, it will set the subnet_record
-and also return the name it finds.
-
-
-/*************************************************************************
- find_name()
- *************************************************************************/
-
-this function is a low-level search function that searches a single
-interface's NetBIOS records for a name. if the ip to be found is
-zero then the ip address is ignored. this is to enable a name to
-be found without knowing its ip address, and also to find the exact
-name if a large number of group names are added with different ip
-addresses.
-
-
-/*************************************************************************
- remove_name()
- *************************************************************************/
-
-this function is responsible for removing a specific NetBIOS entry
-from a subnet list's records. only if the pointer to the entry is
-in the list will the name be removed.
-
-
-/*************************************************************************
- add_name()
- *************************************************************************/
-
-this function is responsible for adding a NetBIOS entry into a
-subnet list's records.
-
-
-/*************************************************************************
- ms_browser_name()
- *************************************************************************/
-
-this function returns True if the NetBIOS name passed to it is
-^1^2__MSBROWSE__^2^1
-
-
-/*************************************************************************
- name_equal()
- *************************************************************************/
-
-this function returns True if the two NetBIOS names passed to it
-match in name, type and scope: the NetBIOS names are equal.
-
-
diff --git a/source/namedbresp.c b/source/namedbresp.c
deleted file mode 100644
index 86d7eddbd41..00000000000
--- a/source/namedbresp.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios library routines
- Copyright (C) Andrew Tridgell 1994-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.
-
- Module name: namedbresp.c
-
-*/
-
-#include "includes.h"
-
-extern int ClientNMB;
-extern int ClientDGRAM;
-
-extern struct subnet_record *subnetlist;
-
-extern int DEBUGLEVEL;
-
-extern pstring scope;
-extern pstring myname;
-extern struct in_addr ipzero;
-
-int num_response_packets = 0;
-
-/***************************************************************************
- add an expected response record into the list
- **************************************************************************/
-void add_response_record(struct subnet_record *d,
- struct response_record *n)
-{
- struct response_record *n2;
-
- if (!d) return;
-
- num_response_packets++; /* count of total number of packets still around */
-
- DEBUG(4,("adding response record id:%d num_records:%d\n",
- n->response_id, num_response_packets));
-
- if (!d->responselist)
- {
- d->responselist = n;
- n->prev = NULL;
- n->next = NULL;
- return;
- }
-
- for (n2 = d->responselist; n2->next; n2 = n2->next) ;
-
- n2->next = n;
- n->next = NULL;
- n->prev = n2;
-}
-
-
-/***************************************************************************
- remove an expected response record from the list
- **************************************************************************/
-void remove_response_record(struct subnet_record *d,
- struct response_record *n)
-{
- if (!d) return;
-
- if (n->prev) n->prev->next = n->next;
- if (n->next) n->next->prev = n->prev;
-
- if (d->responselist == n) d->responselist = n->next;
-
- free(n);
-
- num_response_packets--; /* count of total number of packets still around */
-}
-
-
-/****************************************************************************
- create a name query response record
- **************************************************************************/
-struct response_record *make_response_queue_record(enum state_type state,
- int id,uint16 fd,
- int quest_type, char *name,int type, int nb_flags, time_t ttl,
- int server_type, char *my_name, char *my_comment,
- BOOL bcast,BOOL recurse,
- struct in_addr send_ip, struct in_addr reply_to_ip)
-{
- struct response_record *n;
-
- if (!name || !name[0]) return NULL;
-
- if (!(n = (struct response_record *)malloc(sizeof(*n))))
- return(NULL);
-
- bzero((char *)n, sizeof(*n));
-
- n->response_id = id;
- n->state = state;
- n->fd = fd;
- n->quest_type = quest_type;
- make_nmb_name(&n->name, name, type, scope);
- n->nb_flags = nb_flags;
- n->ttl = ttl;
- n->server_type = server_type;
- n->bcast = bcast;
- n->recurse = recurse;
- n->send_ip = send_ip;
- n->reply_to_ip = reply_to_ip;
- if(my_name)
- StrnCpy(n->my_name, my_name, sizeof(n->my_name)-1);
- else
- *n->my_name = 0;
- if(my_comment)
- StrnCpy(n->my_comment, my_comment, sizeof(n->my_comment)-1);
- else
- *n->my_comment = 0;
- n->repeat_interval = 1; /* XXXX should be in ms */
- n->repeat_count = 3; /* 3 retries */
- n->repeat_time = time(NULL) + n->repeat_interval; /* initial retry time */
-
- n->num_msgs = 0;
-
- return n;
-}
-
-
-/****************************************************************************
- find a response in a subnet's name query response list.
- **************************************************************************/
-struct response_record *find_response_record(struct subnet_record **d,
- uint16 id)
-{
- struct response_record *n;
-
- if (!d) return NULL;
-
- for ((*d) = FIRST_SUBNET; (*d); (*d) = NEXT_SUBNET_INCLUDING_WINS(*d))
- {
- for (n = (*d)->responselist; n; n = n->next)
- {
- if (n->response_id == id) {
- DEBUG(4, ("found response record on %s: %d\n",
- inet_ntoa((*d)->bcast_ip), id));
- return n;
- }
- }
- }
-
- *d = NULL;
-
- return NULL;
-}
-
-
diff --git a/source/namedbresp.doc b/source/namedbresp.doc
deleted file mode 100644
index a54c0702758..00000000000
--- a/source/namedbresp.doc
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- Unix SMB/Netbios documentation.
- Version 0.1
- Copyright (C) Luke Leighton Andrew Tridgell 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.
-
- Document name: namedbresp.doc
-
- Revision History:
-
- 0.0 - 02jul96 : lkcl@pires.co.uk
- created
-
- 0.1 - 22jul96 Andrew.Tridgell@anu.edu.au
- tridge's comments on first revision
-*/
-
-module namedbresp deals with the maintenance of the list of expected
-responses - creating, finding and removal.
-
-module nameresp deals with the initial transmission, re-transmission
-and time-out of netbios response records.
-
-
-/*************************************************************************
- find_response_record()
- *************************************************************************/
-
-this function is responsible for matching the unique response transaction
-id with an expected response record. as a side-effect of this search,
-it will find the subnet (or the WINS pseudo-subnet) that samba expected
-the response to come from.
-
-
-/*************************************************************************
- make_response_queue_record()
- *************************************************************************/
-
-this function is responsible for creating a response record, which will
-be queued awaiting a response.
-
-the number of retries is set to 3, and the retry period set to 1 second.
-if no response is received, then the packet is re-transmitted, which is
-why so much information is stored in the response record.
-
-the number of expected responses queued is kept, so listen_for_packets()
-knows it must time-out after 1 second if one or more responses are
-expected.
-
-
-/*************************************************************************
- remove_response_record()
- *************************************************************************/
-
-this function is responsible for removing a response record from the
-expected response queue. the number of expected responses is decreased.
-
-
-/*************************************************************************
- add_response_record()
- *************************************************************************/
-
-this function is responsible for adding the response record created by
-make_response_queue_record() into the appropriate response record queue.
-
-
------------------
-NOTE FROM TRIDGE:
-
-namedbresp.c is interesting because it implements a novel way of
-getting most of the advantages of a multi-threaded nmbd daemon without
-the portability problems.
-
-The NBT specs (rfc1001/1002) talk about the 16 bit IDs in the packets
-as being used to ensure that packets are unique, and to stop packets
-from being confused. It suggests incrementing the ID by 1 each time.
-
-Instead Luke uses these IDs to identify individual threads of control
-in nmbd. So when nmbd sends out a NBT packet as part of some complex
-processing, it adds to a linked list the information required to
-continue the processing when the reply comes in (or it times
-out). When a reply arrives this list can be searched to find the
-matching query and the next step in the processing can be carried out.
-
-This is really good stuff, and allows for much more complex behaviour
-than was possible with the old nmbd.
-----------------
diff --git a/source/namedbserver.c b/source/namedbserver.c
deleted file mode 100644
index 9223cb6ce6a..00000000000
--- a/source/namedbserver.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-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.
-
- Revision History:
-
- 14 jan 96: lkcl@pires.co.uk
- added multiple workgroup domain master support
-
- 04 jul 96: lkcl@pires.co.uk
- created module namedbserver containing server database functions
-
-*/
-
-#include "includes.h"
-#include "smb.h"
-
-extern int ClientNMB;
-extern int ClientDGRAM;
-
-extern int DEBUGLEVEL;
-
-extern pstring myname;
-extern fstring myworkgroup;
-
-/* this is our domain/workgroup/server database */
-extern struct subnet_record *subnetlist;
-
-extern BOOL updatedlists;
-
-
-/*******************************************************************
- expire old servers in the serverlist
- time of -1 indicates everybody dies except those with time of 0
- remove_all_servers indicates everybody dies.
- ******************************************************************/
-void remove_old_servers(struct work_record *work, time_t t,
- BOOL remove_all)
-{
- struct server_record *s;
- struct server_record *nexts;
-
- /* expire old entries in the serverlist */
- for (s = work->serverlist; s; s = nexts)
- {
- if (remove_all || (s->death_time && (t == -1 || s->death_time < t)))
- {
- DEBUG(3,("Removing dead server %s\n",s->serv.name));
- updatedlists = True;
- nexts = s->next;
-
- if (s->prev) s->prev->next = s->next;
- if (s->next) s->next->prev = s->prev;
-
- if (work->serverlist == s)
- work->serverlist = s->next;
-
- free(s);
- }
- else
- {
- nexts = s->next;
- }
- }
-}
-
-
-/***************************************************************************
- add a server into the list
- **************************************************************************/
-static void add_server(struct work_record *work,struct server_record *s)
-{
- struct server_record *s2;
-
- if (!work->serverlist) {
- work->serverlist = s;
- s->prev = NULL;
- s->next = NULL;
- return;
- }
-
- for (s2 = work->serverlist; s2->next; s2 = s2->next) ;
-
- s2->next = s;
- s->next = NULL;
- s->prev = s2;
-}
-
-
-/****************************************************************************
- find a server in a server list.
- **************************************************************************/
-struct server_record *find_server(struct work_record *work, char *name)
-{
- struct server_record *ret;
-
- if (!work) return NULL;
-
- for (ret = work->serverlist; ret; ret = ret->next)
- {
- if (strequal(ret->serv.name,name))
- {
- return ret;
- }
- }
- return NULL;
-}
-
-
-/****************************************************************************
- add a server entry
- ****************************************************************************/
-struct server_record *add_server_entry(struct subnet_record *d,
- struct work_record *work,
- char *name,int servertype,
- int ttl,char *comment,
- BOOL replace)
-{
- BOOL newentry=False;
- struct server_record *s;
-
- if (name[0] == '*')
- {
- return (NULL);
- }
-
- s = find_server(work, name);
-
- if (s && !replace)
- {
- DEBUG(4,("Not replacing %s\n",name));
- return(s);
- }
-
- if (!s || s->serv.type != servertype || !strequal(s->serv.comment, comment))
- updatedlists=True;
-
- if (!s)
- {
- newentry = True;
- s = (struct server_record *)malloc(sizeof(*s));
-
- if (!s) return(NULL);
-
- bzero((char *)s,sizeof(*s));
- }
-
-
- /* update the entry */
- StrnCpy(s->serv.name,name,sizeof(s->serv.name)-1);
- StrnCpy(s->serv.comment,comment,sizeof(s->serv.comment)-1);
- strupper(s->serv.name);
- s->serv.type = servertype;
- s->death_time = servertype ? (ttl?time(NULL)+ttl*3:0) : (time(NULL)-1);
-
- /* for a domain entry, the comment field refers to the server name */
-
- if (s->serv.type & SV_TYPE_DOMAIN_ENUM) strupper(s->serv.comment);
-
- if (newentry)
- {
- add_server(work, s);
-
- DEBUG(3,("Added "));
- }
- else
- {
- DEBUG(3,("Updated "));
- }
-
- DEBUG(3,("server entry %s of type %x (%s) to %s %s\n",
- name,servertype,comment,
- work->work_group,inet_ntoa(d->bcast_ip)));
-
- return(s);
-}
-
-
-/*******************************************************************
- expire old servers in the serverlist
- ******************************************************************/
-void expire_servers(time_t t)
-{
- struct subnet_record *d;
-
- for (d = FIRST_SUBNET; d ; d = NEXT_SUBNET_INCLUDING_WINS(d))
- {
- struct work_record *work;
-
- for (work = d->workgrouplist; work; work = work->next)
- {
- remove_old_servers(work, t, False);
- }
- }
-}
-
diff --git a/source/namedbsubnet.c b/source/namedbsubnet.c
deleted file mode 100644
index c6663d71fd4..00000000000
--- a/source/namedbsubnet.c
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-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.
-
- Revision History:
-
- 14 jan 96: lkcl@pires.co.uk
- added multiple workgroup domain master support
-
- 04 jul 96: lkcl@pires.co.uk
- created module namedbsubnet containing subnet database functions
-
-*/
-
-#include "includes.h"
-#include "smb.h"
-
-extern int ClientNMB;
-extern int ClientDGRAM;
-
-extern int DEBUGLEVEL;
-
-extern struct in_addr wins_ip;
-extern struct in_addr ipzero;
-
-extern pstring myname;
-extern fstring myworkgroup;
-extern char **my_netbios_names;
-
-BOOL updatedlists = True;
-int updatecount = 0;
-
-/* local interfaces structure */
-extern struct interface *local_interfaces;
-
-/* this is our domain/workgroup/server database */
-struct subnet_record *subnetlist = NULL;
-
-/* WINS subnet - keep this separate so enumeration code doesn't
- run onto it by mistake. */
-struct subnet_record *wins_subnet = NULL;
-
-extern uint16 nb_type; /* samba's NetBIOS name type */
-
-/****************************************************************************
- add a domain into the list
- **************************************************************************/
-static void add_subnet(struct subnet_record *d)
-{
- struct subnet_record *d2;
-
- if (!subnetlist)
- {
- subnetlist = d;
- d->prev = NULL;
- d->next = NULL;
- return;
- }
-
- for (d2 = subnetlist; d2->next; d2 = d2->next);
-
- d2->next = d;
- d->next = NULL;
- d->prev = d2;
-}
-
-
-/****************************************************************************
- find a subnet in the subnetlist - not including WINS.
- **************************************************************************/
-struct subnet_record *find_subnet(struct in_addr bcast_ip)
-{
- struct subnet_record *d;
-
- /* search through subnet list for broadcast/netmask that matches
- the source ip address. */
-
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
- {
- if (same_net(bcast_ip, d->bcast_ip, d->mask_ip))
- return d;
- }
-
- return (NULL);
-}
-
-
-/****************************************************************************
- finds the appropriate subnet structure. directed packets (non-bcast) are
- assumed to come from a point-to-point (P or M node), and so the subnet we
- return in this instance is the WINS 'pseudo-subnet' with ip 255.255.255.255
- ****************************************************************************/
-struct subnet_record *find_req_subnet(struct in_addr ip, BOOL bcast)
-{
- if (bcast)
- {
- /* identify the subnet the broadcast request came from */
- return find_subnet(*iface_bcast(ip));
- }
- /* Return the subnet with the pseudo-ip of 255.255.255.255 */
- return wins_subnet;
-}
-
-/****************************************************************************
- find a subnet in the subnetlist - if the subnet is not found
- then return the WINS subnet.
- **************************************************************************/
-struct subnet_record *find_subnet_all(struct in_addr bcast_ip)
-{
- struct subnet_record *d = find_subnet(bcast_ip);
- if(!d)
- return wins_subnet;
- return d;
-}
-
-/****************************************************************************
- create a domain entry
- ****************************************************************************/
-static struct subnet_record *make_subnet(struct in_addr bcast_ip, struct in_addr mask_ip, BOOL add)
-{
- struct subnet_record *d;
- d = (struct subnet_record *)malloc(sizeof(*d));
-
- if (!d) return(NULL);
-
- bzero((char *)d,sizeof(*d));
-
- DEBUG(4, ("making subnet %s ", inet_ntoa(bcast_ip)));
- DEBUG(4, ("%s\n", inet_ntoa(mask_ip)));
-
- d->bcast_ip = bcast_ip;
- d->mask_ip = mask_ip;
- d->workgrouplist = NULL;
-
- if(add)
- add_subnet(d);
-
- return d;
-}
-
-/****************************************************************************
- add a domain entry. creates a workgroup, if necessary, and adds the domain
- to the named a workgroup.
- ****************************************************************************/
-static struct subnet_record *add_subnet_entry(struct in_addr bcast_ip,
- struct in_addr mask_ip, char *name,
- BOOL create_subnets, BOOL add)
-{
- struct subnet_record *d = NULL;
-
- if (zero_ip(bcast_ip))
- bcast_ip = *iface_bcast(bcast_ip);
-
- /* Note that we should also add into the WINS subnet as add_subnet_entry
- should be called to add NetBIOS names and server entries on all
- interfaces, including the WINS interface
- */
-
- if(create_subnets == True)
- {
- /* Create new subnets. */
- if((d = make_subnet(bcast_ip, mask_ip, add)) == NULL)
- {
- DEBUG(0,("add_subnet_entry: Unable to create subnet %s\n",
- inet_ntoa(bcast_ip) ));
- return NULL;
- }
- return d;
- }
- if(ip_equal(bcast_ip, wins_ip))
- return wins_subnet;
- return find_subnet(bcast_ip);
-}
-
-/****************************************************************************
- Add a workgroup into a subnet, and if it's our primary workgroup,
- add the required names to it.
-**************************************************************************/
-
-void add_workgroup_to_subnet( struct subnet_record *d, char *group)
-{
- struct work_record *w = NULL;
-
- DEBUG(5,("add_workgroup_to_subnet: Adding workgroup %s to subnet %s\n",
- group, inet_ntoa(d->bcast_ip)));
-
- /* This next statement creates the workgroup struct if it doesn't
- already exist.
- */
- if((w = find_workgroupstruct(d, group, True)) == NULL)
- {
- DEBUG(0,("add_workgroup_to_subnet: Unable to add workgroup %s to subnet %s\n",
- group, inet_ntoa(d->bcast_ip) ));
- return;
- }
-
- /* add WORKGROUP(00) entries into name database
- or register with WINS server, if it's our workgroup.
- */
- if (strequal(myworkgroup, group))
- {
- int n;
-
- add_my_name_entry(d,group,0x0 ,nb_type|NB_ACTIVE|NB_GROUP);
-
- /* Only register the WORKGROUP<0x1e> name if we could be a local master
- browser. */
- if(lp_local_master())
- add_my_name_entry(d,group,0x1e,nb_type|NB_ACTIVE|NB_GROUP);
-
- /* Add all our server names to the workgroup list. We remove any
- browser or logon server flags from all but the primary name.
- */
- for( n = 0; my_netbios_names[n]; n++)
- {
- char *name = my_netbios_names[n];
- int stype = w->ServerType;
-
- if(!strequal(myname, name))
- stype &= ~(SV_TYPE_MASTER_BROWSER|SV_TYPE_POTENTIAL_BROWSER|
- SV_TYPE_DOMAIN_MASTER|SV_TYPE_DOMAIN_MEMBER);
-
- add_server_entry(d,w,name,stype|SV_TYPE_LOCAL_LIST_ONLY,0,
- lp_serverstring(),True);
- DEBUG(3,("add_workgroup_to_subnet: Added server name entry %s \
-to subnet %s\n", name, inet_ntoa(d->bcast_ip)));
- }
- }
-}
-
-/****************************************************************************
- create subnet / workgroup / server entries
-
- - add or create the subnet lists
- - add or create the workgroup entries in each subnet entry
- - register appropriate NetBIOS names for the workgroup entries
-
-**************************************************************************/
-void add_my_subnets(char *group)
-{
- static BOOL create_subnets = True;
- struct subnet_record *d = NULL;
- struct interface *i = NULL;
-
- if (*group == '*') return;
-
- /* Create subnets from all the local interfaces and thread them onto
- the linked list.
- */
- for (i = local_interfaces; i; i = i->next)
- {
- add_subnet_entry(i->bcast,i->nmask,group, create_subnets, True);
- }
-
- /* If we are using WINS, then we must add the workgroup to the WINS
- subnet. This is used as a place to keep collated server lists.
- */
-
- /* Create the WINS subnet if we are using WINS - but don't thread it
- onto the linked subnet list.
- */
- if (lp_wins_support() || lp_wins_server())
- {
- struct in_addr wins_nmask = ipzero;
- wins_subnet = add_subnet_entry(wins_ip, wins_nmask, group, create_subnets, False);
- }
-
- /* Ensure we only create the subnets once. */
- create_subnets = False;
-
- /* Now we have created all the subnets - we can add the names
- that make us a client member in the workgroup.
- */
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d))
- add_workgroup_to_subnet(d, group);
-}
-
-/*******************************************************************
- write out browse.dat
- ******************************************************************/
-void write_browse_list(time_t t)
-{
- struct subnet_record *d;
- pstring fname,fnamenew;
- FILE *f;
-
- static time_t lasttime = 0;
-
- if (!lasttime) lasttime = t;
- if (!updatedlists || t - lasttime < 5) return;
-
- lasttime = t;
- updatedlists = False;
- updatecount++;
-
- dump_names();
- dump_workgroups();
-
- pstrcpy(fname,lp_lockdir());
- trim_string(fname,NULL,"/");
- strcat(fname,"/");
- strcat(fname,SERVER_LIST);
- pstrcpy(fnamenew,fname);
- strcat(fnamenew,".");
-
- f = fopen(fnamenew,"w");
-
- if (!f)
- {
- DEBUG(4,("Can't open %s - %s\n",fnamenew,strerror(errno)));
- return;
- }
-
- for (d = FIRST_SUBNET; d ; d = NEXT_SUBNET_INCLUDING_WINS(d))
- {
- struct work_record *work;
- for (work = d->workgrouplist; work ; work = work->next)
- {
- struct server_record *s;
- for (s = work->serverlist; s ; s = s->next)
- {
- fstring tmp;
-
- /* don't list domains I don't have a master for */
- if ((s->serv.type & SV_TYPE_DOMAIN_ENUM) && !s->serv.comment[0])
- {
- continue;
- }
-
- /* output server details, plus what workgroup/domain
- they're in. without the domain information, the
- combined list of all servers in all workgroups gets
- sent to anyone asking about any workgroup! */
-
- sprintf(tmp, "\"%s\"", s->serv.name);
- fprintf(f, "%-25s ", tmp);
- fprintf(f, "%08x ", s->serv.type);
- sprintf(tmp, "\"%s\" ", s->serv.comment);
- fprintf(f, "%-30s", tmp);
- fprintf(f, "\"%s\"\n", work->work_group);
- }
- }
- }
-
- fclose(f);
- unlink(fname);
- chmod(fnamenew,0644);
- rename(fnamenew,fname);
- DEBUG(3,("Wrote browse list %s\n",fname));
-}
-
diff --git a/source/namedbwork.c b/source/namedbwork.c
deleted file mode 100644
index a6260aab467..00000000000
--- a/source/namedbwork.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-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.
-
- Revision History:
-
- 14 jan 96: lkcl@pires.co.uk
- added multiple workgroup domain master support
-
- 04 jul 96: lkcl@pires.co.uk
- created module namedbwork containing workgroup database functions
-
-*/
-
-#include "includes.h"
-#include "smb.h"
-
-extern int ClientNMB;
-
-extern int DEBUGLEVEL;
-
-/* this is our domain/workgroup/server database */
-extern struct subnet_record *subnetlist;
-
-extern struct in_addr wins_ip;
-
-extern fstring myworkgroup;
-
-int workgroup_count = 0; /* unique index key: one for each workgroup */
-
-
-
-/****************************************************************************
- add a workgroup into the domain list
- **************************************************************************/
-static void add_workgroup(struct work_record *work, struct subnet_record *d)
-{
- struct work_record *w2;
-
- if (!work || !d) return;
-
- if (!d->workgrouplist)
- {
- d->workgrouplist = work;
- work->prev = NULL;
- work->next = NULL;
- return;
- }
-
- for (w2 = d->workgrouplist; w2->next; w2 = w2->next);
-
- w2->next = work;
- work->next = NULL;
- work->prev = w2;
-}
-
-
-/****************************************************************************
- create a blank workgroup
- **************************************************************************/
-static struct work_record *make_workgroup(char *name)
-{
- struct work_record *work;
- struct subnet_record *d;
- int t = -1;
-
- if (!name || !name[0]) return NULL;
-
- work = (struct work_record *)malloc(sizeof(*work));
- if (!work) return(NULL);
- bzero((char *)work, sizeof(*work));
-
- StrnCpy(work->work_group,name,sizeof(work->work_group)-1);
- work->serverlist = NULL;
-
- work->ServerType = lp_default_server_announce() | (lp_local_master() ?
- SV_TYPE_POTENTIAL_BROWSER : 0 );
- work->RunningElection = False;
- work->ElectionCount = 0;
- work->announce_interval = 0;
- work->needelection = False;
- work->needannounce = True;
- work->mst_state = MST_POTENTIAL;
- work->dom_state = DOMAIN_NONE;
- work->log_state = LOGON_NONE;
-
- /* make sure all token representations of workgroups are unique */
-
- for (d = FIRST_SUBNET; d && t == -1; d = NEXT_SUBNET_INCLUDING_WINS(d))
- {
- struct work_record *w;
- for (w = d->workgrouplist; w && t == -1; w = w->next)
- {
- if (strequal(w->work_group, work->work_group)) t = w->token;
- }
- }
-
- if (t == -1)
- {
- work->token = ++workgroup_count;
- }
- else
- {
- work->token = t;
- }
-
-
- /* WfWg uses 01040b01 */
- /* Win95 uses 01041501 */
- /* NTAS uses ???????? */
- work->ElectionCriterion = (MAINTAIN_LIST)|(ELECTION_VERSION<<8);
- work->ElectionCriterion |= (lp_os_level() << 24);
- if (lp_domain_master()) {
- work->ElectionCriterion |= 0x80;
- }
-
- return work;
-}
-
-
-/*******************************************************************
- remove workgroups
- ******************************************************************/
-struct work_record *remove_workgroup(struct subnet_record *d,
- struct work_record *work,
- BOOL remove_all_servers)
-{
- struct work_record *ret_work = NULL;
-
- if (!d || !work) return NULL;
-
- DEBUG(3,("Removing old workgroup %s\n", work->work_group));
-
- ret_work = work->next;
-
- remove_old_servers(work, -1, remove_all_servers);
-
- if (!work->serverlist)
- {
- if (work->prev) work->prev->next = work->next;
- if (work->next) work->next->prev = work->prev;
-
- if (d->workgrouplist == work) d->workgrouplist = work->next;
-
- free(work);
- }
-
- return ret_work;
-}
-
-
-/****************************************************************************
- find a workgroup in the workgrouplist
- only create it if the domain allows it, or the parameter 'add' insists
- that it get created/added anyway. this allows us to force entries in
- lmhosts file to be added.
- **************************************************************************/
-struct work_record *find_workgroupstruct(struct subnet_record *d,
- fstring name, BOOL add)
-{
- struct work_record *ret, *work;
-
- if (!d) return NULL;
-
- DEBUG(4, ("workgroup search for %s: ", name));
-
- for (ret = d->workgrouplist; ret; ret = ret->next) {
- if (!strcmp(ret->work_group,name)) {
- DEBUG(4, ("found\n"));
- return(ret);
- }
- }
-
- if (!add) {
- DEBUG(4, ("not found\n"));
- return NULL;
- }
-
- DEBUG(4,("not found: creating\n"));
-
- if ((work = make_workgroup(name)))
- {
- if (!ip_equal(d->bcast_ip, wins_ip) &&
- lp_preferred_master() && lp_local_master() &&
- strequal(myworkgroup, name))
- {
- DEBUG(3, ("preferred master startup for %s\n", work->work_group));
- work->needelection = True;
- work->ElectionCriterion |= (1<<3);
- }
- add_workgroup(work, d);
- return(work);
- }
- return NULL;
-}
-
-
-/****************************************************************************
- dump a copy of the workgroup/domain database
- **************************************************************************/
-void dump_workgroups(void)
-{
- struct subnet_record *d;
-
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d))
- {
- if (d->workgrouplist)
- {
- struct work_record *work;
-
- DEBUG(4,("dump domain bcast=%15s: ", inet_ntoa(d->bcast_ip)));
- DEBUG(4,(" netmask=%15s:\n", inet_ntoa(d->mask_ip)));
-
- for (work = d->workgrouplist; work; work = work->next)
- {
- DEBUG(4,("\t%s(%d)\n", work->work_group, work->token));
- if (work->serverlist)
- {
- struct server_record *s;
- for (s = work->serverlist; s; s = s->next)
- {
- DEBUG(4,("\t\t%s %8x (%s)\n",
- s->serv.name, s->serv.type, s->serv.comment));
- }
- }
- }
- }
- }
-}
diff --git a/source/nameelect.c b/source/nameelect.c
deleted file mode 100644
index 5fd1a4bdf2e..00000000000
--- a/source/nameelect.c
+++ /dev/null
@@ -1,855 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-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.
-
- Module name: nameelect.c
-
- Revision History:
-
- 14 jan 96: lkcl@pires.co.uk
- added multiple workgroup domain master support
-
- 04 jul 96: lkcl@pires.co.uk
- added system to become a master browser by stages.
-
-
-*/
-
-#include "includes.h"
-
-extern int ClientNMB;
-extern int ClientDGRAM;
-
-extern int DEBUGLEVEL;
-extern pstring scope;
-
-extern pstring myname;
-extern fstring myworkgroup;
-extern struct in_addr ipzero;
-extern struct in_addr wins_ip;
-
-/* here are my election parameters */
-
-extern time_t StartupTime;
-
-extern struct subnet_record *subnetlist;
-
-extern uint16 nb_type; /* samba's NetBIOS name type */
-
-
-/*******************************************************************
- occasionally check to see if the master browser is around
- ******************************************************************/
-void check_master_browser(time_t t)
-{
- static time_t lastrun=0;
- struct subnet_record *d;
-
- if (!lastrun) lastrun = t;
- if (t < lastrun + CHECK_TIME_MST_BROWSE * 60) return;
-
- lastrun = t;
-
- dump_workgroups();
-
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
- {
- struct work_record *work;
-
- for (work = d->workgrouplist; work; work = work->next)
- {
- if (strequal(work->work_group, myworkgroup) && !AM_MASTER(work))
- {
- if (lp_local_master() && lp_preferred_master())
- {
- /* potential master browser - not a master browser. force
- becoming a master browser, hence the log message.
- */
-
- DEBUG(2,("%s potential master for %s %s - force election\n",
- timestring(), work->work_group,
- inet_ntoa(d->bcast_ip)));
-
- browser_gone(work->work_group, d->bcast_ip);
- }
- else
- {
- /* if we are not the browse master of a workgroup,
- and we can't find a browser on the subnet, do
- something about it.
- */
-
- queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_MST_CHK,
- work->work_group,0x1d,0,0,0,NULL,NULL,
- True,False,d->bcast_ip,d->bcast_ip);
- }
- }
- }
- }
-}
-
-
-/*******************************************************************
- what to do if a master browser DOESN't exist.
-
- option 1: force an election, and participate in it
- option 2: force an election, and let everyone else participate.
-
- ******************************************************************/
-void browser_gone(char *work_name, struct in_addr ip)
-{
- struct subnet_record *d = find_subnet(ip);
- struct work_record *work = find_workgroupstruct(d, work_name, False);
-
- /* i don't know about this workgroup, therefore i don't care */
- if (!work || !d) return;
-
- /* don't do election stuff on the WINS subnet */
- if (ip_equal(d->bcast_ip,wins_ip))
- return;
-
- if (strequal(work->work_group, myworkgroup))
- {
-
- if (lp_local_master())
- {
- /* we have discovered that there is no local master
- browser, and we are configured to initiate
- an election under exactly such circumstances.
- */
- DEBUG(2,("Forcing election on %s %s\n",
- work->work_group,inet_ntoa(d->bcast_ip)));
-
- /* we can attempt to become master browser */
- work->needelection = True;
- }
- else
- {
- /* we need to force an election, because we are configured
- not to _become_ the local master, but we still _need_ one,
- having detected that one doesn't exist.
- */
-
- /* local interfaces: force an election */
- send_election(d, work->work_group, 0, 0, myname);
-
- /* only removes workgroup completely on a local interface
- persistent lmhosts entries on a local interface _will_ be removed).
- */
- remove_workgroup(d, work,True);
- add_workgroup_to_subnet(d, work->work_group);
- }
- }
-}
-
-
-/****************************************************************************
- send an election packet
- **************************************************************************/
-void send_election(struct subnet_record *d, char *group,uint32 criterion,
- int timeup,char *name)
-{
- pstring outbuf;
- char *p;
-
- if (!d) return;
-
- DEBUG(2,("Sending election to %s for workgroup %s\n",
- inet_ntoa(d->bcast_ip),group));
-
- bzero(outbuf,sizeof(outbuf));
- p = outbuf;
- CVAL(p,0) = ANN_Election; /* election */
- p++;
-
- CVAL(p,0) = (criterion == 0 && timeup == 0) ? 0 : ELECTION_VERSION;
- SIVAL(p,1,criterion);
- SIVAL(p,5,timeup*1000); /* ms - despite the spec */
- p += 13;
- pstrcpy(p,name);
- strupper(p);
- p = skip_string(p,1);
-
- send_mailslot_reply(False,BROWSE_MAILSLOT,ClientDGRAM,
- outbuf,PTR_DIFF(p,outbuf),
- name,group,0,0x1e,d->bcast_ip,*iface_ip(d->bcast_ip));
-}
-
-
-/****************************************************************************
- un-register a SELF name that got rejected.
-
- if this name happens to be rejected when samba is in the process
- of becoming a master browser (registering __MSBROWSE__, WORKGROUP(1d)
- or WORKGROUP(1b)) then we must stop being a master browser. sad.
-
- **************************************************************************/
-void name_unregister_work(struct subnet_record *d, char *name, int name_type)
-{
- struct work_record *work;
- int remove_type_local = 0;
- int remove_type_domain = 0;
- int remove_type_logon = 0;
-
- remove_netbios_name(d,name,name_type,SELF,ipzero);
-
- if (!(work = find_workgroupstruct(d, name, False))) return;
-
- /* work out what to unbecome, from the name type being removed */
-
- if (ms_browser_name(name, name_type))
- {
- remove_type_local |= SV_TYPE_MASTER_BROWSER;
- }
- if (AM_MASTER(work) && strequal(name, myworkgroup) && name_type == 0x1d)
- {
- remove_type_local |= SV_TYPE_MASTER_BROWSER;
- }
- if (AM_DOMMST(work) && strequal(name, myworkgroup) && name_type == 0x1b)
- {
- remove_type_domain |= SV_TYPE_DOMAIN_MASTER;
- }
- if (AM_DOMMEM(work) && strequal(name, myworkgroup) && name_type == 0x1c)
- {
- remove_type_logon|= SV_TYPE_DOMAIN_MEMBER;
- }
-
- if (remove_type_local ) unbecome_local_master (d, work, remove_type_local );
- if (remove_type_domain) unbecome_domain_master(d, work, remove_type_domain);
- if (remove_type_logon ) unbecome_logon_server (d, work, remove_type_logon );
-}
-
-
-/****************************************************************************
- registers a name.
-
- if the name being added is a SELF name, we must additionally check
- whether to proceed to the next stage in samba becoming a master browser.
-
- **************************************************************************/
-void name_register_work(struct subnet_record *d, char *name, int name_type,
- int nb_flags, time_t ttl, struct in_addr ip, BOOL bcast)
-{
- enum name_source source = (ismyip(ip) || ip_equal(ip, ipzero)) ?
- SELF : REGISTER;
-
- if (source == SELF)
- {
- struct work_record *work = find_workgroupstruct(d,
- myworkgroup, False);
-
- add_netbios_entry(d,name,name_type,nb_flags,ttl,source,ip,True,!bcast);
-
- if (work)
- {
- int add_type_local = False;
- int add_type_domain = False;
- int add_type_logon = False;
-
- DEBUG(4,("checking next stage: name_register_work %s\n", name));
-
- /* work out what to become, from the name type being added */
-
- if (ms_browser_name(name, name_type))
- {
- add_type_local = True;
- }
- if (strequal(name, myworkgroup) && name_type == 0x1d)
- {
- add_type_local = True;
- }
- if (strequal(name, myworkgroup) && name_type == 0x1b)
- {
- add_type_domain = True;
- }
- if (strequal(name, myworkgroup) && name_type == 0x1c)
- {
- add_type_logon = True;
- }
-
- if (add_type_local ) become_local_master (d, work);
- if (add_type_domain) become_domain_master(d, work);
- if (add_type_logon ) become_logon_server (d, work);
- }
- }
-}
-
-
-/*******************************************************************
- become the local master browser.
-
- this is done in stages. note that this could take a while,
- particularly on a broadcast subnet, as we have to wait for
- the implicit registration of each name to be accepted.
-
- as each name is successfully registered, become_local_master() is
- called again, in order to initiate the next stage. see
- dead_netbios_entry() - deals with implicit name registration
- and response_name_reg() - deals with explicit registration
- with a WINS server.
-
- stage 1: was MST_POTENTIAL - go to MST_POTENTIAL and register ^1^2__MSBROWSE__^2^1.
- stage 2: was MST_BACK - go to MST_MSB and register WORKGROUP(0x1d)
- stage 3: was MST_MSB - go to MST_BROWSER and stay there
-
- XXXX note: this code still does not cope with the distinction
- between different types of nodes, particularly between M and P
- nodes. that comes later.
-
- ******************************************************************/
-void become_local_master(struct subnet_record *d, struct work_record *work)
-{
- /* domain type must be limited to domain enum + server type. it must
- not have SV_TYPE_SERVER or anything else with SERVER in it, else
- clients get confused and start thinking this entry is a server
- not a workgroup
- */
- uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT;
-
- if (!work || !d)
- return;
-
- if (!lp_local_master())
- {
- DEBUG(0,("Samba not configured as a local master browser.\n"));
- return;
- }
-
- DEBUG(2,("Becoming master for %s %s (currently at stage %d)\n",
- work->work_group,inet_ntoa(d->bcast_ip),work->mst_state));
-
- switch (work->mst_state)
- {
- case MST_POTENTIAL: /* while we were nothing but a server... */
- {
- DEBUG(3,("go to first stage: register ^1^2__MSBROWSE__^2^1\n"));
- work->mst_state = MST_BACK; /* an election win was successful */
-
- work->ElectionCriterion |= 0x5;
-
- /* update our server status */
- work->ServerType &= ~SV_TYPE_POTENTIAL_BROWSER;
- add_server_entry(d,work,myname,work->ServerType|SV_TYPE_LOCAL_LIST_ONLY,
- 0,lp_serverstring(),True);
-
- /* add special browser name */
- add_my_name_entry(d,MSBROWSE,0x01,nb_type|NB_ACTIVE|NB_GROUP);
-
- /* DON'T do anything else after calling add_my_name_entry() */
- break;
- }
-
- case MST_BACK: /* while nothing had happened except we won an election... */
- {
- DEBUG(3,("go to second stage: register as master browser\n"));
- work->mst_state = MST_MSB; /* registering MSBROWSE was successful */
-
- /* add server entry on successful registration of MSBROWSE */
- add_server_entry(d,work,work->work_group,domain_type|SV_TYPE_LOCAL_LIST_ONLY,
- 0,myname,True);
-
- /* add master name */
- add_my_name_entry(d,work->work_group,0x1d,nb_type|NB_ACTIVE);
-
- /* DON'T do anything else after calling add_my_name_entry() */
- break;
- }
-
- case MST_MSB: /* while we were still only registered MSBROWSE state... */
- {
- int i = 0;
- struct server_record *sl;
-
- DEBUG(3,("2nd stage complete: registered as master browser for workgroup %s \
-on subnet %s\n", work->work_group, inet_ntoa(d->bcast_ip)));
- work->mst_state = MST_BROWSER; /* registering WORKGROUP(1d) succeeded */
-
- /* update our server status */
- work->ServerType |= SV_TYPE_MASTER_BROWSER;
-
- DEBUG(3,("become_local_master: updating our server %s to type %x\n",
- myname, work->ServerType));
-
- add_server_entry(d,work,myname,work->ServerType|SV_TYPE_LOCAL_LIST_ONLY,
- 0,lp_serverstring(),True);
-
- /* Count the number of servers we have on our list. If it's
- less than 10 (just a heuristic) request the servers
- to announce themselves.
- */
- for( sl = work->serverlist; sl != NULL; sl = sl->next)
- i++;
-
- if (i < 10)
- {
- /* ask all servers on our local net to announce to us */
- announce_request(work, d->bcast_ip);
- }
-
- /* Reset the announce master timer so that we do an announce as soon as possible
- now we are a master. */
- reset_announce_timer();
-
- DEBUG(0,("Samba is now a local master browser for workgroup %s on subnet %s\n",
- work->work_group, inet_ntoa(d->bcast_ip)));
-
- break;
- }
-
- case MST_BROWSER:
- {
- /* don't have to do anything: just report success */
- DEBUG(3,("3rd stage: become master browser!\n"));
- break;
- }
- }
-}
-
-
-/*******************************************************************
- become the domain master browser.
-
- this is done in stages. note that this could take a while,
- particularly on a broadcast subnet, as we have to wait for
- the implicit registration of each name to be accepted.
-
- as each name is successfully registered, become_domain_master() is
- called again, in order to initiate the next stage. see
- dead_netbios_entry() - deals with implicit name registration
- and response_name_reg() - deals with explicit registration
- with a WINS server.
-
- stage 1: was DOMAIN_NONE - go to DOMAIN_MST
-
- XXXX note: this code still does not cope with the distinction
- between different types of nodes, particularly between M and P
- nodes. that comes later.
-
- ******************************************************************/
-void become_domain_master(struct subnet_record *d, struct work_record *work)
-{
- /* domain type must be limited to domain enum + server type. it must
- not have SV_TYPE_SERVER or anything else with SERVER in it, else
- clients get confused and start thinking this entry is a server
- not a workgroup
- */
-
- if (!work || !d) return;
-
- if (!lp_domain_master())
- {
- DEBUG(0,("Samba not configured as a domain master browser.\n"));
- return;
- }
-
- DEBUG(2,("Becoming domain master for %s %s (currently at stage %d)\n",
- work->work_group,inet_ntoa(d->bcast_ip),work->dom_state));
-
- switch (work->dom_state)
- {
- case DOMAIN_NONE: /* while we were nothing but a server... */
- {
- DEBUG(3,("become_domain_master: go to first stage: register <1b> name\n"));
- work->dom_state = DOMAIN_WAIT;
-
- /* XXXX the 0x1b is domain master browser name */
- add_my_name_entry(d, work->work_group,0x1b,nb_type|NB_ACTIVE);
-
- /* DON'T do anything else after calling add_my_name_entry() */
- break;
- }
-
- case DOMAIN_WAIT:
- {
- work->dom_state = DOMAIN_MST; /* ... become domain master */
- DEBUG(3,("become_domain_master: first stage - register as domain member\n"));
-
- /* update our server status */
- work->ServerType |= SV_TYPE_NT|SV_TYPE_DOMAIN_MASTER;
- add_server_entry(d,work,myname,work->ServerType|SV_TYPE_LOCAL_LIST_ONLY,
- 0, lp_serverstring(),True);
-
- DEBUG(0,("Samba is now a domain master browser for workgroup %s on subnet %s\n",
- work->work_group, inet_ntoa(d->bcast_ip)));
-
- if (d == wins_subnet)
- {
- /* ok! we successfully registered by unicast with the
- WINS server. we now expect to become the domain
- master on the local subnets. if this fails, it's
- probably a 1.9.16p2 to 1.9.16p11 server's fault.
-
- this is a configuration issue that should be addressed
- by the network administrator - you shouldn't have
- several machines configured as a domain master browser
- for the same WINS scope (except if they are 1.9.17 or
- greater, and you know what you're doing.
-
- see DOMAIN.txt.
-
- */
- add_domain_master_bcast();
- }
- break;
- }
-
- case DOMAIN_MST:
- {
- /* don't have to do anything: just report success */
- DEBUG(3,("domain second stage: there isn't one!\n"));
- break;
- }
- }
-}
-
-
-/*******************************************************************
- become a logon server.
- ******************************************************************/
-void become_logon_server(struct subnet_record *d, struct work_record *work)
-{
- if (!work || !d) return;
-
- if (!lp_domain_logons())
- {
- DEBUG(0,("samba not configured as a logon master.\n"));
- return;
- }
-
- DEBUG(2,("Becoming logon server for %s %s (currently at stage %d)\n",
- work->work_group,inet_ntoa(d->bcast_ip),work->log_state));
-
- switch (work->log_state)
- {
- case LOGON_NONE: /* while we were nothing but a server... */
- {
- DEBUG(3,("go to first stage: register <1c> name\n"));
- work->log_state = LOGON_WAIT;
-
- /* XXXX the 0x1c is apparently something to do with domain logons */
- add_my_name_entry(d, myworkgroup,0x1c,nb_type|NB_ACTIVE|NB_GROUP);
-
- /* DON'T do anything else after calling add_my_name_entry() */
- break;
- }
-
- case LOGON_WAIT:
- {
- work->log_state = LOGON_SRV; /* ... become logon server */
- DEBUG(3,("logon second stage: register \n"));
-
- /* update our server status */
- work->ServerType |= SV_TYPE_NT|SV_TYPE_DOMAIN_MEMBER;
- add_server_entry(d,work,myname,work->ServerType|SV_TYPE_LOCAL_LIST_ONLY
- ,0, lp_serverstring(),True);
-
- /* DON'T do anything else after calling add_my_name_entry() */
- break;
- }
-
- case LOGON_SRV:
- {
- DEBUG(3,("logon third stage: there isn't one!\n"));
- break;
- }
- }
-}
-
-
-/*******************************************************************
- unbecome the local master browser. initates removal of necessary netbios
- names, and tells the world that we are no longer a master browser.
-
- XXXX this _should_ be used to demote to a backup master browser, without
- going straight to non-master browser. another time.
-
- ******************************************************************/
-void unbecome_local_master(struct subnet_record *d, struct work_record *work,
- int remove_type)
-{
- int new_server_type = work->ServerType;
-
- /* can only remove master types with this function */
- remove_type &= SV_TYPE_MASTER_BROWSER;
-
- new_server_type &= ~remove_type;
-
- if (remove_type)
- {
- DEBUG(2,("Becoming local non-master for %s\n",work->work_group));
-
- /* no longer a master browser of any sort */
-
- work->ServerType |= SV_TYPE_POTENTIAL_BROWSER;
- work->ElectionCriterion &= ~0x4;
- work->mst_state = MST_POTENTIAL;
-
- /* announce ourselves as no longer active as a master browser. */
- announce_server(d, work, work->work_group, myname, 0, 0);
- remove_name_entry(d,MSBROWSE ,0x01);
- remove_name_entry(d,work->work_group,0x1d);
- }
-}
-
-
-/*******************************************************************
- unbecome the domain master browser. initates removal of necessary netbios
- names, and tells the world that we are no longer a domain browser.
- ******************************************************************/
-void unbecome_domain_master(struct subnet_record *d, struct work_record *work,
- int remove_type)
-{
- int new_server_type = work->ServerType;
-
- DEBUG(2,("Becoming domain non-master for %s\n",work->work_group));
-
- /* can only remove master or domain types with this function */
- remove_type &= SV_TYPE_DOMAIN_MASTER;
-
- new_server_type &= ~remove_type;
-
- if (remove_type)
- {
- /* no longer a domain master browser of any sort */
-
- work->dom_state = DOMAIN_NONE;
-
- /* announce ourselves as no longer active as a master browser on
- all our local subnets. */
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
- {
- work = find_workgroupstruct(d, myworkgroup, False);
-
- /* Remove the name entry without any NetBIOS traffic as that's
- how it was registered. */
- remove_name_entry(d,work->work_group,0x1b);
- }
-
- /* Unregister the 1b name from the WINS server. */
- if(wins_subnet != NULL)
- remove_name_entry(wins_subnet, myworkgroup, 0x1b);
- }
-}
-
-
-/*******************************************************************
- unbecome the logon server. initates removal of necessary netbios
- names, and tells the world that we are no longer a logon server.
- ******************************************************************/
-void unbecome_logon_server(struct subnet_record *d, struct work_record *work,
- int remove_type)
-{
- int new_server_type = work->ServerType;
-
- DEBUG(2,("Becoming logon non-server for %s\n",work->work_group));
-
- /* can only remove master or domain types with this function */
- remove_type &= SV_TYPE_DOMAIN_MEMBER;
-
- new_server_type &= ~remove_type;
-
- if (remove_type)
- {
- /* no longer a master browser of any sort */
-
- work->log_state = LOGON_NONE;
-
- remove_name_entry(d,work->work_group,0x1c);
- }
-}
-
-
-/*******************************************************************
- run the election
- ******************************************************************/
-void run_elections(time_t t)
-{
- static time_t lastime = 0;
-
- struct subnet_record *d;
-
- /* send election packets once a second */
- if (lastime && t-lastime <= 0) return;
-
- lastime = t;
-
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
- {
- struct work_record *work;
-
- for (work = d->workgrouplist; work; work = work->next)
- {
- if (work->RunningElection)
- {
- send_election(d,work->work_group, work->ElectionCriterion,
- t-StartupTime,myname);
-
- if (work->ElectionCount++ >= 4)
- {
- /* I won! now what :-) */
- DEBUG(2,(">>> Won election on %s %s <<<\n",
- work->work_group,inet_ntoa(d->bcast_ip)));
-
- work->RunningElection = False;
- work->mst_state = MST_POTENTIAL;
-
- become_local_master(d, work);
- }
- }
- }
- }
-}
-
-
-/*******************************************************************
- work out if I win an election
- ******************************************************************/
-static BOOL win_election(struct work_record *work,int version,uint32 criterion,
- int timeup,char *name)
-{
- int mytimeup = time(NULL) - StartupTime;
- uint32 mycriterion = work->ElectionCriterion;
-
- /* If local master is false then never win
- in election broadcasts. */
- if(!lp_local_master())
- {
- DEBUG(3,("win_election: Losing election as local master == False\n"));
- return False;
- }
-
- DEBUG(4,("election comparison: %x:%x %x:%x %d:%d %s:%s\n",
- version,ELECTION_VERSION,
- criterion,mycriterion,
- timeup,mytimeup,
- name,myname));
-
- if (version > ELECTION_VERSION) return(False);
- if (version < ELECTION_VERSION) return(True);
-
- if (criterion > mycriterion) return(False);
- if (criterion < mycriterion) return(True);
-
- if (timeup > mytimeup) return(False);
- if (timeup < mytimeup) return(True);
-
- if (strcasecmp(myname,name) > 0) return(False);
-
- return(True);
-}
-
-
-/*******************************************************************
- process a election packet
-
- An election dynamically decides who will be the master.
- ******************************************************************/
-void process_election(struct packet_struct *p,char *buf)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- struct in_addr ip = dgram->header.source_ip;
- struct subnet_record *d = find_subnet(ip);
- int version = CVAL(buf,0);
- uint32 criterion = IVAL(buf,1);
- int timeup = IVAL(buf,5)/1000;
- char *name = buf+13;
- struct work_record *work;
-
- if (!d) return;
-
- if (ip_equal(d->bcast_ip,wins_ip))
- {
- DEBUG(0,("Unexpected election request from %s %s on WINS net\n",
- name, inet_ntoa(p->ip)));
- return;
- }
-
- name[15] = 0;
-
- DEBUG(3,("Election request from %s %s vers=%d criterion=%08x timeup=%d\n",
- name,inet_ntoa(p->ip),version,criterion,timeup));
-
- if (same_context(dgram)) return;
-
- for (work = d->workgrouplist; work; work = work->next)
- {
- if (!strequal(work->work_group, myworkgroup))
- continue;
-
- if (win_election(work, version,criterion,timeup,name))
- {
- if (!work->RunningElection)
- {
- work->needelection = True;
- work->ElectionCount=0;
- work->mst_state = MST_POTENTIAL;
- }
- }
- else
- {
- work->needelection = False;
-
- if (work->RunningElection || AM_MASTER(work))
- {
- work->RunningElection = False;
- DEBUG(3,(">>> Lost election on %s %s <<<\n",
- work->work_group,inet_ntoa(d->bcast_ip)));
- if (AM_MASTER(work))
- {
- unbecome_local_master(d, work, SV_TYPE_MASTER_BROWSER);
- }
- }
- }
- }
-}
-
-
-/****************************************************************************
- checks whether a browser election is to be run on any workgroup
-
- this function really ought to return the time between election
- packets (which depends on whether samba intends to be a domain
- master or a master browser) in milliseconds.
-
- ***************************************************************************/
-BOOL check_elections(void)
-{
- struct subnet_record *d;
- BOOL run_any_election = False;
-
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
- {
- struct work_record *work;
- for (work = d->workgrouplist; work; work = work->next)
- {
- run_any_election |= work->RunningElection;
-
- if (work->needelection && !work->RunningElection)
- {
- DEBUG(3,(">>> Starting election on %s %s <<<\n",
- work->work_group,inet_ntoa(d->bcast_ip)));
- work->ElectionCount = 0;
- work->RunningElection = True;
- work->needelection = False;
- }
- }
- }
- return run_any_election;
-}
-
diff --git a/source/nameelect.doc b/source/nameelect.doc
deleted file mode 100644
index df025e2069a..00000000000
--- a/source/nameelect.doc
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- Unix SMB/Netbios documentation.
- Version 0.1
- Copyright (C) Luke Leighton Andrew Tridgell 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.
-
- Document name: nameelect.doc
-
- Revision History:
-
- 0.0 - 02jul96 : lkcl@pires.co.uk
- created
-
- 0.1 - 22jul96 Andrew.Tridgell@anu.edu.au
- tridge's comments on first revision
-*/
-
-the module nameelect.c deals with initiating, winning, losing
-browsing elections, and checking if browsers are still around,
-and the consequences of getting involved in all this.
-
-an election packet can be received at any time, which will initiate
-an election. samba can also detect that there is no longer a
-master browser and will initiate an election.
-
-there is one way to become a master browser, but there are two
-ways to un-become a master browser. if you lose an election, you
-must stop being a master browser. if you fail to register your
-unique special browser names (either on your local subnet or with
-the WINS server) then you must stop being a master browser.
-
-this is a double fail-safe mechanism to ensure that there is only
-one master browser per workgroup per subnet (and one domain master
-browser - per domain (workgroup) per wide area network).
-
-(a wide area network is created when one or more servers on a
-broadcast-isolated subnet point to the same WINS server).
-
---------
-NOTE FROM TRIDGE:
-
-I'd say "domain master browser" not "WINS server" here. WINS doesn't
-have much to do with browsing, it is the WAN varient of name
-resolution. The name resolution and browsing functions of a netbios
-network are almost entirely separate. Both grew out of systems that
-could only be used on local networks.
-
-To adapt them to WANs, WINS was added for name resolution, and "domain
-master browsers" were added for browse lists. It would be perfectly
-possible to have a WINS server that doesn't even listen to UDP port
-138.
---------
-
-/*************************************************************************
- check_elections()
- *************************************************************************/
-
-this function returns True if samba is in the process of running an
-election on any of its interfaces. a better version of this function
-should return the time-out period in between election packets, in
-milliseconds.
-
-
-/*************************************************************************
- process_election()
- *************************************************************************/
-
-this function is responsible for dealing with the receipt of an election
-browse MAILSLOT packet.
-
-if samba is running an election, it checks the criteria in the packet
-received using win_election() to see if it has lost the election or if
-it should join in the election.
-
-if it loses the election, then it becomes a non-master.
-
-
-/*************************************************************************
- win_election()
- *************************************************************************/
-
-this function returns True if samba has won an election. the criteria
-in order of precedence are:
-
-the election version; the election criteria; the time since samba was
-started; and as a last resort, a name comparison is used.
-
-
-/*************************************************************************
- run_elections()
- *************************************************************************/
-
-this function is responsible for sending out election packets if
-samba is running in an election. once the fourth packet is sent
-out, it is assumed that we have won, and samba initiates becoming
-a master browser.
-
-(it looks like samba sends out an extra packet just to be sure...)
-
-
-/*************************************************************************
- become_nonmaster()
- *************************************************************************/
-
-this function is responsible for down-grading samba's status from
-either domain master to master browser or nothing, or master browser
-to nothing, depending on its current status.
-
-samba can become a non-master in three ways: by losing an election -
-see process_election(); by having one of its special browser names
-de-registered - see name_unregister_work(); by receiving and
-processing a browser reset packet - see process_reset_browser().
-
-when samba stops being a domain master, it must release its unique
-0x1b name. when samba stops being a master browser, it must release
-its unique 0x1d name.
-
-becoming non-master is done on a per-subnet basis.
-
-
-/*************************************************************************
- become_master()
- *************************************************************************/
-
-this function is responsible for slowly turning samba into a
-local master browser or a domain master browser.
-
-
-this is done in stages. note that this could take a while,
-particularly on a broadcast subnet, as we have to wait for
-the implicit registration of each name to be accepted.
-
-as each name is successfully registered, become_master() is
-called again via name_register_work(), in order to initiate
-the next stage (see dead_netbios_entry() - deals with implicit
-name registration and response_name_reg() - deals with explicit
-registration with a WINS server).
-
-stage 1: was MST_NONE - go to MST_NONE and register ^1^2__MSBROWSE__^2^1.
-stage 2: was MST_WON - go to MST_MSB and register WORKGROUP(0x1d)
-stage 3: was MST_MSB - go to MST_BROWSER and register WORKGROUP(0x1b)
-stage 4: was MST_BROWSER - go to MST_DOMAIN (do not pass GO, do not...)
-
-note that this code still does not cope with the distinction
-between different types of nodes, particularly between M and P
-nodes (see rfc1001.txt). that will be developed later.
-
-
-/*************************************************************************
- name_register_work()
- *************************************************************************/
-
-this function is called when a NetBIOS name is successfully
-registered. it will add the registered name into samba's NetBIOS
-records.
-
-it has the additional responsibility that when samba is becoming
-a master browser, it must initiate the next stage in the progress
-towards becoming a master browser.
-
-implicit name registration is done through dead_netbios_entry()
-by time-out. explicit name registration is done through
-response_name_reg() with a WINS server.
-
-
-/*************************************************************************
- name_unregister_work()
- *************************************************************************/
-
-this function is called when there is an objection to a NetBIOS
-name being registered. this will always be done through a negative
-response to a name registration, whether it be by a host that
-already owns the unique name being registered on a subnet, or
-by a WINS server.
-
-the name being objected to must be removed from samba's records.
-
-it has the additional responsibility of checking whether samba is
-currently a master browser or not, and if so it should initiate
-becoming a non-master.
-
-
-
-/*************************************************************************
- send_election()
- *************************************************************************/
-
-this function is responsible for sending a browse mailslot
-datagram election packet (of type ANN_Election). it constructs
-the packet with all the relevant info needed to participate:
-election version; election criteria; time since startup and
-our name.
-
-this function can be used to ensure that initiate but lose an
-election by specifying a criteria and time up of zero. this
-is necessary if we are a master browser and we are about to
-go down (politely!) - see nmbd.c:sig_term().
-
-
-/*************************************************************************
- browser_gone()
- *************************************************************************/
-
-this function is responsible for dealing with the instance when
-the master browser we thought was present on a subnet is no longer
-responding.
-
-if it is samba's workgroup, and it's a local interface, samba
-detects that it can participate in an election on that interface
-and potentially become a master browser or domain master.
-
-if it's a local subnet and not one of samba's workgroups, then
-samba will force an election (which it is not obliged to do).
-remove_workgroup() will be expected to remove all references
-to this workgroup and the servers in it from the database.
-
-if it's a remote subnet and not one of samba's workgroups then
-no election is forced, and remove_workgroup() will be expected
-to remove all server entries from this workgroup _except_ those
-added from the lmhosts file. if there are entries added from
-the lmhosts file, then the workgroup entry will remain,
-otherwise it too will be removed.
-
-
-/*************************************************************************
- check_master_browser()
- *************************************************************************/
-
-this function is responsible for periodically checking whether
-master browsers that samba expects to be alive are alive. this
-is done every CHECK_TIME_MST_BROWSE minutes.
-
-for every workgroup record for which samba is not a master browser,
-on both local and remote interfaces, samba will initiate a
-broadcast query for a master browser on that subnet.
-
-(browser_gone() will be called to deal with the case where no
-response is received to the NAME_QUERY_MST_CHK initiated here.
-no action is required when a response _is_ received, however:
-see nameservresp.c:response_process() and dead_netbios_entry()
-for details)
-
-
diff --git a/source/namelogon.c b/source/namelogon.c
deleted file mode 100644
index 1f57139d56a..00000000000
--- a/source/namelogon.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-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.
-
- Revision History:
-
- 14 jan 96: lkcl@pires.co.uk
- added multiple workgroup domain master support
-
-*/
-
-#include "includes.h"
-
-extern int ClientDGRAM;
-
-#define TEST_CODE /* want to debug unknown browse packets */
-
-extern int DEBUGLEVEL;
-
-extern pstring myname;
-
-
-/****************************************************************************
- process a domain logon packet
-
- **************************************************************************/
-void process_logon_packet(struct packet_struct *p,char *buf,int len)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- char *logname,*q;
- fstring reply_name;
- BOOL add_slashes = False;
- pstring outbuf;
- int code,reply_code;
- char unknown_byte = 0;
- uint16 request_count = 0;
- uint16 token = 0;
-
- if (!lp_domain_logons())
- {
- DEBUG(3,("No domain logons\n"));
- return;
- }
-
-
- code = SVAL(buf,0);
- switch (code)
- {
- case 0:
- {
- char *machine = buf+2;
- char *user = skip_string(machine,1);
- char *tmp;
- logname = skip_string(user,1);
- tmp = skip_string(logname,1);
- unknown_byte = CVAL(tmp,0);
- request_count = SVAL(tmp,1);
- token = SVAL(tmp,3);
-
- reply_code = 0x6;
- fstrcpy(reply_name,myname);
- strupper(reply_name);
- add_slashes = True;
- DEBUG(3,("Domain login request from %s(%s) user=%s token=%x\n",
- machine,inet_ntoa(p->ip),user,token));
- break;
- }
- case 7:
- {
- char *machine = buf+2;
- logname = skip_string(machine,1);
- token = SVAL(skip_string(logname,1),0);
-
- fstrcpy(reply_name,lp_domain_controller());
- if (!*reply_name)
- {
- /* oo! no domain controller. must be us, then */
- fstrcpy(reply_name,myname);
- reply_code = 0xC;
- }
- else
- {
- /* refer logon request to the domain controller */
- reply_code = 0x7;
- }
-
- strupper(reply_name);
- DEBUG(3,("GETDC request from %s(%s), reporting %s 0x%x token=%x\n",
- machine,inet_ntoa(p->ip), reply_name, reply_code,token));
- break;
- }
- default:
- {
- DEBUG(3,("Unknown domain request %d\n",code));
- return;
- }
- }
-
- bzero(outbuf,sizeof(outbuf));
- q = outbuf;
- SSVAL(q,0,reply_code);
- q += 2;
-
- if (token == 0xffff || /* LM 2.0 or later */
- token == 0xfffe) /* WfWg networking */
- {
- if (add_slashes)
- {
- strcpy(q,"\\\\");
- q += 2;
- }
- strcpy(q, reply_name);
- strupper(q);
- q = skip_string(q,1);
-
- if (token == 0xffff) /* LM 2.0 or later */
- {
- SSVAL(q,0,token);
- q += 2;
- }
- }
-
- SSVAL(q,0,0xFFFF);
- q += 2;
-
- send_mailslot_reply(True, logname,ClientDGRAM,outbuf,PTR_DIFF(q,outbuf),
- myname,&dgram->source_name.name[0],0x20,0,p->ip,
- *iface_ip(p->ip));
-}
diff --git a/source/namelogon.doc b/source/namelogon.doc
deleted file mode 100644
index c4a97d0cf16..00000000000
--- a/source/namelogon.doc
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- Unix SMB/Netbios documentation.
- Version 0.0
- Copyright (C) Luke Leighton Andrew Tridgell 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.
-
- Document name: namelogon.doc
-
- Revision History:
-
- 0.0 - 02jul96 : lkcl@pires.co.uk
- created
-*/
-
-this module deals with the first stage of domain logons. there is much
-more work to be done on this: it's all totally undocumented.
-
-
-/*************************************************************************
- process_logon_packet()
- *************************************************************************/
-
-a function that processes logon packets (the most helpful comment yet :-).
diff --git a/source/namepacket.c b/source/namepacket.c
deleted file mode 100644
index 44e449b8c2a..00000000000
--- a/source/namepacket.c
+++ /dev/null
@@ -1,637 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-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.
-
- Revision History:
-
- 14 jan 96: lkcl@pires.co.uk
- added multiple workgroup domain master support
-
-*/
-
-#include "includes.h"
-
-extern int ClientNMB;
-extern int ClientDGRAM;
-
-extern int DEBUGLEVEL;
-
-extern int num_response_packets;
-
-BOOL CanRecurse = True;
-extern pstring scope;
-extern struct in_addr wins_ip;
-
-static uint16 name_trn_id=0;
-
-
-/***************************************************************************
- updates the unique transaction identifier
- **************************************************************************/
-void debug_browse_data(char *outbuf, int len)
-{
- int i,j;
- for (i = 0; i < len; i+= 16)
- {
- DEBUG(4, ("%3x char ", i));
-
- for (j = 0; j < 16; j++)
- {
- unsigned char x = outbuf[i+j];
- if (x < 32 || x > 127) x = '.';
-
- if (i+j >= len) break;
- DEBUG(4, ("%c", x));
- }
-
- DEBUG(4, (" hex ", i));
-
- for (j = 0; j < 16; j++)
- {
- if (i+j >= len) break;
- DEBUG(4, (" %02x", (unsigned char)outbuf[i+j]));
- }
-
- DEBUG(4, ("\n"));
- }
-
-}
-
-
-/***************************************************************************
- updates the unique transaction identifier
- **************************************************************************/
-static void update_name_trn_id(void)
-{
- if (!name_trn_id)
- {
- name_trn_id = (time(NULL)%(unsigned)0x7FFF) + (getpid()%(unsigned)100);
- }
- name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
-}
-
-
-/****************************************************************************
- initiate a netbios packet
- ****************************************************************************/
-void initiate_netbios_packet(uint16 *id,
- int fd,int quest_type,char *name,int name_type,
- int nb_flags,BOOL bcast,BOOL recurse,
- struct in_addr to_ip)
-{
- struct packet_struct p;
- struct nmb_packet *nmb = &p.packet.nmb;
- struct res_rec additional_rec;
- char *packet_type = "unknown";
- int opcode = -1;
-
- if (!id) return;
-
- if (quest_type == NMB_STATUS) { packet_type = "nmb_status"; opcode = 0; }
- if (quest_type == NMB_QUERY ) { packet_type = "nmb_query"; opcode = 0; }
- if (quest_type == NMB_REG ) { packet_type = "nmb_reg"; opcode = 5; }
- if (quest_type == NMB_REG_REFRESH ) { packet_type = "nmb_reg_refresh"; opcode = 9; }
- if (quest_type == NMB_REL ) { packet_type = "nmb_rel"; opcode = 6; }
-
- DEBUG(4,("initiating netbios packet: %s %s(%x) (bcast=%s) %s\n",
- packet_type, name, name_type, BOOLSTR(bcast), inet_ntoa(to_ip)));
-
- if (opcode == -1) return;
-
- bzero((char *)&p,sizeof(p));
-
- if (*id == 0xffff) {
- update_name_trn_id();
- *id = name_trn_id; /* allow resending with same id */
- }
-
- nmb->header.name_trn_id = *id;
- nmb->header.opcode = opcode;
- nmb->header.response = False;
-
- nmb->header.nm_flags.bcast = bcast;
- nmb->header.nm_flags.recursion_available = False;
- nmb->header.nm_flags.recursion_desired = recurse;
- nmb->header.nm_flags.trunc = False;
- nmb->header.nm_flags.authoritative = False;
-
- nmb->header.rcode = 0;
- nmb->header.qdcount = 1;
- nmb->header.ancount = 0;
- nmb->header.nscount = 0;
- nmb->header.arcount = (quest_type==NMB_REG ||
- quest_type==NMB_REL ||
- quest_type==NMB_REG_REFRESH) ? 1 : 0;
-
- make_nmb_name(&nmb->question.question_name,name,name_type,scope);
-
- nmb->question.question_type = quest_type == NMB_STATUS ? 0x21 : 0x20;
- nmb->question.question_class = 0x1;
-
- if (quest_type == NMB_REG ||
- quest_type == NMB_REG_REFRESH ||
- quest_type == NMB_REL)
- {
- nmb->additional = &additional_rec;
- bzero((char *)nmb->additional,sizeof(*nmb->additional));
-
- nmb->additional->rr_name = nmb->question.question_name;
- nmb->additional->rr_type = 0x20;
- nmb->additional->rr_class = 0x1;
-
- if (quest_type == NMB_REG || quest_type == NMB_REG_REFRESH)
- nmb->additional->ttl = lp_max_ttl();
- else
- nmb->additional->ttl = 0;
-
- nmb->additional->rdlength = 6;
- nmb->additional->rdata[0] = nb_flags;
- putip(&nmb->additional->rdata[2],(char *)iface_ip(to_ip));
- }
-
- p.ip = to_ip;
- p.port = NMB_PORT;
- p.fd = fd;
- p.timestamp = time(NULL);
- p.packet_type = NMB_PACKET;
-
- debug_nmb_packet(&p);
-
- if (!send_packet(&p)) {
- DEBUG(3,("send_packet to %s %d failed\n",inet_ntoa(p.ip),p.port));
- *id = 0xffff;
- }
-
- return;
-}
-
-
-/****************************************************************************
- reply to a netbios name packet. see rfc1002.txt
- ****************************************************************************/
-void reply_netbios_packet(struct packet_struct *p1,int trn_id,
- int rcode, int rcv_code, int opcode,
- BOOL recursion_available,
- BOOL recursion_desired,
- struct nmb_name *rr_name,int rr_type,int rr_class,int ttl,
- char *data,int len)
-{
- struct packet_struct p;
- struct nmb_packet *nmb = &p.packet.nmb;
- struct res_rec answers;
- char *packet_type = "unknown";
-
- p = *p1;
-
- switch (rcv_code)
- {
- case NMB_STATUS:
- {
- packet_type = "nmb_status";
- break;
- }
- case NMB_QUERY:
- {
- packet_type = "nmb_query";
- break;
- }
- case NMB_REG:
- {
- packet_type = "nmb_reg";
- break;
- }
- case NMB_REL:
- {
- packet_type = "nmb_rel";
- break;
- }
- case NMB_WAIT_ACK:
- {
- packet_type = "nmb_wack";
- break;
- }
- default:
- {
- DEBUG(1,("replying netbios packet: %s %s\n",
- packet_type, namestr(rr_name), inet_ntoa(p.ip)));
-
- return;
- }
- }
-
- DEBUG(4,("replying netbios packet: %s %s\n",
- packet_type, namestr(rr_name), inet_ntoa(p.ip)));
-
- nmb->header.name_trn_id = trn_id;
- nmb->header.opcode = opcode;
- nmb->header.response = True;
- nmb->header.nm_flags.bcast = False;
- nmb->header.nm_flags.recursion_available = recursion_available;
- nmb->header.nm_flags.recursion_desired = recursion_desired;
- nmb->header.nm_flags.trunc = False;
- nmb->header.nm_flags.authoritative = True;
-
- nmb->header.qdcount = 0;
- nmb->header.ancount = 1;
- nmb->header.nscount = 0;
- nmb->header.arcount = 0;
- nmb->header.rcode = rcode;
-
- bzero((char*)&nmb->question,sizeof(nmb->question));
-
- nmb->answers = &answers;
- bzero((char*)nmb->answers,sizeof(*nmb->answers));
-
- nmb->answers->rr_name = *rr_name;
- nmb->answers->rr_type = rr_type;
- nmb->answers->rr_class = rr_class;
- nmb->answers->ttl = ttl;
-
- if (data && len)
- {
- nmb->answers->rdlength = len;
- memcpy(nmb->answers->rdata, data, len);
- }
-
- p.packet_type = NMB_PACKET;
-
- debug_nmb_packet(&p);
-
- send_packet(&p);
-}
-
-
-/*******************************************************************
- the global packet linked-list. incoming entries are added to the
- end of this list. it is supposed to remain fairly short so we
- won't bother with an end pointer.
- ******************************************************************/
-static struct packet_struct *packet_queue = NULL;
-
-/*******************************************************************
- queue a packet into the packet queue
- ******************************************************************/
-void queue_packet(struct packet_struct *packet)
-{
- struct packet_struct *p;
-
- if (!packet_queue) {
- packet->prev = NULL;
- packet->next = NULL;
- packet_queue = packet;
- return;
- }
-
- /* find the bottom */
- for (p=packet_queue;p->next;p=p->next) ;
-
- p->next = packet;
- packet->next = NULL;
- packet->prev = p;
-}
-
-/****************************************************************************
- determine if a packet is for us. Note that to have any chance of
- being efficient we need to drop as many packets as possible at this
- stage as subsequent processing is expensive.
-
- We also must make absolutely sure we don't tread on another machines
- property by answering a packet that is not for us.
- ****************************************************************************/
-static BOOL listening(struct packet_struct *p,struct nmb_name *n)
-{
- struct subnet_record *d;
- struct name_record *n1;
-
- /* We explicitly don't search WINS here - this will be done
- in find_name_search if it was a packet from a non-local subnet. */
- d = find_subnet(p->ip);
-
- n1 = find_name_search(&d,n,FIND_LOCAL|FIND_WINS|FIND_SELF,p->ip);
-
- return (n1 != NULL);
-}
-
-
-/****************************************************************************
- process udp 138 datagrams
- ****************************************************************************/
-static void process_dgram(struct packet_struct *p)
-{
- char *buf;
- char *buf2;
- int len;
- struct dgram_packet *dgram = &p->packet.dgram;
-
- /* if we aren't listening to the destination name then ignore the packet */
- if (!listening(p,&dgram->dest_name))
- {
- DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s(%x) from %s\n",
- dgram->dest_name.name, dgram->dest_name.name_type, inet_ntoa(p->ip)));
- return;
- }
-
- if (dgram->header.msg_type != 0x10 &&
- dgram->header.msg_type != 0x11 &&
- dgram->header.msg_type != 0x12)
- {
- /* don't process error packets etc yet */
- DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s(%d) from %s as it is \
- an error packet of type %x\n",
- dgram->dest_name.name, dgram->dest_name.name_type,
- inet_ntoa(p->ip), dgram->header.msg_type));
- return;
- }
-
- buf = &dgram->data[0];
- buf -= 4; /* XXXX for the pseudo tcp length -
- someday I need to get rid of this */
-
- if (CVAL(buf,smb_com) != SMBtrans) return;
-
- len = SVAL(buf,smb_vwv11);
- buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
-
- DEBUG(4,("process_dgram: datagram from %s to %s for %s of type %d len=%d\n",
- namestr(&dgram->source_name),namestr(&dgram->dest_name),
- smb_buf(buf),CVAL(buf2,0),len));
-
-
- if (len <= 0) return;
-
- /* datagram packet received for the browser mailslot */
- if (strequal(smb_buf(buf),BROWSE_MAILSLOT)) {
- process_browse_packet(p,buf2,len);
- return;
- }
-
- /* datagram packet received for the domain log on mailslot */
- if (strequal(smb_buf(buf),NET_LOGON_MAILSLOT)) {
- process_logon_packet(p,buf2,len);
- return;
- }
-}
-
-/****************************************************************************
- process a nmb packet
- ****************************************************************************/
-static void process_nmb(struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
-
- debug_nmb_packet(p);
-
- switch (nmb->header.opcode)
- {
- case 8: /* what is this?? */
- case NMB_REG:
- case NMB_REG_REFRESH:
- {
- if (nmb->header.response)
- {
- if (nmb->header.ancount ==0) break;
- response_netbios_packet(p); /* response to registration dealt
- with here */
- }
- else
- {
- if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
- reply_name_reg(p);
- }
- break;
- }
-
- case 0:
- {
- if (nmb->header.response)
- {
- switch (nmb->question.question_type)
- {
- case 0x0:
- {
- response_netbios_packet(p);
- break;
- }
- }
- return;
- }
- else if (nmb->header.qdcount>0)
- {
- switch (nmb->question.question_type)
- {
- case NMB_QUERY:
- {
- reply_name_query(p);
- break;
- }
- case NMB_STATUS:
- {
- reply_name_status(p);
- break;
- }
- }
- return;
- }
- break;
- }
-
- case NMB_REL:
- {
- if (nmb->header.response)
- {
- if (nmb->header.ancount ==0) break;
- response_netbios_packet(p); /* response to release dealt
- with here */
- }
- else
- {
- if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
- reply_name_release(p);
- }
- break;
- }
- }
-}
-
-
-/*******************************************************************
- run elements off the packet queue till its empty
- ******************************************************************/
-void run_packet_queue()
-{
- struct packet_struct *p;
-
- while ((p=packet_queue))
- {
- switch (p->packet_type)
- {
- case NMB_PACKET:
- process_nmb(p);
- break;
-
- case DGRAM_PACKET:
- process_dgram(p);
- break;
- }
-
- packet_queue = packet_queue->next;
- if (packet_queue) packet_queue->prev = NULL;
- free_packet(p);
- }
-}
-
-/****************************************************************************
- listens for NMB or DGRAM packets, and queues them
- ***************************************************************************/
-void listen_for_packets(BOOL run_election)
-{
- fd_set fds;
- int selrtn;
- struct timeval timeout;
-
- FD_ZERO(&fds);
- FD_SET(ClientNMB,&fds);
- FD_SET(ClientDGRAM,&fds);
-
- /* during elections and when expecting a netbios response packet we
- need to send election packets at tighter intervals
-
- ideally it needs to be the interval (in ms) between time now and
- the time we are expecting the next netbios packet */
-
- timeout.tv_sec = (run_election||num_response_packets) ? 1:NMBD_SELECT_LOOP;
- timeout.tv_usec = 0;
-
- /* We can only take term signals when we are in the select. */
- BlockSignals(False, SIGTERM);
- selrtn = sys_select(&fds,&timeout);
- BlockSignals(True, SIGTERM);
-
- if (FD_ISSET(ClientNMB,&fds))
- {
- struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
- if (packet)
- {
- if (ismyip(packet->ip) && packet->port == NMB_PORT)
- {
- DEBUG(7,("discarding own packet from %s:%d\n",
- inet_ntoa(packet->ip),packet->port));
- free_packet(packet);
- }
- else
- {
- queue_packet(packet);
- }
- }
- }
-
- if (FD_ISSET(ClientDGRAM,&fds))
- {
- struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
- if (packet)
- {
- if (ismyip(packet->ip) && packet->port == DGRAM_PORT)
- {
- DEBUG(7,("discarding own packet from %s:%d\n",
- inet_ntoa(packet->ip),packet->port));
- free_packet(packet);
- }
- else
- {
- queue_packet(packet);
- }
- }
- }
-}
-
-
-
-/****************************************************************************
- construct and send a netbios DGRAM
-
- Note that this currently sends all answers to port 138. thats the
- wrong things to do! I should send to the requestors port. XXX
- **************************************************************************/
-BOOL send_mailslot_reply(BOOL unique, char *mailslot,int fd,char *buf,int len,char *srcname,
- char *dstname,int src_type,int dest_type,
- struct in_addr dest_ip,struct in_addr src_ip)
-{
- struct packet_struct p;
- struct dgram_packet *dgram = &p.packet.dgram;
- char *ptr,*p2;
- char tmp[4];
-
- /* ha ha. no. do NOT send packets to 255.255.255.255: it's a pseudo address */
- if (ip_equal(wins_ip, dest_ip)) return False;
-
- bzero((char *)&p,sizeof(p));
-
- update_name_trn_id();
-
- /* DIRECT GROUP or UNIQUE datagram */
- dgram->header.msg_type = unique ? 0x10 : 0x11;
- dgram->header.flags.node_type = M_NODE;
- dgram->header.flags.first = True;
- dgram->header.flags.more = False;
- dgram->header.dgm_id = name_trn_id;
- dgram->header.source_ip = src_ip;
- dgram->header.source_port = DGRAM_PORT;
- dgram->header.dgm_length = 0; /* let build_dgram() handle this */
- dgram->header.packet_offset = 0;
-
- make_nmb_name(&dgram->source_name,srcname,src_type,scope);
- make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
-
- ptr = &dgram->data[0];
-
- /* now setup the smb part */
- ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */
- memcpy(tmp,ptr,4);
- set_message(ptr,17,17 + len,True);
- memcpy(ptr,tmp,4);
-
- CVAL(ptr,smb_com) = SMBtrans;
- SSVAL(ptr,smb_vwv1,len);
- SSVAL(ptr,smb_vwv11,len);
- SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
- SSVAL(ptr,smb_vwv13,3);
- SSVAL(ptr,smb_vwv14,1);
- SSVAL(ptr,smb_vwv15,1);
- SSVAL(ptr,smb_vwv16,2);
- p2 = smb_buf(ptr);
- strcpy(p2,mailslot);
- p2 = skip_string(p2,1);
-
- memcpy(p2,buf,len);
- p2 += len;
-
- dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */
-
- p.ip = dest_ip;
- p.port = DGRAM_PORT;
- p.fd = ClientDGRAM;
- p.timestamp = time(NULL);
- p.packet_type = DGRAM_PACKET;
-
- DEBUG(4,("send mailslot %s from %s %s", mailslot,
- inet_ntoa(src_ip),namestr(&dgram->source_name)));
- DEBUG(4,("to %s %s\n", inet_ntoa(dest_ip),namestr(&dgram->dest_name)));
-
- return(send_packet(&p));
-}
diff --git a/source/namepacket.doc b/source/namepacket.doc
deleted file mode 100644
index 159a50738c5..00000000000
--- a/source/namepacket.doc
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- Unix SMB/Netbios documentation.
- Version 0.0
- Copyright (C) Luke Leighton Andrew Tridgell 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.
-
- Document name: namepacket.doc
-
- Revision History:
-
- 0.0 - 02jul96 : lkcl@pires.co.uk
- created
-*/
-
-this module deals with packets: sending, receiving, queueing
-and some basic interpretation (e.g it excludes datagram
-error packets at the moment).
-
-the packet queueing mechanism was originally introduced when
-samba dealt with responses by sending a packet, receiving
-packets and queueing all packets that didn't match up with
-the response expected. this is fine in a single-thread
-environment, but samba now deals with response packets by
-queueing the responses. to some extent, therefore, this
-queue_packet mechanism is redundant.
-
-
-/*************************************************************************
- send_mailslot_reply()
- *************************************************************************/
-
-this function is responsible for sending a MAILSLOT packet.
-
-it will _not_ send packets to the pseudo WINS subnet's address of
-255.255.255.255: this would be disastrous.
-
-each packet sent out has a unique transaction identifier. this is done
-so that responses can be matched later with the original purpose for
-the packet being sent out in the first place.
-
-
-/*************************************************************************
- listen_for_packets()
- *************************************************************************/
-
-this function is responsible for reading NMB and DGRAM packets, and then
-queueing them. it will normally time-out for NMBD_SELECT_LOOP seconds, but
-if there is an election currently running or we are expecting a response
-then this time is reduced to 1 second.
-
-note: the time-out period needs refining to the millisecond level.
-
-
-/*************************************************************************
- queue_packet()
- *************************************************************************/
-
-this function is responsible for queueing any NMB and DGRAM packets passed
-to it. these packets will be removed from the queue in run_packet_queue().
-
-
-/*************************************************************************
- run_packet_queue()
- *************************************************************************/
-
-this function is responsible for taking a packet off the queue,
-identifying whether it is an NMB or a DGRAM packet, processing
-it accordingly and deleting it. this process continues until
-there are no more packets on the queue.
-
-
-/*************************************************************************
- process_nmb()
- *************************************************************************/
-
-this function receives a packet identified as a netbios packet.
-it further identifies whether it is a response or a query packet.
-by identifying the type of packet (name registration, query etc)
-process_nmb() will call the appropriate function to deal with the
-type of packet received.
-
-
-/*************************************************************************
- process_dgram()
- *************************************************************************/
-
-this function is responsible for identifying whether the datagram
-packet received is a browser packet or a domain logon packet. it
-also does some filtering of certain types of packets (e.g it
-filters out error packets).
-
-
-/*************************************************************************
- reply_netbios_packet()
- *************************************************************************/
-
-this function is responsible for sending a reply to another NetBIOS
-packet from another host. it can be used to send a reply to a name
-registration, name release, name query or name status request.
-
-the reply can be either a positive or a negative one.
-
-
-/*************************************************************************
- initiate_netbios_packet()
- *************************************************************************/
-
-this function is responsible for construction a netbios packet and sending
-it. if the packet has not had a unique transaction id allocated to it,
-then initiate_netbios_packet() will give it one.
-
-
-/*************************************************************************
- update_name_trn_id()
- *************************************************************************/
-
-this function is responsible for allocating unique transaction identifiers
-for each new packet sent on the network.
-
-
diff --git a/source/namequery.doc b/source/namequery.doc
deleted file mode 100644
index 4337cfb7e2a..00000000000
--- a/source/namequery.doc
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- Unix SMB/Netbios documentation.
- Version 0.0
- Copyright (C) Luke Leighton Andrew Tridgell 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.
-
- Document name: namequery.doc
-
- Revision History:
-
- 0.0 - 02jul96 : lkcl@pires.co.uk
- created
-*/
-
-this module contains non-threaded versions of name status and name
-query functions. if a multi-threaded nmbd was to be written, these
-functions would be the starting point.
-
-at the moment, the expected response queueing system is used to
-replace these functions without needing to multi-thread nmbd.
-
-these functions are used in smbclient and nmblookup at present to
-avoid having the vast quantities of complex and unused code needed
-to support even a simple name query (or providing stubs for the
-unused side of these functions).
-
-there is a down-side to these functions, which is all microsoft's
-fault. microsoft machines always always reply to queries on the
-priveleged ports, rather than following the usual tcp/ip mechanism
-of replying on the client's port (the exception to this i am led
-to believe is windows nt 3.50).
-
-as a result of this, in order to receive a response to a name
-query from a microsoft machine, we must be able to listen on
-the priveleged netbios name server ports. this is simply not
-possible with some versions of unix, unless you have root access.
-
-it is also not possible if you run smbclient or nmblookup on an
-interface that already has been claimed by the netbios name server
-daemon nmbd.
-
-all in all, i wish that microsoft would fix this.
-
-a solution does exist: nmbd _does_ actually reply on the client's
-port, so if smbclient and nmblookup were to use nmbd as a proxy
-forwarder of queries (or to use samba's WINS capabilities) then
-a query could be made without needing access to the priveleged
-ports. in order to do this properly, samba must implement secured
-netbios name server functionality (see rfc1001.txt 15.1.6).
-(lkcl 01aug96: samba now supports secured name registration)
-
-/*************************************************************************
- name_query()
- *************************************************************************/
-
-
-
-/*************************************************************************
- name_status()
- *************************************************************************/
-
-
-
-/*************************************************************************
- _interpret_node_status()
- *************************************************************************/
-
-
-this is a older version of interpret_node_status().
-
diff --git a/source/nameresp.c b/source/nameresp.c
deleted file mode 100644
index f44171f4b67..00000000000
--- a/source/nameresp.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios library routines
- Copyright (C) Andrew Tridgell 1994-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.
-
- Module name: nameresp.c
-
-*/
-
-#include "includes.h"
-
-extern int ClientNMB;
-extern int ClientDGRAM;
-
-extern struct subnet_record *subnetlist;
-
-extern int DEBUGLEVEL;
-
-extern pstring scope;
-extern struct in_addr ipzero;
-extern struct in_addr wins_ip;
-
-
-/***************************************************************************
- deals with an entry before it dies
- **************************************************************************/
-static void dead_netbios_entry(struct subnet_record *d,
- struct response_record *n)
-{
- DEBUG(3,("Removing dead netbios entry for %s %s (num_msgs=%d)\n",
- inet_ntoa(n->send_ip), namestr(&n->name), n->num_msgs));
-
- debug_state_type(n->state);
-
- switch (n->state)
- {
- case NAME_QUERY_CONFIRM:
- {
- if (!lp_wins_support()) return; /* only if we're a WINS server */
-
- if (n->num_msgs == 0)
- {
- /* oops. name query had no response. check that the name is
- unique and then remove it from our WINS database */
-
- /* IMPORTANT: see query_refresh_names() */
-
- if ((!NAME_GROUP(n->nb_flags)))
- {
- struct subnet_record *d1 = wins_subnet;
- if (d1)
- {
- /* remove the name that had been registered with us,
- and we're now getting no response when challenging.
- see rfc1001.txt 15.5.2
- */
- remove_netbios_name(d1, n->name.name, n->name.name_type,
- REGISTER, n->send_ip);
- }
- }
- }
- break;
- }
-
- case NAME_QUERY_MST_CHK:
- {
- /* if no response received, the master browser must have gone
- down on that subnet, without telling anyone. */
-
- /* IMPORTANT: see response_netbios_packet() */
-
- if (n->num_msgs == 0)
- browser_gone(n->name.name, n->send_ip);
- break;
- }
-
- case NAME_RELEASE:
- {
- /* if no response received, it must be OK for us to release the
- name. nobody objected (including a potentially dead or deaf
- WINS server) */
-
- /* IMPORTANT: see response_name_release() */
-
- if (ismyip(n->send_ip))
- {
- name_unregister_work(d,n->name.name,n->name.name_type);
- }
- if (!n->bcast && n->num_msgs == 0)
- {
- DEBUG(0,("WINS server did not respond to name release!\n"));
- /* XXXX whoops. we have problems. must deal with this */
- }
- break;
- }
-
- case NAME_REGISTER_CHALLENGE:
- {
- /* name challenge: no reply. we can reply to the person that
- wanted the unique name and tell them that they can have it
- */
-
- add_name_respond(d,n->fd,d->myip, n->response_id ,&n->name,
- n->nb_flags, GET_TTL(0),
- n->reply_to_ip, True, n->reply_to_ip);
-
- if (!n->bcast && n->num_msgs == 0)
- {
- DEBUG(1,("WINS server did not respond to name registration!\n"));
- /* XXXX whoops. we have problems. must deal with this */
- }
- break;
- }
-
- case NAME_REGISTER:
- {
- /* if no response received, and we are using a broadcast registration
- method, it must be OK for us to register the name: nobody objected
- on that subnet. if we are using a WINS server, then the WINS
- server must be dead or deaf.
- */
- if (n->num_msgs == 0)
- {
- if (n->bcast)
- {
- /* broadcast method: implicit acceptance of the name registration
- by not receiving any objections. */
-
- /* IMPORTANT: see response_name_reg() */
-
- name_register_work(d,n->name.name,n->name.name_type,
- n->nb_flags, n->ttl, n->reply_to_ip, n->bcast);
- }
- else
- {
- /* received no response. rfc1001.txt states that after retrying,
- we should assume the WINS server is dead, and fall back to
- broadcasting (see bits about M nodes: can't find any right
- now) */
-
- DEBUG(1,("WINS server did not respond to name registration!\n"));
- /* XXXX whoops. we have problems. must deal with this */
- }
- }
- break;
- }
-
- case NAME_QUERY_DOMAIN:
- {
- /* if no response was received, there is no domain controller for
- this DOMAIN registered within WINS. it's ok for us to register
- the DOMAIN<1b> name.
- */
-
- if (n->num_msgs == 0)
- {
- struct work_record *work = find_workgroupstruct(d,n->name.name,False);
- if (work && d)
- {
- become_domain_master(d,work);
- }
- }
- else
- {
- DEBUG(1, ("nmbd configured as domain master and one already exists\n"));
- }
- break;
- }
-
- default:
- {
- /* nothing to do but delete the dead expected-response structure */
- /* this is normal. */
- break;
- }
- }
-}
-
-
-/*******************************************************************
- remove old name response entries
-
- XXXX retry code needs to be added, including a retry wait period and a count
- see name_query() and name_status() for suggested implementation.
-
- ******************************************************************/
-void expire_netbios_response_entries(time_t t)
-{
- struct subnet_record *d;
-
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d))
- {
- struct response_record *n, *nextn;
-
- for (n = d->responselist; n; n = nextn)
- {
- nextn = n->next;
-
- if (n->repeat_time <= t)
- {
- if (n->repeat_count > 0)
- {
- /* resend the entry */
- initiate_netbios_packet(&n->response_id, n->fd, n->quest_type,
- n->name.name, n->name.name_type,
- n->nb_flags, n->bcast, n->recurse, n->send_ip);
-
- n->repeat_time += n->repeat_interval; /* XXXX ms needed */
- n->repeat_count--;
-
- }
- else
- {
- DEBUG(4,("timeout response %d for %s %s\n",
- n->response_id, namestr(&n->name),
- inet_ntoa(n->send_ip)));
-
- dead_netbios_entry(d,n); /* process the non-response */
- remove_response_record(d,n); /* remove the non-response */
-
- continue;
- }
- }
- }
- }
-}
-
-
-/****************************************************************************
- wrapper function to override a broadcast message and send it to the WINS
- name server instead, if it exists. if wins is false, and there has been no
- WINS server specified, the packet will NOT be sent.
- ****************************************************************************/
-struct response_record *queue_netbios_pkt_wins(
- int fd,int quest_type,enum state_type state,
- char *name,int name_type,int nb_flags, time_t ttl,
- int server_type, char *my_name, char *my_comment,
- struct in_addr send_ip, struct in_addr reply_to_ip)
-{
- /* XXXX note: please see rfc1001.txt section 10 for details on this
- function: it is currently inappropriate to use this - it will do
- for now - once there is a clarification of B, M and P nodes and
- which one samba is supposed to be
- */
-
- if ((!lp_wins_support()) && (*lp_wins_server()))
- {
- /* samba is not a WINS server, and we are using a WINS server */
- struct in_addr real_wins_ip;
- real_wins_ip = *interpret_addr2(lp_wins_server());
-
- if (!zero_ip(real_wins_ip))
- {
- send_ip = real_wins_ip;
- }
- else
- {
- /* oops. smb.conf's wins server parameter MUST be a host_name
- or an ip_address. */
- DEBUG(0,("invalid smb.conf parameter 'wins server'\n"));
- }
- }
-
- if (zero_ip(send_ip)) return NULL;
-
- return queue_netbios_packet(wins_subnet,fd, quest_type, state,
- name, name_type, nb_flags, ttl,
- server_type,my_name,my_comment,
- False, True, send_ip, reply_to_ip);
-}
-
-
-/****************************************************************************
- initiate a netbios name query to find someone's or someones' IP
- this is intended to be used (not exclusively) for broadcasting to
- master browsers (WORKGROUP(1d or 1b) or __MSBROWSE__(1)) to get
- complete lists across a wide area network
- ****************************************************************************/
-struct response_record *queue_netbios_packet(struct subnet_record *d,
- int fd,int quest_type,enum state_type state,char *name,
- int name_type,int nb_flags, time_t ttl,
- int server_type, char *my_name, char *my_comment,
- BOOL bcast,BOOL recurse,
- struct in_addr send_ip, struct in_addr reply_to_ip)
-{
- struct response_record *n;
- uint16 id = 0xffff;
-
- /* ha ha. no. do NOT broadcast to 255.255.255.255: it's a pseudo address */
- if (ip_equal(wins_ip, send_ip)) return NULL;
-
- initiate_netbios_packet(&id, fd, quest_type, name, name_type,
- nb_flags, bcast, recurse, send_ip);
-
- if (id == 0xffff) {
- DEBUG(4,("did not initiate netbios packet: %s\n", inet_ntoa(send_ip)));
- return NULL;
- }
-
- if ((n = make_response_queue_record(state,id,fd,
- quest_type,name,name_type,nb_flags,ttl,
- server_type,my_name, my_comment,
- bcast,recurse,send_ip,reply_to_ip)))
- {
- add_response_record(d,n);
- return n;
- }
- return NULL;
-}
diff --git a/source/nameresp.doc b/source/nameresp.doc
deleted file mode 100644
index cfe63500c88..00000000000
--- a/source/nameresp.doc
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- Unix SMB/Netbios documentation.
- Version 0.0
- Copyright (C) Luke Leighton Andrew Tridgell 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.
-
- Document name: nameresp.doc
-
- Revision History:
-
- 0.0 - 02jul96 : lkcl@pires.co.uk
- created
-*/
-
-the netbios expected response code is a key part of samba's NetBIOS
-handling capabilities. it allows samba to carry on dealing with
-other things while expecting a response from one or more hosts.
-
-this allows samba to simultaneously deal with registering its names
-with another WINS server, register its names on its local subnets,
-query any hosts that have registered with samba in its capacity as
-a WINS server, and at a later date it will be also be able handle
-END-NODE CHALLENGES (see rfc1001.txt 15.2.2.2 and 15.2.2.3 - secured
-NBNS functionality).
-
-all at once!
-
-when a netbios packet is sent out by samba and it expects a response,
-a record of all the relevant information is kept (most importantly,
-the unique transaction id associated which will come back to us in
-a response packet is recorded, and also recorded is the reason that
-the original packet was sent out by samba in the first place!).
-
-if a response is received, then the unique transaction identifier
-returned in the response packet is searched for in the expected
-response records. the record indicates why the initial request was
-made (and therefore the type of response can be verified) and
-appropriate action can be taken.
-
-when no responses, after a number of retries, are not received, then
-samba may take appropriate action. this is a crucial part of samba's
-operation: for a key number of NetBIOS operations, no response is an
-implicit positive response.
-
-module nameresp deals with the initial transmission, re-transmission
-and time-out of netbios response records.
-
-module namedbresp deals with the maintenance of the list of expected
-responses - creation, finding and removal.
-
-
-/*************************************************************************
- queue_netbios_packet()
- *************************************************************************/
-
-this function is responsible for sending out a netbios packet, and then
-making a record of the information that was sent out. a response will
-be expected later (or not, as the case may be).
-
-if a response is received, response_netbios_packet() will deal with it.
-otherwise, it will be dealt with in expire_netbios_response_entries().
-
-
-/*************************************************************************
- queue_netbios_pkt_wins()
- *************************************************************************/
-
-this function is a wrapper around queue_netbios_packet(). there is
-some confusion about B, M and P nodes (see rfc1001.txt section 10) -
-confusion introduced by luke :-) - which needs sorting out.
-
-for example, rfc1001.txt 15.2.3 - an M node must attempt to register a
-name first as a B node, then attempt to register as an M node. negative
-responses on either of these attempts is a failure to register the
-name.
-
-this is NOT the case with a P node.
-
-
-/*************************************************************************
- expire_netbios_response_entries()
- *************************************************************************/
-
-this function is responsible for dealing with queued response records
-that have not received a response packet matching their unique
-transaction id.
-
-if the retry count for any record is non-zero, and its time-out period
-has expired, the retry count is reduced, the time-out period is stepped
-forward and the packet is re-transmitted (from the information stored
-in the queued response record) with the same unique transaction id of
-the initial attempt at soliciting a response.
-
-if the retry count is zero, then the packet is assumed to have expired.
-dead_netbios_entry() is called to deal with the possibility of an error
-or a problem (or in certain instances, no answer is an implicit
-positive response!).
-
-the expected response record is then deleted, and the number of expected
-responses reduced. when this count gets to zero, listen_for_packets()
-will no longer time-out for 1 second on account of expecting response
-packets.
-
-
-/*************************************************************************
- dead_netbios_entry()
- *************************************************************************/
-
-this function is responsible for dealing with the case when a NetBIOS
-response to a packet sent out by samba was not received. for certain
-transactions, this may be normal. for others, under certain conditions
-it may constitute either an error or a problem with or failure of one
-or more hosts.
-
-- NAME_QUERY_CONFIRM
-
-when a samba 'state' of type NAME_QUERY_CONFIRM is sent, a response
-may or may not be forthcoming. if no response is received to a unique
-name, then the record is removed from samba's WINS database. non-unique
-names are simply expected to die off on a time-to-live basis (see
-rfc1001.txt 15.1.3.4)
-
-query_refresh_names() issues this samba 'state'
-response_name_query_sync() deals with responses to NAME_QUERY_CONFIRM.
-
-- NAME_QUERY_MST_CHK
-
-when a samba 'state' of type NAME_QUERY_MST_CHK is sent, and a response
-is not received, this implies that a master browser will have failed.
-remedial action may need to be taken, for example if samba is a member
-of that workgroup and it is also a potential master browser it could
-force an election.
-
-check_master_browser() issues this samba 'state'.
-response_process() does nothing if a response is received. this is normal.
-
-- NAME_RELEASE
-
-when a samba 'state' of type NAME_RELEASE is sent, and a response is
-not received, it is assumed to be acceptable to release the name. if the
-original response was sent to another WINS server, then that WINS server
-may be inaccessible or may have failed. if so, then at a later date
-samba should take this into account (see rfc1001.txt 10.3).
-
-remove_name_entry() issues this samba 'state'
-response_name_rel() deals with responses to NAME_RELEASE.
-
-- NAME_REGISTER
-
-when a samba 'state' of type NAME_REGISTER is sent, and a response is
-not received, if the registration was done by broadcast, it is assumed
-that there are no objections to the registration of this name, and samba
-adds the name to the appropriate subnet record name database. if the
-registration was point-to-point (i.e with another WINS server) then that
-WINS server may be inaccessible or may have failed. if so, then at a later
-date samba should take this into account (see rfc1001.txt 10.3).
-
-add_my_name_entry() issues this samba 'state'
-response_name_reg() deals with responses to NAME_REGISTER.
-
-no action is taken for any other kinds of samba 'states' if a response
-is not received. this is not to say that action may not be appropriate,
-just that it's not been looked at yet :-)
-
-
diff --git a/source/nameserv.c b/source/nameserv.c
deleted file mode 100644
index ccd0ef379cb..00000000000
--- a/source/nameserv.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-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.
-
- Module name: nameserv.c
-
- Revision History:
-
- 14 jan 96: lkcl@pires.co.uk
- added multiple workgroup domain master support
-
- 04 jul 96: lkcl@pires.co.uk
- module nameserv contains name server management functions
-*/
-
-#include "includes.h"
-
-extern int ClientNMB;
-
-extern int DEBUGLEVEL;
-
-extern pstring scope;
-extern pstring myname;
-extern fstring myworkgroup;
-extern char **my_netbios_names;
-extern struct in_addr ipzero;
-extern struct in_addr wins_ip;
-
-extern struct subnet_record *subnetlist;
-
-extern uint16 nb_type; /* samba's NetBIOS type */
-
-/****************************************************************************
- remove an entry from the name list
-
- note: the name will _always_ be removed
- XXXX at present, the name is removed _even_ if a WINS server says keep it.
-
- ****************************************************************************/
-void remove_name_entry(struct subnet_record *d, char *name,int type)
-{
- /* XXXX BUG: if samba is offering WINS support, it should still broadcast
- a de-registration packet to the local subnet before removing the
- name from its local-subnet name database. */
-
- int search = FIND_SELF;
- struct name_record n;
- struct name_record *n2=NULL;
-
- make_nmb_name(&n.name,name,type,scope);
-
- if(d == wins_subnet)
- search |= FIND_WINS;
- else
- search |= FIND_LOCAL;
-
- if ((n2 = find_name_search(&d, &n.name, search, ipzero)))
- {
- /* check name isn't already being de-registered */
- if (NAME_DEREG(n2->ip_flgs[0].nb_flags))
- return;
-
- /* mark the name as in the process of deletion. */
- n2->ip_flgs[0].nb_flags &= NB_DEREG;
- }
-
- if (!n2) return;
-
- /* Only remove names with non-zero death times. */
- if(n2->death_time == 0)
- {
- DEBUG(5,("remove_name_entry: Name %s(%d) has zero ttl - not removing.\n",
- name, type));
- return;
- }
-
- /* remove the name immediately. even if the spec says we should
- first try to release them, this is too dangerous with our current
- name structures as otherwise we will end up replying to names we
- don't really own */
- remove_netbios_name(d,name,type,SELF,n2->ip_flgs[0].ip);
-
- if (ip_equal(d->bcast_ip, wins_ip))
- {
- if (!lp_wins_support())
- {
- /* not a WINS server: we have to release them on the network */
- queue_netbios_pkt_wins(ClientNMB,NMB_REL,NAME_RELEASE,
- name, type, 0, 0,0,NULL,NULL,
- ipzero, ipzero);
- }
- }
- else
- {
- /* local interface: release them on the network */
- queue_netbios_packet(d,ClientNMB,NMB_REL,NAME_RELEASE,
- name, type, 0, 0,0,NULL,NULL,
- True, False, d->bcast_ip, d->bcast_ip);
- }
-}
-
-
-/****************************************************************************
- add an entry to the name list
-
- big note: our name will _always_ be added (if there are no objections).
- it's just a matter of when this will be done (e.g after a time-out).
-
- ****************************************************************************/
-void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags)
-{
- BOOL re_reg = False;
- struct nmb_name n;
-
- if (!d) return;
-
- /* not that it particularly matters, but if the SELF name already exists,
- it must be re-registered, rather than just registered */
-
- make_nmb_name(&n, name, type, scope);
- if (find_name(d->namelist, &n, SELF))
- re_reg = True;
-
- /* XXXX BUG: if samba is offering WINS support, it should still add the
- name entry to a local-subnet name database. see rfc1001.txt 15.1.1 p28
- regarding the point about M-nodes. */
-
- if (ip_equal(d->bcast_ip, wins_ip))
- {
- if (lp_wins_support())
- {
- /* we are a WINS server. */
- if(lp_wins_support())
- {
- DEBUG(4,("add_my_name_entry: samba as WINS server adding: "));
- }
-
- /* this will call add_netbios_entry() */
- name_register_work(d, name, type, nb_flags,0, ipzero, False);
- }
- else
- {
- DEBUG(4,("add_my_name_entry registering name %s with WINS server.\n",
- name));
-
- /* a time-to-live allows us to refresh this name with the WINS server. */
- queue_netbios_pkt_wins(ClientNMB,
- re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
- name, type, nb_flags, GET_TTL(0),0,NULL,NULL,
- ipzero, ipzero);
- }
- }
- else
- {
- /* broadcast the packet, but it comes from ipzero */
- queue_netbios_packet(d,ClientNMB,
- re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER,
- name, type, nb_flags, GET_TTL(0),0,NULL,NULL,
- True, False, d->bcast_ip, ipzero);
- }
-}
-
-
-/****************************************************************************
- add the internet group <1c> domain logon names by wins unicast and broadcast.
- ****************************************************************************/
-void add_domain_logon_names(void)
-{
- struct subnet_record *d;
-
- if (!lp_domain_logons()) return;
-
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d))
- {
- struct work_record *work = find_workgroupstruct(d, myworkgroup, True);
-
- if (work && work->log_state == LOGON_NONE)
- {
- struct nmb_name n;
- make_nmb_name(&n,myworkgroup,0x1c,scope);
-
- if (!find_name(d->namelist, &n, FIND_SELF))
- {
- /* logon servers are group names. don't expect failure */
-
- DEBUG(0,("%s attempting to become logon server for %s %s\n",
- timestring(), myworkgroup, inet_ntoa(d->bcast_ip)));
-
- become_logon_server(d, work);
- }
- }
- }
-}
-
-
-/****************************************************************************
- add the <1b> domain master names by broadcast.
- ****************************************************************************/
-void add_domain_master_bcast(void)
-{
- struct subnet_record *d;
-
- if (!lp_domain_master()) return;
-
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
- {
- struct work_record *work = find_workgroupstruct(d, myworkgroup, True);
-
- if (work && work->dom_state == DOMAIN_NONE)
- {
- struct nmb_name n;
- make_nmb_name(&n,myworkgroup,0x1b,scope);
-
- if (!find_name(d->namelist, &n, FIND_SELF))
- {
- DEBUG(0,("%s add_domain_names: attempting to become domain \
-master browser on workgroup %s %s\n",
- timestring(), myworkgroup, inet_ntoa(d->bcast_ip)));
-
- /* send out a query to establish whether there's a
- domain controller on the local subnet. if not,
- we can become a domain controller. it's only
- polite that we check, before claiming the
- NetBIOS name 0x1b.
- */
-
- DEBUG(0,("add_domain_names:querying subnet %s \
-for domain master on workgroup %s\n",
- inet_ntoa(d->bcast_ip), myworkgroup));
-
- queue_netbios_packet(d,ClientNMB,NMB_QUERY,
- NAME_QUERY_DOMAIN,
- myworkgroup, 0x1b,
- 0, 0,0,NULL,NULL,
- True, False,
- d->bcast_ip, d->bcast_ip);
- }
- }
- }
-}
-
-
-/****************************************************************************
- add the <1b> domain master name by wins unicast.
- ****************************************************************************/
-void add_domain_master_wins(void)
-{
- struct work_record *work;
-
- if (!lp_domain_master() || wins_subnet == NULL) return;
-
- work = find_workgroupstruct(wins_subnet, myworkgroup, True);
-
- if (work && work->dom_state == DOMAIN_NONE)
- {
- struct nmb_name n;
- make_nmb_name(&n,myworkgroup,0x1b,scope);
-
- if (!find_name(wins_subnet->namelist, &n, FIND_SELF))
- {
- DEBUG(0,("%s add_domain_names: attempting to become domain \
-master browser on workgroup %s %s\n",
- timestring(), myworkgroup, inet_ntoa(wins_subnet->bcast_ip)));
-
- if (lp_wins_support())
- {
- /* use the wins server's capabilities (indirectly). if
- someone has already registered the domain<1b>
- name with the WINS server, then the WINS
- server's job is to _check_ that the owner still
- wants it, before giving it away.
- */
-
- DEBUG(1,("%s initiate become domain master for %s\n",
- timestring(), myworkgroup));
-
- become_domain_master(wins_subnet, work);
- }
- else
- {
- /* send out a query to establish whether there's a
- domain controller on the WINS subnet. if not,
- we can become a domain controller. it's only
- polite that we check, before claiming the
- NetBIOS name 0x1b.
- */
-
- DEBUG(0,("add_domain_names:querying WINS \
-for domain master on workgroup %s\n", myworkgroup));
-
- queue_netbios_pkt_wins(ClientNMB,NMB_QUERY,
- NAME_QUERY_DOMAIN,
- myworkgroup, 0x1b,
- 0, 0,0,NULL,NULL,
- ipzero, ipzero);
- }
- }
- }
-}
-
-
-/****************************************************************************
- add the domain logon server and domain master browser names
-
- this code was written so that several samba servers can co-operate in
- sharing the task of (one server) being a domain master, and of being
- domain logon servers.
-
- **************************************************************************/
-void add_domain_names(time_t t)
-{
- static time_t lastrun = 0;
-
- if (lastrun != 0 && t < lastrun + CHECK_TIME_ADD_DOM_NAMES * 60) return;
- lastrun = t;
-
- /* do the "internet group" - <1c> names */
- add_domain_logon_names();
-
- /* do the domain master names */
- if (wins_subnet != NULL)
- {
- /* if the registration of the <1b> name is successful, then
- add_domain_master_bcast() will be called. this will
- result in domain logon services being gracefully provided,
- as opposed to the aggressive nature of 1.9.16p2 to 1.9.16p11.
-
- which, due to a bug in namelogon.c from 1.9.16p2 to 1.9.16p11
- cannot _provide_ domain master / domain logon services!!!
-
- */
- add_domain_master_wins();
- }
- else
- {
- add_domain_master_bcast();
- }
-}
-
-/****************************************************************************
- add the magic samba names, useful for finding samba servers
- **************************************************************************/
-void add_my_names(void)
-{
- struct subnet_record *d;
- /* each subnet entry, including WINS pseudo-subnet, has SELF names */
-
- /* XXXX if there was a transport layer added to samba (ipx/spx etc) then
- there would be yet _another_ for-loop, this time on the transport type
- */
-
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d))
- {
- int n;
- BOOL wins = (lp_wins_support() && (d == wins_subnet));
-
- /* Add all our names including aliases. */
- for (n=0; my_netbios_names[n]; n++)
- {
- add_my_name_entry(d, my_netbios_names[n],0x20,nb_type|NB_ACTIVE);
- add_my_name_entry(d, my_netbios_names[n],0x03,nb_type|NB_ACTIVE);
- add_my_name_entry(d, my_netbios_names[n],0x00,nb_type|NB_ACTIVE);
- }
-
- /* these names are added permanently (ttl of zero) and will NOT be
- refreshed with the WINS server */
- add_netbios_entry(d,"*",0x0,nb_type|NB_ACTIVE,0,SELF,d->myip,False,wins);
- add_netbios_entry(d,"*",0x20,nb_type|NB_ACTIVE,0,SELF,d->myip,False,wins);
- add_netbios_entry(d,"__SAMBA__",0x20,nb_type|NB_ACTIVE,0,SELF,d->myip,False,wins);
- add_netbios_entry(d,"__SAMBA__",0x00,nb_type|NB_ACTIVE,0,SELF,d->myip,False,wins);
- }
-}
-
-
-/****************************************************************************
- remove all the samba names... from a WINS server if necessary.
- **************************************************************************/
-void remove_my_names()
-{
- struct subnet_record *d;
-
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d))
- {
- struct name_record *n, *next;
-
- for (n = d->namelist; n; n = next)
- {
- next = n->next;
- if (n->source == SELF)
- {
- /* get all SELF names removed from the WINS server's database */
- /* XXXX note: problem occurs if this removes the wrong one! */
-
- remove_name_entry(d,n->name.name, n->name.name_type);
- }
- }
- }
-}
-
-
-/*******************************************************************
- refresh my own names
- ******************************************************************/
-void refresh_my_names(time_t t)
-{
- struct subnet_record *d;
-
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d))
- {
- struct name_record *n;
-
- for (n = d->namelist; n; n = n->next)
- {
- /* each SELF name has an individual time to be refreshed */
- if (n->source == SELF && n->refresh_time < t &&
- n->death_time != 0)
- {
- add_my_name_entry(d,n->name.name,n->name.name_type,
- n->ip_flgs[0].nb_flags);
- /* they get a new lease on life :-) */
- n->death_time += GET_TTL(0);
- n->refresh_time += GET_TTL(0);
- }
- }
- }
-}
-
-
-/*******************************************************************
- queries names occasionally. an over-cautious, non-trusting WINS server!
-
- this function has been added because nmbd could be restarted. it
- is generally a good idea to check all the names that have been
- reloaded from file.
-
- XXXX which names to poll and which not can be refined at a later date.
- ******************************************************************/
-void query_refresh_names(time_t t)
-{
- struct name_record *n;
- struct subnet_record *d = wins_subnet;
-
- static time_t lasttime = 0;
-
- int count = 0;
- int name_refresh_time = NAME_POLL_REFRESH_TIME;
- int max_count = name_refresh_time * 2 / NAME_POLL_INTERVAL;
- if (max_count > 10) max_count = 10;
-
- name_refresh_time = NAME_POLL_INTERVAL * max_count / 2;
-
- /* if (!lp_poll_wins()) return; polling of registered names allowed */
-
- if (!d) return;
-
- if (!lasttime) lasttime = t;
- if (t - lasttime < NAME_POLL_INTERVAL) return;
-
- lasttime = time(NULL);
-
- for (n = d->namelist; n; n = n->next)
- {
- /* only do unique, registered names */
-
- if (n->source != REGISTER) continue;
- if (!NAME_GROUP(n->ip_flgs[0].nb_flags)) continue;
-
- if (n->refresh_time < t)
- {
- DEBUG(3,("Polling name %s\n", namestr(&n->name)));
-
- queue_netbios_packet(d,ClientNMB,NMB_QUERY,NAME_QUERY_CONFIRM,
- n->name.name, n->name.name_type,
- 0,0,0,NULL,NULL,
- False,False,n->ip_flgs[0].ip,n->ip_flgs[0].ip);
- count++;
- }
-
- if (count >= max_count)
- {
- /* don't do too many of these at once, but do enough to
- cover everyone in the list */
- return;
- }
-
- /* this name will be checked on again, if it's not removed */
- n->refresh_time += name_refresh_time;
- }
-}
-
diff --git a/source/nameserv.doc b/source/nameserv.doc
deleted file mode 100644
index af4934ade21..00000000000
--- a/source/nameserv.doc
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- Unix SMB/Netbios documentation.
- Version 0.0
- Copyright (C) Luke Leighton Andrew Tridgell 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.
-
- Document name: nameserv.doc
-
- Revision History:
-
- 0.0 - 02jul96 : lkcl@pires.co.uk
- created
-*/
-
-this module deals with general maintenance of NetBIOS names.
-
-/*************************************************************************
- query_refresh_names()
- *************************************************************************/
-
-this function is responsible for polling all names registered in the
-WINS database. it is planned to enable this function should samba
-detect an inconsistency on the network, which could occur if the
-samba NetBIOS daemon dies and is restarted.
-
-polling is done very infrequently, but all names will be covered
-within a period NAME_POLL_REFRESH_TIME. a group of at most ten names
-will be queried at once, at intervals of NAME_POLL_INTERVAL seconds.
-if the total number of names queried in this way will take too long,
-then the time that an individual name will next be polled is
-increased accordingly.
-
-name query polling is functionality over-and-above the normal
-requirement (see rfc1001.txt 15.1.7 point 7). it is normally the
-responsibility of the owner of a name to re-register the name at
-regular intervals.
-
-
-/*************************************************************************
- refresh_my_names()
- *************************************************************************/
-
-this function is responsible for refreshing samba's names that have
-been registered with other servers on a local subnet, or with another
-WINS server if samba is using one.
-
-samba's names' refresh_time will be updated through the use of the function
-add_my_name_entry().
-
-
-/*************************************************************************
- remove_my_names()
- *************************************************************************/
-
-this function is responsible for removing all samba's SELF names. it
-is used when samba receives a SIG_TERM. samba at present does not wait
-for the WINS server to reply to the name releases sent out.
-
-
-/*************************************************************************
- add_my_names()
- *************************************************************************/
-
-this function is responsible for adding and registering if necessary all
-samba's SELF names, on each of its local subnets and with another WINS
-server if samba is using one.
-
-/*************************************************************************
- add_my_name_entry()
- *************************************************************************/
-
-this function is responsible for registering or re-registering one of
-samba's names, either on the local subnet or with another WINS server
-if samba is using one.
-
-if the name is already in samba's database, then it is re-registered,
-otherwise it is simply registered.
-
-if the name is being registered in a WINS capacity (the subnet to which
-the name should be added is the WINS pseudo-subnet) then we add the entry
-immediately if samba is a WINS server. it uses name_register_work()
-because if the name is being added as part of becoming a master browser,
-we want to carry on that process. if the name is registered with another
-WINS server, we must wait for an answer from that WINS server. either
-name_register_work() or name_unregister_work() will be called as a result.
-
-if the name is being registered on a local subnet, then it is
-broadcast. an explicit rejection from another host will result
-in name_unregister_work() being called. no response will, after
-retrying, result in name_register_work() being called.
-
-what ever method is used, the name will either be registered
-or rejected, and what ever process was taking place (becoming
-a master browser for example) will carry on.
-
-expire_netbios_response_entries() is responsible for taking further
-action if no response to the registration is received.
-
-note that there may be a large number of function calls on the
-stack if become_master() is called and samba is configured as
-a WINS server. the loop will be:
-
-become_master(), add_my_name_entry(), name_register_work() and
-back to become_master() with the new value of the workgroup
-'state'.
-
-
-/*************************************************************************
- remove_name_entry()
- *************************************************************************/
-
-this function is responsible for removing a NetBIOS name. if the name
-being removed is registered on a local subnet, a name release should be
-broadcast on the local subnet.
-
-if the name is being released in a WINS capacity (the subnet to
-which the name should be added is the WINS pseudo-subnet) then we
-remove the entry immediately if samba is a WINS server. it uses
-name_unregister_work() because if the name is being added as part of
-becoming a master browser, we want to terminate that process. if the
-name is released from another WINS server, we must wait for an
-answer from that WINS server. name_unregister_work() will
-definitely be called as a result, because at present we ignore
-negative responses for a name release from a WINS server.
-
-if the name is being releasedd on a local subnet, then it is
-broadcast. name_unregister_work() will definitely be called
-because we ignore negative name releases at present.
-
-what ever method is used, the name will be released. (NOT TRUE!
-see response_name_release())
-
-expire_netbios_response_entries() is responsible for taking further action
-if no response to the name release is received.
-
-
-/*************************************************************************
- load_netbios_names()
- *************************************************************************/
-
-this function is responsible for loading any NetBIOS names that samba,
-in its WINS capacity, has written out to disk. all the relevant details
-are recorded in this file, including the time-to-live. should the
-time left to live be small, the name is not added back in to samba's
-WINS database.
-
diff --git a/source/nameservreply.c b/source/nameservreply.c
deleted file mode 100644
index 5b9c476549d..00000000000
--- a/source/nameservreply.c
+++ /dev/null
@@ -1,667 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-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.
-
- Module name: nameservreply.c
-
- Revision History:
-
- 14 jan 96: lkcl@pires.co.uk
- added multiple workgroup domain master support
-
- 04 jul 96: lkcl@pires.co.uk
- created module nameservreply containing NetBIOS reply functions
-
-*/
-
-#include "includes.h"
-
-extern int ClientNMB;
-
-extern int DEBUGLEVEL;
-
-extern struct in_addr wins_ip;
-
-/****************************************************************************
-send a registration / release response: pos/neg
-**************************************************************************/
-static void send_name_response(int fd, struct in_addr from_ip,
- int name_trn_id, int opcode, BOOL success,
- BOOL recursion_available, BOOL recursion_desired,
- struct nmb_name *reply_name, int nb_flags, int ttl,
- struct in_addr ip)
-{
- char rdata[6];
- struct packet_struct p;
-
- int rcode = 0;
-
- if (success == False)
- {
- /* NEGATIVE RESPONSE */
- rcode = 6;
- }
- else if (opcode == NMB_REG && !recursion_available)
- {
- /* END-NODE CHALLENGE REGISTRATION RESPONSE */
- rcode = 0;
- }
-
- rdata[0] = nb_flags;
- rdata[1] = 0;
- putip(&rdata[2],(char *)&ip);
-
- p.ip = from_ip;
- p.port = NMB_PORT;
- p.fd = fd;
- p.timestamp = time(NULL);
- p.packet_type = NMB_PACKET;
-
- reply_netbios_packet(&p,name_trn_id,
- rcode,opcode,opcode,
- recursion_available, recursion_desired,
- reply_name, 0x20, 0x1,
- ttl,
- rdata, 6);
-}
-
-/****************************************************************************
- add a netbios entry. respond to the (possibly new) owner.
- **************************************************************************/
-void add_name_respond(struct subnet_record *d, int fd, struct in_addr from_ip,
- uint16 response_id,
- struct nmb_name *name,
- int nb_flags, int ttl, struct in_addr register_ip,
- BOOL new_owner, struct in_addr reply_to_ip)
-{
- /* register the old or the new owners' ip */
- add_netbios_entry(d,name->name,name->name_type,
- nb_flags,ttl,REGISTER,register_ip,False,True);
-
- /* reply yes or no to the host that requested the name */
- /* see rfc1002.txt - 4.2.10 and 4.2.11 */
- send_name_response(fd,from_ip, response_id, NMB_REG,
- new_owner,
- True, True,
- name, nb_flags, ttl, reply_to_ip);
-}
-
-
-/****************************************************************************
-reply to a name release
-****************************************************************************/
-void reply_name_release(struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct in_addr ip;
- int nb_flags = nmb->additional->rdata[0];
- BOOL bcast = nmb->header.nm_flags.bcast;
- struct name_record *n;
- struct subnet_record *d = NULL;
- int search = 0;
- BOOL success = False;
-
- putip((char *)&ip,&nmb->additional->rdata[2]);
-
- DEBUG(3,("Name release on name %s\n",
- namestr(&nmb->question.question_name)));
-
- if (!(d = find_req_subnet(p->ip, bcast)))
- {
- DEBUG(3,("response packet: bcast %s not known\n",
- inet_ntoa(p->ip)));
- return;
- }
-
- if (bcast)
- search |= FIND_LOCAL;
- else
- search |= FIND_WINS;
-
- n = find_name_search(&d, &nmb->question.question_name,
- search, ip);
-
- /* XXXX under what conditions should we reject the removal?? */
- /* For now - remove if the names match and the group bit matches. */
- if (n && (n->source != SELF) && (NAME_GROUP(n->ip_flgs[0].nb_flags) == NAME_GROUP(nb_flags)))
- {
- success = True;
-
- /* If it's a group name not ending in 1c (not an internet name)
- then just allow it to fade out of existance by timing out. */
- if(NAME_GROUP(nb_flags) && (n->name.name_type != 0x1c))
- {
- DEBUG(5, ("reply_name_release: Allow group name %s(%d) to fade out on \
-subnet %s\n", namestr(&nmb->question.question_name), n->name.name_type,
- inet_ntoa(d->bcast_ip)));
- }
- else
- {
- DEBUG(5, ("reply_name_release: Removing name %s on subnet %s\n",
- namestr(&nmb->question.question_name), inet_ntoa(d->bcast_ip)));
- remove_name(d,n);
- n = NULL;
- }
- }
-
- if (bcast) return;
-
- /* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */
- send_name_response(p->fd,p->ip, nmb->header.name_trn_id, NMB_REL,
- success, False, False,
- &nmb->question.question_name, nb_flags, 0, ip);
-}
-
-
-/****************************************************************************
-reply to a reg request
-**************************************************************************/
-void reply_name_reg(struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
-
- struct nmb_name *reply_name = question;
-
- char *qname = question->name;
- int qname_type = question->name_type;
-
- BOOL bcast = nmb->header.nm_flags.bcast;
-
- int ttl = GET_TTL(nmb->additional->ttl);
- int nb_flags = nmb->additional->rdata[0];
- BOOL group = NAME_GROUP(nb_flags);
-
- struct subnet_record *d = NULL;
- struct name_record *n = NULL;
-
- BOOL success = True;
- BOOL secured_redirect = False;
-
- struct in_addr ip, from_ip;
- int search = 0;
-
- putip((char *)&from_ip,&nmb->additional->rdata[2]);
- ip = from_ip;
-
- DEBUG(3,("Name registration for name %s at %s - ",
- namestr(question),inet_ntoa(ip)));
-
- if (group)
- {
- /* apparently we should return 255.255.255.255 for group queries
- (email from MS) */
- ip = *interpret_addr2("255.255.255.255");
- }
-
- if (!(d = find_req_subnet(p->ip, bcast)))
- {
- DEBUG(3,("reply_name_reg: subnet %s not known\n",
- inet_ntoa(p->ip)));
- return;
- }
-
- if (bcast)
- search |= FIND_LOCAL;
- else
- search |= FIND_WINS;
-
- /* see if the name already exists */
- n = find_name_search(&d, question, search, from_ip);
-
- if (n)
- {
- DEBUG(3,("found\n"));
- if (!group) /* unique names */
- {
- if (n->source == SELF || NAME_GROUP(n->ip_flgs[0].nb_flags))
- {
- /* no-one can register one of samba's names, nor can they
- register a name that's a group name as a unique name */
-
- success = False;
- }
- else if(!ip_equal(ip, n->ip_flgs[0].ip))
- {
- /* XXXX rfc1001.txt says:
- * if we are doing secured WINS, we must send a Wait-Acknowledge
- * packet (WACK) to the person who wants the name, then do a
- * name query on the person who currently owns the unique name.
- * if the current owner still says they own it, the person who wants
- * the name can't have it. if they do not, or are not alive, they can.
- */
-
- secured_redirect = True;
-
- reply_name = &n->name;
- }
- else
- {
- n->ip_flgs[0].ip = ip;
- n->death_time = ttl?p->timestamp+ttl*3:0;
- DEBUG(3,("%s owner: %s\n",namestr(&n->name),inet_ntoa(n->ip_flgs[0].ip)));
- }
- }
- else
- {
- /* refresh the name */
- if (n->source != SELF)
- {
- n->death_time = ttl?p->timestamp + ttl*3:0;
- }
- }
-
- /* XXXX bug reported by terryt@ren.pc.athabascau.ca */
- /* names that people have checked for and not found get DNSFAILed.
- we need to update the name record if someone then registers */
-
- if (n->source == DNSFAIL)
- n->source = REGISTER;
-
- }
- else
- {
- DEBUG(3,("not found\n"));
- /* add the name to our name/subnet, or WINS, database */
- n = add_netbios_entry(d,qname,qname_type,nb_flags,ttl,REGISTER,ip,
- True,!bcast);
- }
-
- /* if samba owns a unique name on a subnet, then it must respond and
- disallow the attempted registration. if the registration is
- successful by broadcast, only then is there no need to respond
- (implicit registration: see rfc1001.txt 15.2.1).
- */
-
- if (bcast && success) return;
-
- if (secured_redirect)
- {
- char rdata[2];
-
- /* XXXX i am confused. RSVAL or SSVAL? assume NMB byte ordering */
- RSSVAL(rdata,0,(nmb->header.opcode&0xf) + ((nb_flags&0xff) << 4));
-
- /* XXXX mistake in rfc1002.txt? 4.2.16: NULL is 0xa see 4.2.1.3
- type = 0x0a; see rfc1002.txt 4.2.1.3
- class = 0x01; see rfc1002.txt 4.2.16
- */
-
- /* send WAIT ACKNOWLEDGEMENT see rfc1002.txt 4.2.16 */
- reply_netbios_packet(p,nmb->header.name_trn_id,
- 0,NMB_WAIT_ACK,NMB_WAIT_ACK,
- False,False,
- reply_name, 0x0a, 0x01,
- 15*1000, /* 15 seconds long enough to wait? */
- rdata, 2);
-
- /* initiate some enquiries to the current owner. */
- queue_netbios_packet(d,ClientNMB,NMB_QUERY,
- NAME_REGISTER_CHALLENGE,
- reply_name->name,reply_name->name_type,
- nb_flags,0,0,NULL,NULL,
- False, False,
- n->ip_flgs[0].ip, p->ip);
- }
- else
- {
- /* Send a NAME REGISTRATION RESPONSE (pos/neg) see rfc1002.txt 4.2.5-6
- or an END-NODE CHALLENGE REGISTRATION RESPONSE see rfc1002.txt 4.2.7
- */
-
- send_name_response(p->fd,p->ip, nmb->header.name_trn_id, NMB_REG,
- success,
- True, True,
- reply_name, nb_flags, ttl, ip);
- }
-}
-
-/* this is used to sort names for a name status into a sensible order
- we put our own names first, then in alphabetical order */
-static int status_compare(char *n1,char *n2)
-{
- extern pstring myname;
- int l1,l2,l3;
-
- /* its a bit tricky because the names are space padded */
- for (l1=0;l1<15 && n1[l1] && n1[l1] != ' ';l1++) ;
- for (l2=0;l2<15 && n2[l2] && n2[l2] != ' ';l2++) ;
- l3 = strlen(myname);
-
- if ((l1==l3) && strncmp(n1,myname,l3) == 0 &&
- (l2!=l3 || strncmp(n2,myname,l3) != 0))
- return -1;
-
- if ((l2==l3) && strncmp(n2,myname,l3) == 0 &&
- (l1!=l3 || strncmp(n1,myname,l3) != 0))
- return 1;
-
- return memcmp(n1,n2,18);
-}
-
-
-/****************************************************************************
- reply to a name status query
-
- combine the list of the local interface on which the query was made with
- the names registered via wins.
- ****************************************************************************/
-void reply_name_status(struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- char *qname = nmb->question.question_name.name;
- int ques_type = nmb->question.question_name.name_type;
- char rdata[MAX_DGRAM_SIZE];
- char *countptr, *buf, *bufend, *buf0;
- int names_added,i;
- struct name_record *n;
- struct subnet_record *d = NULL;
- int search = FIND_SELF | FIND_WINS | FIND_LOCAL;
-
- /* NOTE: we always treat a name status lookup as a bcast */
- if (!(d = find_req_subnet(p->ip, True)))
- {
- DEBUG(3,("Name status req: bcast %s not known\n",
- inet_ntoa(p->ip)));
- return;
- }
-
- DEBUG(3,("Name status for name %s %s\n",
- namestr(&nmb->question.question_name),
- inet_ntoa(p->ip)));
-
- n = find_name_search(&d, &nmb->question.question_name,
- search, p->ip);
-
- if (!n) return;
-
- /* XXXX hack, we should calculate exactly how many will fit */
- bufend = &rdata[MAX_DGRAM_SIZE] - 18;
- countptr = buf = rdata;
- buf += 1;
- buf0 = buf;
-
- names_added = 0;
-
- n = d->namelist;
-
- while (buf < bufend)
- {
- if (n->source == SELF)
- {
- int name_type = n->name.name_type;
-
- /* check if we want to exclude other workgroup names
- from the response. if we don't exclude them, windows clients
- get confused and will respond with an error for NET VIEW */
-
- if (!strequal(n->name.name,"*") &&
- !strequal(n->name.name,"__SAMBA__") &&
- (name_type < 0x1b || name_type >= 0x20 ||
- ques_type < 0x1b || ques_type >= 0x20 ||
- strequal(qname, n->name.name)))
- {
- /* start with first bit of putting info in buffer: the name */
- bzero(buf,18);
- sprintf(buf,"%-15.15s",n->name.name);
- strupper(buf);
-
- /* put name type and netbios flags in buffer */
- buf[15] = name_type;
- buf[16] = n->ip_flgs[0].nb_flags;
-
- buf += 18;
-
- names_added++;
- }
- }
-
- /* remove duplicate names */
- qsort(buf0,names_added,18,QSORT_CAST status_compare);
-
- for (i=1;i<names_added;i++) {
- if (memcmp(buf0 + 18*i,buf0 + 18*(i-1),16) == 0) {
- names_added--;
- if (names_added == i) break;
- memmove(buf0 + 18*i,buf0 + 18*(i+1),18*(names_added-i));
- i--;
- }
- }
-
- buf = buf0 + 18*names_added;
-
- n = n->next;
-
- if (!n)
- {
- /* end of this name list: add wins names too? */
- struct subnet_record *w_d;
-
- if (!(w_d = wins_subnet)) break;
-
- if (w_d != d)
- {
- d = w_d;
- n = d->namelist; /* start on the wins name list */
- }
- }
- if (!n) break;
- }
-
- SCVAL(countptr,0,names_added);
-
- /* XXXXXXX we should fill in more fields of the statistics structure */
- bzero(buf,64);
- {
- extern int num_good_sends,num_good_receives;
- SIVAL(buf,20,num_good_sends);
- SIVAL(buf,24,num_good_receives);
- }
-
- buf += 46;
-
- /* Send a POSITIVE NAME STATUS RESPONSE */
- reply_netbios_packet(p,nmb->header.name_trn_id,
- 0,NMB_STATUS,0,False, False,
- &nmb->question.question_name,
- 0x21, 0x01,
- 0, rdata,PTR_DIFF(buf,rdata));
-}
-
-
-/***************************************************************************
-reply to a name query.
-
-with broadcast name queries:
-
- - only reply if the query is for one of YOUR names. all other machines on
- the network will be doing the same thing (that is, only replying to a
- broadcast query if they own it)
- NOTE: broadcast name queries should only be sent out by a machine
- if they HAVEN'T been configured to use WINS. this is generally bad news
- in a wide area tcp/ip network and should be rectified by the systems
- administrator. USE WINS! :-)
- - the exception to this is if the query is for a Primary Domain Controller
- type name (0x1b), in which case, a reply is sent.
-
- - NEVER send a negative response to a broadcast query. no-one else will!
-
-with directed name queries:
-
- - if you are the WINS server, you are expected to respond with either
- a negative response, a positive response, or a wait-for-acknowledgement
- packet, and then later on a pos/neg response.
-
-****************************************************************************/
-void reply_name_query(struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *question = &nmb->question.question_name;
- int name_type = question->name_type;
-
- BOOL bcast = nmb->header.nm_flags.bcast;
- BOOL query_is_to_wins_server = (!bcast &&
- nmb->header.nm_flags.recursion_desired);
- int ttl=0;
- int rcode = 0;
- int nb_flags = 0;
- struct in_addr retip;
- char rdata[6];
- struct subnet_record *d = NULL;
- BOOL success = True;
- struct name_record *n = NULL;
- BOOL acting_as_wins_server = lp_wins_support();
-
- /* directed queries are for WINS server: broadcasts are local SELF queries.
- the exception is Domain Master names. */
-
- if (query_is_to_wins_server)
- {
- /* queries to the WINS server involve the WINS server subnet */
- if (!(d = wins_subnet))
- {
- DEBUG(3,("name query: wins search %s not known\n",
- inet_ntoa(p->ip)));
- success = False;
- }
- }
- else
- {
- /* queries to the WINS client involve, unfortunately, the WINS subnet
- because it contains WINS client (SELF) entries, as _well_ as WINS
- server entries. not good.
- */
-
- if (!(d = find_subnet(*iface_bcast(p->ip))))
- {
- DEBUG(3,("name query: interface for %s not known\n",
- inet_ntoa(p->ip)));
- success = False;
- }
- }
-
- DEBUG(3,("Name query from %s for name %s<0x%x>\n",
- inet_ntoa(p->ip), question->name, question->name_type));
-
- if (!bcast && (name_type == 0x1d) && lp_wins_support())
- {
- /* see WINS manager HELP - 'How WINS Handles Special Names' */
- /* a WINS query (unicasted) for a 0x1d name must always return False */
- success = False;
- }
-
- if (success)
- {
- /* look up the name in the cache */
- n = find_name_search(&d, question, FIND_LOCAL, p->ip);
-
- /* it is a name that already failed DNS lookup or it's expired */
- if (n && (n->source == DNSFAIL ||
- (n->death_time && n->death_time < p->timestamp)))
- {
- success = False;
- }
-
- /* do we want to do dns lookups? */
- /* XXXX this DELAYS nmbd while it does a search. lp_dns_proxy()
- can be switched off, to ensure that the blocking doesn't occur.
- a better solution would be to fork, but this will require a
- mechanism to carry on processing after the query is resolved
- (similar to the netbios queue).
- */
- if (success && !n && (lp_dns_proxy() || !bcast))
- {
- n = dns_name_search(question, p->timestamp);
- }
- }
-
- if (!n) success = False;
-
- if (success)
- {
- if (bcast && n->source != SELF && name_type != 0x1b)
- {
- /* don't respond to broadcast queries unless the query is for
- a name we own or it is for a Primary Domain Controller name */
-
- if (!lp_wins_proxy() ||
- same_net(p->ip,n->ip_flgs[0].ip,*iface_nmask(p->ip)))
- {
- /* never reply with a negative response to broadcast queries */
- return;
- }
- }
-
- /* name is directed query, or it's self, or it's a Domain Master type
- name, or we're replying on behalf of a caller because they are on a
- different subnet and cannot hear the broadcast. XXXX lp_wins_proxy
- should be switched off in environments where broadcasts are forwarded
- */
-
- /* XXXX note: for proxy servers, we should forward the query on to
- another WINS server if the name is not in our database, or we are
- not a WINS server ourselves
- */
- ttl = n->death_time ? n->death_time - p->timestamp : GET_TTL(0);
- retip = n->ip_flgs[0].ip;
- nb_flags = n->ip_flgs[0].nb_flags;
- }
-
- if (!success && bcast) return; /* never reply negative response to bcasts */
-
- /* if the IP is 0 then substitute my IP */
- if (zero_ip(retip)) retip = *iface_ip(p->ip);
-
- /* SPECIAL CASE... If we are a WINS server and the request is explicitly
- *to* the WINS server and the name type is WORKGROUP<0x1e> we should
- respond with the local broadcast address 255.255.255.255.
- */
- if(!bcast && (name_type == 0x1e) && lp_wins_support())
- retip = *interpret_addr2("255.255.255.255");
-
- if (success)
- {
- rcode = 0;
- DEBUG(3,("OK %s\n",inet_ntoa(retip)));
- }
- else
- {
- rcode = 3;
- DEBUG(3,("UNKNOWN\n"));
- }
-
- if (success)
- {
- rdata[0] = nb_flags;
- rdata[1] = 0;
- putip(&rdata[2],(char *)&retip);
- }
-
- /* see rfc1002.txt 4.2.13 */
-
- reply_netbios_packet(p,nmb->header.name_trn_id,
- rcode,NMB_QUERY,0,
- (query_is_to_wins_server && acting_as_wins_server ?
- True : False), /* recursion_available flag */
- True, /* recursion_desired_flag */
- &nmb->question.question_name,
- 0x20, 0x01,
- ttl,
- rdata, success ? 6 : 0);
-}
diff --git a/source/nameservreply.doc b/source/nameservreply.doc
deleted file mode 100644
index a5acf8a9c26..00000000000
--- a/source/nameservreply.doc
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- Unix SMB/Netbios documentation.
- Version 0.0
- Copyright (C) Luke Leighton Andrew Tridgell 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.
-
- Document name: nameservreply.doc
-
- Revision History:
-
- 0.0 - 02jul96 : lkcl@pires.co.uk
- created
-*/
-
-/*************************************************************************
- reply_name_query()
- *************************************************************************/
-
-this function is responsible for replying to a NetBIOS name query.
-
-there are two kinds of name queries: directed, and broadcast. directed
-queries are usually sent to samba in its WINS capacity. such hosts are
-termed 'point-to-point' hosts. broadcast queries are usually sent from
-'broadcast' or 'mixed' hosts.
-
-broadcasting is used by either older NetBIOS hosts, new NetBIOS hosts that
-have not had WINS capabilities added and new NetBIOS hosts that think the
-WINS server has died.
-
-the samba NetBIOS name database is divided into sections, on a
-per-subnet basis. there is also a WINS NetBIOS name database, and for
-convenience this is added as a pseudo-subnet with the ip address of
-255.255.255.255.
-
-the local subnet NetBIOS name databases only contain samba's names.
-the reason for this is that if a broadcast query is received, a NetBIOS
-hosts is only expected to respond if that query is for one of its own
-names (the exception to this is if a host is configured as a 'proxy'
-server, in which case, samba should redirect the query to another WINS
-server).
-
-the WINS pseudo-subnet NetBIOS database contains all NetBIOS names
-that are not 'special browser' type names (regarding this i am a
-_bit_ confused :-). names of type 0x01, 0x1d and 0x1e i consider to
-be 'special browser' names. at the moment. maybe.
-
-the type of search to be initiated is determined. if the NetBIOS name
-type is a non-special-browser name, then the WINS database is included
-in the search.
-
-if the name is not a special browser name, then we need to find the
-right subnet that the query came from. this is done using
-find_req_subnet(). this also has the benefit of stopping any queries
-from subnets that samba does not know about.
-
-if the query is a broadcast query, then the database of the local subnet
-is included in the search.
-
-the name is then searched for in the appropriate NetBIOS data structures.
-if it is found, then we need to check whether it is appropriate for us
-to reply to such a query.
-
-we will only reply if the query is a directed query, the name belongs to
-samba on that subnet, or the name is a domain master browser type,
-or we're doing replies on behalf of hosts on subnets not known to the
-host issuing the query. in the latter instance, it would be appropriate
-if samba is using a WINS server for it to forward the name query on to
-this WINS server.
-
-reply_name_query() then takes note of all the information that is
-needed to construct a reply to the caller. a negative reply (if the
-name is unknown to samba) or a positive reply (the name is known to
-samba) is then issued.
-
-
-/*************************************************************************
- reply_name_status()
- *************************************************************************/
-
-this function is responsible for constructing a reply to a NetBIOS
-name status query. this response contains all samba's NetBIOS names
-on the subnet that the query came in from.
-
-a reply will only be made if the NetBIOS name being queried exists.
-
-see rfc1001.txt and rfc1002.txt for details of the name status reply.
-
-
-/*************************************************************************
- reply_name_reg()
- *************************************************************************/
-
-this function is responsible for updating the NetBIOS name database
-from registration packets sent out by hosts wishing to register a
-name, and for informing them, if necessary, if this is acceptable
-or not.
-
-name registration can be done by broadcast or by point-to-point,
-i.e the registration is sent directly to samba in its capacity as
-a WINS server.
-
-if the name registration is done by broadcast (see rfc1001.txt 15.2.1),
-then samba's involvement in replying is limited to whether that name
-is owned by samba or not, on the relevant subnet.
-
-if the name registration is done point-to-point (see rfc1001.txt 15.2.2)
-then samba will first need to check its WINS name database records and
-proceed accordingly.
-
-samba looks for the appropriate subnet record that the registration
-should be added to / checked against, using find_req_subnet().
-
-next, the name is searched for in the local database or the WINS
-database as appropriate.
-
-if the name is not found, then it is added to the NetBIOS name database,
-using add_netbios_entry(), which may choose not to add the name (not
-that this affects the registration of the name on the network in any way).
-it will only add names to the WINS database, and even then it will only
-add non-special-browser type names.
-
-if the name is found, then samba must decide whether to accept the name
-or not. a group name is always added. for unique names, further checks
-need to be carried out.
-
-firstly, if the name in the database is one of samba's names, or if the
-name in the database is a group name, then it cannot be added as a unique
-name belonging to someone else. it is therefore rejected.
-
-secondly, if the ip address of the name being registered does not match
-against the ip in the database, then the unique name may belong to
-someone else. a check needs to be carried out with the owner in case
-they still wish to keep this name. a detailed discussion of what action
-to take is in rfc1001.txt 15.2.2.2 and 15.2.2.3.
-
-samba currently implements non-secured WINS, whereupon the responsibility
-for checking the name is passed on to the host doing the registration.
-rfc1001.txt refers to this as an END-NODE CHALLENGE REGISTRATION RESPONSE.
-(samba itself cannot yet cope with receiving such responses if it
-registers its names with another WINS server).
-
-having decided what kind of response to send (if any - acceptance of
-name registrations by broadcast is implicit), samba will send either a
-positive or negative NAME REGISTRATION RESPONSE, or an END-NODE CHALLENGE
-REGISTRATION RESPONSE to the host that initially sent the registration.
-
-whew.
-
-
-/*************************************************************************
- reply_name_release()
- *************************************************************************/
-
-this function is responsible for removing a NetBIOS name from the
-database when a server sends a release packet.
-
-samba looks for the appropriate subnet record that the release should
-be removed from, using find_req_subnet(). next, the name is searched
-for in the local database or the WINS database as appropriate.
-
-if the name is found, it is removed from the database and a
-positive reply is sent confirming this. if the name is not
-found, a negative reply is sent.
-
-a reply is _not_ sent if the release was done by broadcast: the
-release is implicit, and we should be grateful that they bothered
-to tell us. if the release was done by directed packet, then
-we deal with it as a WINS server and must reply (pos / neg).
-
-at present, the criteria for removing a name have yet to be
-developed / experimented with. at present, the only flags that
-are checked are the NetBIOS flags.
-
-
-/*************************************************************************
- send_name_response()
- *************************************************************************/
-
-this function is a wrap around reply_netbios_packet(). it sends
-a response to a name registration or release packet, minimising
-the function parameters needed to do this.
-
-if the function is called with the parameter 'success' set to
-True, then a positive response (to the registration or release)
-is made (see rfc1002.txt 4.2.5 and 4.2.10). if this parameter
-is False, then a negative response is issued (see rfc1002.txt
-4.2.6 and 4.2.11)
-
-if the function is called with a registration code, and the
-parameter 'recurse' is False, then an End-Node Challenge
-Registration response is issued (see rfc1002.txt 4.2.7)
-
-note: this function could also easily be used for name conflict
-demand (see rfc1002.txt 4.2.8).
-
-note: End-Node Challenge Registration response is only sent in
-non-secured NetBIOS Name Server implementations. samba now
-implements secured NetBIOS Name Server functionality (see
-rfc1001.txt 15.1.6).
-
diff --git a/source/nameservresp.c b/source/nameservresp.c
deleted file mode 100644
index a88481d06b0..00000000000
--- a/source/nameservresp.c
+++ /dev/null
@@ -1,848 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-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.
-
- Revision History:
-
- Module name: nameservresp.c
-
- 14 jan 96: lkcl@pires.co.uk
- added multiple workgroup domain master support
-
- 05 jul 96: lkcl@pires.co.uk
- created module nameservresp containing NetBIOS response functions
-
-*/
-
-#include "includes.h"
-
-extern int ClientNMB;
-
-extern int DEBUGLEVEL;
-
-extern pstring scope;
-extern fstring myworkgroup;
-extern struct in_addr ipzero;
-extern struct in_addr wins_ip;
-extern struct in_addr ipzero;
-
-
-#define GET_TTL(ttl) ((ttl)?MIN(ttl,lp_max_ttl()):lp_max_ttl())
-
-
-/****************************************************************************
- response for a reg release received. samba has asked a WINS server if it
- could release a name.
- **************************************************************************/
-static void response_name_release(struct nmb_name *ans_name,
- struct subnet_record *d, struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- char *name = ans_name->name;
- int type = ans_name->name_type;
-
- DEBUG(4,("response name release received\n"));
-
- if (nmb->header.rcode == 0 && nmb->answers->rdata)
- {
- /* IMPORTANT: see expire_netbios_response_entries() */
-
- struct in_addr found_ip;
- putip((char*)&found_ip,&nmb->answers->rdata[2]);
-
- /* NOTE: we only release our own names at present */
- if (ismyip(found_ip))
- {
- name_unregister_work(d,name,type);
- }
- else
- {
- DEBUG(2,("name release for different ip! %s %s\n",
- inet_ntoa(found_ip), namestr(ans_name)));
- }
- }
- else
- {
- DEBUG(2,("name release for %s rejected!\n", namestr(ans_name)));
-
- /* XXXX PANIC! what to do if it's one of samba's own names? */
-
- /* XXXX do we honestly care if our name release was rejected?
- only if samba is issuing the release on behalf of some out-of-sync
- server. if it's one of samba's SELF names, we don't care. */
- }
-}
-
-
-/****************************************************************************
-response for a reg request received
-**************************************************************************/
-static void response_name_reg(struct nmb_name *ans_name,
- struct subnet_record *d, struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- BOOL bcast = nmb->header.nm_flags.bcast;
- char *name = ans_name->name;
- int type = ans_name->name_type;
-
- DEBUG(4,("response name registration received!\n"));
-
-#if 1
- /* This code is neccesitated due to bugs in earlier versions of
- Samba (up to 1.9.16p11). They respond to a broadcast
- name registration of WORKGROUP<1b> when they should
- not. Hence, until these versions are gone, we should
- treat such errors as success for this particular
- case only. jallison@whistle.com.
- */
- if ( ((d != wins_subnet) && (nmb->header.rcode == 6) && strequal(myworkgroup, name) &&
- (type == 0x1b)) ||
- (nmb->header.rcode == 0 && nmb->answers->rdata))
-#else
- if (nmb->header.rcode == 0 && nmb->answers->rdata)
-#endif
- {
- /* IMPORTANT: see expire_netbios_response_entries() */
-
- int nb_flags = nmb->answers->rdata[0];
- int ttl = nmb->answers->ttl;
- struct in_addr found_ip;
-
- putip((char*)&found_ip,&nmb->answers->rdata[2]);
-
- name_register_work(d,name,type,nb_flags,ttl,found_ip,bcast);
- }
- else
- {
- DEBUG(2,("name registration for %s rejected by ip %s!\n",
- namestr(ans_name), inet_ntoa(p->ip)));
-
- /* oh dear. we have problems. possibly unbecome a master browser. */
- name_unregister_work(d,name,type);
- }
-}
-
-/****************************************************************************
- response from a name query server check. states of type NAME_QUERY_DOM_SRV_CHK,
- NAME_QUERY_SRV_CHK, and NAME_QUERY_FIND_MST dealt with here.
- ****************************************************************************/
-static void response_server_check(struct nmb_name *ans_name,
- struct response_record *n, struct subnet_record *d, struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct in_addr send_ip;
- enum state_type cmd;
-
- /* This next fix was from Bernhard Laeser <nlaesb@ascom.ch>
- who noticed we were replying directly back to the server
- we sent to - rather than reading the response.
- */
-
- if (nmb->header.rcode == 0 && nmb->answers->rdata)
- putip((char*)&send_ip,&nmb->answers->rdata[2]);
- else
- {
-
- DEBUG(2,("response_server_check: name query for %s failed\n",
- namestr(ans_name)));
- return;
- }
-
- /* issue another state: this time to do a name status check */
-
- cmd = (n->state == NAME_QUERY_DOM_SRV_CHK) ?
- NAME_STATUS_DOM_SRV_CHK : NAME_STATUS_SRV_CHK;
-
- /* initiate a name status check on address given in the reply
- record. In addition, the workgroup being checked has been stored
- in the response_record->my_name (see announce_master) we
- also propagate this into the same field. */
- queue_netbios_packet(d,ClientNMB,NMB_STATUS, cmd,
- ans_name->name, ans_name->name_type,
- 0,0,0,n->my_name,NULL,
- False,False,send_ip,n->reply_to_ip);
-}
-
-
-/****************************************************************************
- interpret a node status response. this is pretty hacked: we need two bits of
- info. a) the name of the workgroup b) the name of the server. it will also
- add all the names it finds into the namelist.
-****************************************************************************/
-static BOOL interpret_node_status(struct subnet_record *d,
- char *p, struct nmb_name *name,int t,
- char *serv_name, struct in_addr ip, BOOL bcast)
-{
- int numnames = CVAL(p,0);
- BOOL found = False;
-
- DEBUG(4,("received %d names\n",numnames));
-
- p += 1;
-
- if (serv_name) *serv_name = 0;
-
- while (numnames--)
- {
- char qname[17];
- int type;
- fstring flags;
- int nb_flags;
-
- BOOL group = False;
- BOOL add = False;
-
- *flags = 0;
-
- StrnCpy(qname,p,15);
- type = CVAL(p,15);
- nb_flags = p[16];
- trim_string(qname,NULL," ");
-
- p += 18;
-
- if (NAME_GROUP (nb_flags)) { strcat(flags,"<GROUP> "); group=True;}
- if (NAME_BFLAG (nb_flags)) { strcat(flags,"B "); }
- if (NAME_PFLAG (nb_flags)) { strcat(flags,"P "); }
- if (NAME_MFLAG (nb_flags)) { strcat(flags,"M "); }
- if (NAME_HFLAG (nb_flags)) { strcat(flags,"H "); }
- if (NAME_DEREG (nb_flags)) { strcat(flags,"<DEREGISTERING> "); }
- if (NAME_CONFLICT (nb_flags)) { strcat(flags,"<CONFLICT> "); }
- if (NAME_ACTIVE (nb_flags)) { strcat(flags,"<ACTIVE> "); add=True; }
- if (NAME_PERMANENT(nb_flags)) { strcat(flags,"<PERMANENT> "); add=True;}
-
- /* we want the server name */
- if (serv_name && !*serv_name && !group && type == 0x20)
- {
- StrnCpy(serv_name,qname,15);
- serv_name[15] = 0;
- }
-
- /* looking for a name and type? */
- if (name && !found && (t == type))
- {
- /* take a guess at some of the name types we're going to ask for.
- evaluate whether they are group names or no... */
- if (((t == 0x1b || t == 0x1d || t == 0x20 ) && !group) ||
- ((t == 0x1c || t == 0x1e ) && group))
- {
- found = True;
- make_nmb_name(name,qname,type,scope);
- }
- }
-
- DEBUG(4,("\t%s(0x%x)\t%s\n",qname,type,flags));
- }
- DEBUG(4,("num_good_sends=%d num_good_receives=%d\n",
- IVAL(p,20),IVAL(p,24)));
- return found;
-}
-
-
-/****************************************************************************
- response from a name status check. states of type NAME_STATUS_DOM_SRV_CHK
- and NAME_STATUS_SRV_CHK dealt with here.
- ****************************************************************************/
-static void response_name_status_check(struct in_addr ip,
- struct nmb_packet *nmb, BOOL bcast,
- struct response_record *n, struct subnet_record *d)
-{
- /* NMB_STATUS arrives: contains workgroup name and server name required.
- amongst other things. */
-
- struct nmb_name name;
- fstring serv_name;
-
- if (interpret_node_status(d,nmb->answers->rdata,
- &name,0x20,serv_name,ip,bcast))
- {
- if (*serv_name)
- {
- /* response_record->my_name contains the
- workgroup name to sync with. See
- response_server_check() */
- sync_server(n->state,serv_name,
- n->my_name,name.name_type, d, n->send_ip);
- }
- }
- else
- {
- DEBUG(1,("No 0x20 name type in interpret_node_status()\n"));
- }
-}
-
-
-/****************************************************************************
- response from a name query for secured WINS registration. a state of
- NAME_REGISTER_CHALLENGE is dealt with here.
- ****************************************************************************/
-static void response_name_query_register(struct nmb_packet *nmb,
- struct nmb_name *ans_name,
- struct response_record *n, struct subnet_record *d)
-{
- struct in_addr register_ip;
- BOOL new_owner;
-
- DEBUG(4, ("Name query at %s ip %s - ",
- namestr(&n->name), inet_ntoa(n->send_ip)));
-
- if (!name_equal(&n->name, ans_name))
- {
- /* someone gave us the wrong name as a reply. oops. */
- /* XXXX should say to them 'oi! release that name!' */
-
- DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
- return;
- }
-
- if (nmb->header.rcode == 0 && nmb->answers->rdata)
- {
- /* we had sent out a name query to the current owner
- of a name because someone else wanted it. now they
- have responded saying that they still want the name,
- so the other host can't have it.
- */
-
- /* first check all the details are correct */
-
- int nb_flags = nmb->answers->rdata[0];
- struct in_addr found_ip;
-
- putip((char*)&found_ip,&nmb->answers->rdata[2]);
-
- if (nb_flags != n->nb_flags)
- {
- /* someone gave us the wrong nb_flags as a reply. oops. */
- /* XXXX should say to them 'oi! release that name!' */
-
- DEBUG(4,("expected nb_flags: %d\n", n->nb_flags));
- DEBUG(4,("unexpected nb_flags: %d\n", nb_flags));
- return;
- }
-
- if (!ip_equal(n->send_ip, found_ip))
- {
- /* someone gave us the wrong ip as a reply. oops. */
- /* XXXX should say to them 'oi! release that name!' */
-
- DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
- DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
- return;
- }
-
- DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
-
- /* fine: now tell the other host they can't have the name */
- register_ip = n->send_ip;
- new_owner = False;
- }
- else
- {
- DEBUG(4, (" NEGATIVE RESPONSE!\n"));
-
- /* the owner didn't want the name: the other host can have it */
- register_ip = n->reply_to_ip;
- new_owner = True;
- }
-
- /* register the old or the new owners' ip */
- add_name_respond(d, n->fd, d->myip, n->response_id,&n->name,n->nb_flags,
- GET_TTL(0), register_ip,
- new_owner, n->reply_to_ip);
-}
-
-
-/****************************************************************************
- response from a name query to sync browse lists or to update our netbios
- entry. states of type NAME_QUERY_SYNC and NAME_QUERY_CONFIRM
- ****************************************************************************/
-static void response_name_query_sync(struct nmb_packet *nmb,
- struct nmb_name *ans_name, BOOL bcast,
- struct response_record *n, struct subnet_record *d)
-{
- DEBUG(4, ("Name query at %s ip %s - ",
- namestr(&n->name), inet_ntoa(n->send_ip)));
-
- if (!name_equal(&n->name, ans_name))
- {
- /* someone gave us the wrong name as a reply. oops. */
- DEBUG(4,("unexpected name received: %s\n", namestr(ans_name)));
- return;
- }
-
- if (nmb->header.rcode == 0 && nmb->answers->rdata)
- {
- int nb_flags = nmb->answers->rdata[0];
- struct in_addr found_ip;
-
- putip((char*)&found_ip,&nmb->answers->rdata[2]);
-
- if (!ip_equal(n->send_ip, found_ip))
- {
- /* someone gave us the wrong ip as a reply. oops. */
- DEBUG(4,("expected ip: %s\n", inet_ntoa(n->send_ip)));
- DEBUG(4,("unexpected ip: %s\n", inet_ntoa(found_ip)));
- return;
- }
-
- DEBUG(4, (" OK: %s\n", inet_ntoa(found_ip)));
-
- if (n->state == NAME_QUERY_SYNC_LOCAL ||
- n->state == NAME_QUERY_SYNC_REMOTE)
- {
- struct work_record *work = NULL;
- /* We cheat here as we know that the workgroup name has
- been placed in the my_comment field of the
- response_record struct by the code in
- start_sync_browse_entry().
- */
- if ((work = find_workgroupstruct(d, n->my_comment, False)))
- {
- BOOL local_list_only = n->state == NAME_QUERY_SYNC_LOCAL;
-
- /* the server is there: sync quick before it (possibly) dies! */
- sync_browse_lists(d, work, ans_name->name, ans_name->name_type,
- found_ip, local_list_only);
- }
- }
- else
- {
- /* update our netbios name list (re-register it if necessary) */
- add_netbios_entry(d, ans_name->name, ans_name->name_type,
- nb_flags,GET_TTL(0),REGISTER,
- found_ip,False,!bcast);
- }
- }
- else
- {
- DEBUG(4, (" NEGATIVE RESPONSE!\n"));
-
- if (n->state == NAME_QUERY_CONFIRM)
- {
- /* XXXX remove_netbios_entry()? */
- /* lots of things we ought to do, here. if we get here,
- then we're in a mess: our name database doesn't match
- reality. sort it out
- */
- remove_netbios_name(d,n->name.name, n->name.name_type,
- REGISTER,n->send_ip);
- }
- }
-}
-
-/****************************************************************************
- response from a name query for DOMAIN<1b>
- NAME_QUERY_DOMAIN is dealt with here - we are trying to become a domain
- master browser and WINS replied - check it's our address.
- ****************************************************************************/
-static void response_name_query_domain(struct nmb_name *ans_name,
- struct nmb_packet *nmb,
- struct response_record *n, struct subnet_record *d)
-{
- DEBUG(4, ("response_name_query_domain: Got %s response from %s for query \
-for %s\n", nmb->header.rcode == 0 ? "success" : "failure",
- inet_ntoa(n->send_ip), namestr(ans_name)));
-
- /* Check the name is correct and ip address returned is our own. If it is then we
- just remove the response record.
- */
- if (name_equal(&n->name, ans_name) && (nmb->header.rcode == 0) && (nmb->answers->rdata))
- {
- struct in_addr found_ip;
-
- putip((char*)&found_ip,&nmb->answers->rdata[2]);
- /* Samba 1.9.16p11 servers seem to return the broadcast address for this
- query. */
- if (ismyip(found_ip) || ip_equal(wins_ip, found_ip) || ip_equal(ipzero, found_ip))
- {
- DEBUG(4, ("response_name_query_domain: WINS server returned our ip \
-address. Pretending we never received response.\n"));
- n->num_msgs = 0;
- n->repeat_count = 0;
- n->repeat_time = 0;
- }
- else
- {
- DEBUG(0,("response_name_query_domain: WINS server already has a \
-domain master browser registered %s at address %s\n",
- namestr(ans_name), inet_ntoa(found_ip)));
- }
- }
- else
- {
- /* Negative/incorrect response. No domain master
- browser was registered - pretend we didn't get this response.
- */
- n->num_msgs = 0;
- n->repeat_count = 0;
- n->repeat_time = 0;
- }
-
-}
-
-/****************************************************************************
- report the response record type
- ****************************************************************************/
-static void debug_rr_type(int rr_type)
-{
- switch (rr_type)
- {
- case NMB_STATUS: DEBUG(3,("Name status ")); break;
- case NMB_QUERY : DEBUG(3,("Name query ")); break;
- case NMB_REG : DEBUG(3,("Name registration ")); break;
- case NMB_REL : DEBUG(3,("Name release ")); break;
- default : DEBUG(1,("wrong response packet type received")); break;
- }
-}
-
-/****************************************************************************
- report the response record nmbd state
- ****************************************************************************/
-void debug_state_type(int state)
-{
- /* report the state type to help debugging */
- switch (state)
- {
- case NAME_QUERY_DOM_SRV_CHK : DEBUG(4,("NAME_QUERY_DOM_SRV_CHK\n")); break;
- case NAME_QUERY_SRV_CHK : DEBUG(4,("NAME_QUERY_SRV_CHK\n")); break;
- case NAME_QUERY_FIND_MST : DEBUG(4,("NAME_QUERY_FIND_MST\n")); break;
- case NAME_QUERY_MST_CHK : DEBUG(4,("NAME_QUERY_MST_CHK\n")); break;
- case NAME_QUERY_CONFIRM : DEBUG(4,("NAME_QUERY_CONFIRM\n")); break;
- case NAME_QUERY_SYNC_LOCAL : DEBUG(4,("NAME_QUERY_SYNC_LOCAL\n")); break;
- case NAME_QUERY_SYNC_REMOTE : DEBUG(4,("NAME_QUERY_SYNC_REMOTE\n")); break;
- case NAME_QUERY_DOMAIN : DEBUG(4,("NAME_QUERY_DOMAIN\n")); break;
-
- case NAME_REGISTER : DEBUG(4,("NAME_REGISTER\n")); break;
- case NAME_REGISTER_CHALLENGE : DEBUG(4,("NAME_REGISTER_CHALLENGE\n"));break;
-
- case NAME_RELEASE : DEBUG(4,("NAME_RELEASE\n")); break;
-
- case NAME_STATUS_DOM_SRV_CHK : DEBUG(4,("NAME_STATUS_DOM_SRV_CHK\n")); break;
- case NAME_STATUS_SRV_CHK : DEBUG(4,("NAME_STATUS_SRV_CHK\n")); break;
-
- default: break;
- }
-}
-
-/****************************************************************************
- report any problems with the fact that a response has been received.
-
- (responses for certain types of operations are only expected from one host)
- ****************************************************************************/
-static BOOL response_problem_check(struct response_record *n,
- struct nmb_packet *nmb, char *ans_name)
-{
- switch (nmb->answers->rr_type)
- {
- case NMB_REL:
- {
- if (n->num_msgs > 1)
- {
- DEBUG(1,("more than one release name response received!\n"));
- return True;
- }
- break;
- }
-
- case NMB_REG:
- {
- if (n->num_msgs > 1)
- {
- DEBUG(1,("more than one register name response received!\n"));
- return True;
- }
- break;
- }
-
- case NMB_QUERY:
- {
- if (n->num_msgs > 1)
- {
- if (nmb->header.rcode == 0 && nmb->answers->rdata)
- {
- int nb_flags = nmb->answers->rdata[0];
-
- if ((!NAME_GROUP(nb_flags)))
- {
- /* oh dear. more than one person responded to a
- unique name.
- there is either a network problem, a
- configuration problem
- or a server is mis-behaving */
-
- /* XXXX mark the name as in conflict, and then let the
- person who just responded know that they
- must also mark it
- as in conflict, and therefore must NOT use it.
- see rfc1001.txt 15.1.3.5 */
-
- /* this may cause problems for some
- early versions of nmbd */
-
- switch (n->state)
- {
- case NAME_QUERY_FIND_MST:
- {
- /* query for ^1^2__MSBROWSE__^2^1 expect
- lots of responses */
- return False;
- }
- case NAME_QUERY_DOM_SRV_CHK:
- case NAME_QUERY_SRV_CHK:
- case NAME_QUERY_MST_CHK:
- {
- if (!strequal(ans_name,n->name.name))
- {
- /* one subnet, one master browser
- per workgroup */
- /* XXXX force an election? */
-
- DEBUG(3,("more than one master browser replied!\n"));
- return True;
- }
- break;
- }
- default: break;
- }
- DEBUG(3,("Unique Name conflict detected!\n"));
- return True;
- }
- }
- else
- {
- /* we have received a negative reply,
- having already received
- at least one response (pos/neg).
- something's really wrong! */
-
- DEBUG(3,("wierd name query problem detected!\n"));
- return True;
- }
- }
- }
- }
- return False;
-}
-
-#if 0
-/****************************************************************************
- check that the response received is compatible with the response record
- ****************************************************************************/
-static BOOL response_compatible(struct response_record *n,
- struct nmb_packet *nmb)
-{
- switch (n->state)
- {
- case NAME_RELEASE:
- {
- if (nmb->answers->rr_type != 0x20)
- {
- DEBUG(1,("Name release reply has wrong answer rr_type\n"));
- return False;
- }
- break;
- }
-
- case NAME_REGISTER:
- {
- if (nmb->answers->rr_type != 0x20)
- {
- DEBUG(1,("Name register reply has wrong answer rr_type\n"));
- return False;
- }
- break;
- }
-
- case NAME_REGISTER_CHALLENGE: /* this is a query: we then do a register */
- case NAME_QUERY_CONFIRM:
- case NAME_QUERY_SYNC_LOCAL:
- case NAME_QUERY_SYNC_REMOTE:
- case NAME_QUERY_DOM_SRV_CHK:
- case NAME_QUERY_SRV_CHK:
- case NAME_QUERY_FIND_MST:
- case NAME_QUERY_MST_CHK:
- {
- if (nmb->answers->rr_type != 0x20)
- {
- DEBUG(1,("Name query reply has wrong answer rr_type\n"));
- return False;
- }
- break;
- }
-
- case NAME_STATUS_DOM_SRV_CHK:
- case NAME_STATUS_SRV_CHK:
- {
- if (nmb->answers->rr_type != 0x21)
- {
- DEBUG(1,("Name status reply has wrong answer rr_type\n"));
- return False;
- }
- break;
- }
-
- default:
- {
- DEBUG(1,("unknown state type received in response_netbios_packet\n"));
- return False;
- }
- }
- return True;
-}
-#endif
-
-
-/****************************************************************************
- process the response packet received
- ****************************************************************************/
-static void response_process(struct subnet_record *d, struct packet_struct *p,
- struct response_record *n, struct nmb_packet *nmb,
- BOOL bcast, struct nmb_name *ans_name)
-{
- switch (n->state)
- {
- case NAME_RELEASE:
- {
- response_name_release(ans_name, d, p);
- break;
- }
-
- case NAME_REGISTER:
- {
- response_name_reg(ans_name, d, p);
- break;
- }
-
- case NAME_REGISTER_CHALLENGE:
- {
- response_name_query_register(nmb, ans_name, n, d);
- break;
- }
-
- case NAME_QUERY_DOM_SRV_CHK:
- case NAME_QUERY_SRV_CHK:
- case NAME_QUERY_FIND_MST:
- {
- response_server_check(ans_name, n, d, p);
- break;
- }
-
- case NAME_STATUS_DOM_SRV_CHK:
- case NAME_STATUS_SRV_CHK:
- {
- response_name_status_check(p->ip, nmb, bcast, n, d);
- break;
- }
-
- case NAME_QUERY_CONFIRM:
- case NAME_QUERY_SYNC_LOCAL:
- case NAME_QUERY_SYNC_REMOTE:
- {
- response_name_query_sync(nmb, ans_name, bcast, n, d);
- break;
- }
- case NAME_QUERY_MST_CHK:
- {
- /* no action required here. it's when NO responses are received
- that we need to do something. see expire_name_query_entries() */
-
- DEBUG(4, ("Master browser exists for %s at %s (just checking!)\n",
- namestr(&n->name), inet_ntoa(n->send_ip)));
- break;
- }
-
- case NAME_QUERY_DOMAIN:
- {
- /* We were asking to be a domain master browser, and someone
- replied. If it was the WINS server and the IP it is
- returning is our own - then remove the record and pretend
- we didn't get a response. Else we do nothing and let
- dead_netbios_entry deal with it.
- We can only become domain master browser
- when no broadcast responses are received and WINS
- either contains no entry for the DOMAIN<1b> name or
- contains our IP address.
- */
- response_name_query_domain(ans_name, nmb, n, d);
- break;
- }
- default:
- {
- DEBUG(1,("unknown state type received in response_netbios_packet\n"));
- break;
- }
- }
-}
-
-
-/****************************************************************************
- response from a netbios packet.
- ****************************************************************************/
-void response_netbios_packet(struct packet_struct *p)
-{
- struct nmb_packet *nmb = &p->packet.nmb;
- struct nmb_name *ans_name = NULL;
- BOOL bcast = nmb->header.nm_flags.bcast;
- struct response_record *n;
- struct subnet_record *d = NULL;
-
- if (!(n = find_response_record(&d,nmb->header.name_trn_id))) {
- DEBUG(2,("unknown netbios response (received late or from nmblookup?)\n"));
- return;
- }
-
- if (!d)
- {
- DEBUG(2,("response packet: subnet %s not known\n", inet_ntoa(p->ip)));
- return;
- }
-
- /* args wrong way round: spotted by ccm@shentel.net */
- if (!same_net(d->bcast_ip, p->ip, d->mask_ip)) /* copes with WINS 'subnet' */
- {
- DEBUG(2,("response from %s. ", inet_ntoa(p->ip)));
- DEBUG(2,("expected on subnet %s. hmm.\n", inet_ntoa(d->bcast_ip)));
- }
-
- if (nmb->answers == NULL)
- {
- /* hm. the packet received was a response, but with no answer. wierd! */
- DEBUG(2,("NMB packet response from %s (bcast=%s) - UNKNOWN\n",
- inet_ntoa(p->ip), BOOLSTR(bcast)));
- return;
- }
-
- ans_name = &nmb->answers->rr_name;
- DEBUG(3,("response for %s from %s (bcast=%s)\n",
- namestr(ans_name), inet_ntoa(p->ip), BOOLSTR(bcast)));
-
- debug_rr_type(nmb->answers->rr_type);
-
- n->num_msgs++; /* count number of responses received */
- n->repeat_count = 0; /* don't resend: see expire_netbios_packets() */
-
- debug_state_type(n->state);
-
- /* problem checking: multiple responses etc */
- if (response_problem_check(n, nmb, ans_name->name))
- return;
-
- /* now deal with the current state */
- response_process(d, p, n, nmb, bcast, ans_name);
-}
diff --git a/source/nameservresp.doc b/source/nameservresp.doc
deleted file mode 100644
index 635db45084f..00000000000
--- a/source/nameservresp.doc
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- Unix SMB/Netbios documentation.
- Version 0.0
- Copyright (C) Luke Leighton Andrew Tridgell 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.
-
- Document name: nameservresp.doc
-
- Revision History:
-
- 0.0 - 02jul96 : lkcl@pires.co.uk
- created
-*/
-
-this module deals with the receipt of response packets. the
-response packets are expected to be received, and there is a
-record of this kept (see also: modules nameresp and namedbresp)
-
-point of interest to design purists: every function in this
-module is static except response_netbios_packet().
-
-/*************************************************************************
- response_netbios_packet()
- *************************************************************************/
-
-this function receives netbios response packets. the samba server
-(or a rogue tcp/ip system, or nmblookup) will have sent out a packet
-requesting a response. a client (or a rogue tcp/ip system) responds
-to that request.
-
-this function checks the validity of the packet it receives.
-the expected response records are searched for the transaction id,
-to see if it's a response expected by the samba server. if it isn't
-it's reported as such, and ignored.
-
-if the response is found, then the subnet it was expected from will
-also have been found. the subnet it actually came in on can be
-checked against the subnet it was expected from and reported,
-otherwise this function just carries on.
-
-the number of responses received is increased, and the number of
-retries left to be sent is set to zero.
-
-after debug information is reported, and validation of the netbios
-packet (e.g only one response from one machine is expected for some
-functions) has occurred, the packet is processed. when the initial
-request was sent out, the expected response record was flagged with,
-for lack of a better word, a samba 'state' type. whenever a
-response is received, the appropriate function is called to carry on
-where the program control flow was interrupted while awaiting exactly
-such a response.
-
-please note that _not_ receiving a response is dealt with in another
-area of code - expire_netbios_response_entries().
-
-
-/*************************************************************************
- response_name_query_sync()
- *************************************************************************/
-
-this function receives responses to samba 'states' NAME_QUERY_SYNC and
-NAME_QUERY_CONFIRM.
-
-NAME_QUERY_SYNC: name query a server before synchronising browse lists.
-NAME_QUERY_CONFIRM: name query a server to check that it's alive.
-
-a NAME_QUERY_SYNC will be carried out in order to check that a server
-is alive before syncing browse lists. we don't want to delay the SMB
-NetServerEnum api just because the server has gone down: we have too
-much else to do.
-
-a NAME_QUERY_CONFIRM is just a name query to see whether the server is
-alive. these queries are sent out by samba's WINS server side, to verify
-its netbios name database of all machines that have registered with it.
-
-we don't normally expect a negative response from such a query, although
-we may do so if the query was sent to another WINS server. the registered
-entry should be removed if we receive a negative response.
-
-
-/*************************************************************************
- response_name_status_check()
- *************************************************************************/
-
-this function receives responses to samba 'states' NAME_STATUS_SRV_CHK
-and NAME_STATUS_DOM_SRV_CHK
-
-NAME_STATUS_DOM_SRV_CHK: name status a domain master browser
- confirm its domain and then initiate syncing
- its browse list.
-
-NAME_STATUS_SRV_CHK: same as NAME_STATUS_DOM_SRV_CHK except the
- name status is issued to a master browser.
-
-if we don't know what workgroup a server is responsible for, but we
-know that there is a master browser at a certain ip, we can issue a
-name status check. from the response received, there will be
-a master browser netbios entry. this will allow us to synchronise
-browse lists with that machine and then add the information to the
-correct part of samba's workgroup - server database.
-
-
-/*************************************************************************
- response_server_check()
- *************************************************************************/
-
-this function receives responses to samba 'states' NAME_QUERY_DOM_SRV_CHK,
-NAME_QUERY_SRV_CHK and NAME_QUERY_FIND_MST.
-
-NAME_QUERY_FIND_MST: issued as a broadcast when we wish to find out all
- master browsers (i.e all servers that have registered
- the NetBIOS name ^1^2__MSBROWSE__^2(0x1), and then
- issue a NAME_STATUS_MASTER_CHECK on any servers that
- respond, which will initiate a sync browse lists.
-
-NAME_QUERY_DOM_SRV_CHK: same as a NAME_QUERY_FIND_MST except this is sent
- to a domain master browser.
-
-NAME_QUERY_SRV_CHK: same as a NAME_QUERY_DOM_SRV_CHK except this is sent to
- a master browser.
-
-the purpose of each of these states is to do a broadcast name query, or
-a name query directed at a WINS server, then to all hosts that respond,
-we issue a name status check, which will confirm for us the workgroup
-or domain name, and then initiate issuing a sync browse list call with
-that server.
-
-a NAME_QUERY_SRV_CHK is sent when samba receives a list of backup
-browsers. it checks to see if that server is alive (by doing a
-name query on a server) and then syncs browse lists with it.
-
-
-/*************************************************************************
- response_name_reg()
- *************************************************************************/
-
-this function is responsible for dealing with samba's registration
-attempts, by broadcast to a local subnet, or point-to-point with
-another WINS server.
-
-please note that it cannot cope with END-NODE CHALLENGE REGISTRATION
-RESPONSEs at present.
-
-when a response is received, samba determines if the response is a
-positive or a negative one. if it is a positive response, the name
-is added to samba's database.
-
-when a negative response is received, samba will remove the name
-from its database. if, however, the name is a browser type (0x1b is
-a domain master browser type name; or 0x1d, which is a local master
-browser type name) then it must also stop being a domain master
-browser or master browser respectively, depending on what kind
-of name was rejected.
-
-(when no response is received, then expire_netbios_response_entries()
-is expected to deal with this. the only case that is dealt with here
-at present is when the registration was done by broadcast. if there
-is no challenge to the broadcast registration, it is implicitly
-assumed that claiming the name is acceptable).
-
-
-/*************************************************************************
- response_name_release()
- *************************************************************************/
-
-this function is responsible for removing samba's NetBIOS name when
-samba contacts another WINS server with which it had registered the
-name.
-
-only positive name releases are expected and dealt with. exactly what
-to do if a negative name release (i.e someone says 'oi! you have to
-keep that name!') is received is uncertain.
-
-(when no response is received, then expire_netbios_response_entries()
-is expected to deal with this. if there is no challenge to the release
-of the name, the name is then removed from that subnet's NetBIOS
-name database).
-
diff --git a/source/namework.c b/source/namework.c
deleted file mode 100644
index 3e1ac220058..00000000000
--- a/source/namework.c
+++ /dev/null
@@ -1,723 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-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.
-
- Revision History:
-
- 14 jan 96: lkcl@pires.co.uk
- added multiple workgroup domain master support
-
-*/
-
-#include "includes.h"
-
-extern int ClientNMB;
-extern int ClientDGRAM;
-
-#define TEST_CODE /* want to debug unknown browse packets */
-
-extern int DEBUGLEVEL;
-extern pstring scope;
-extern BOOL CanRecurse;
-
-extern pstring myname;
-extern fstring myworkgroup;
-
-extern int ClientNMB;
-extern int ClientDGRAM;
-
-extern struct in_addr ipzero;
-
-extern int workgroup_count; /* total number of workgroups we know about */
-
-/* this is our domain/workgroup/server database */
-extern struct subnet_record *subnetlist;
-
-extern int updatecount;
-
-/* backup request types: which servers are to be included */
-#define MASTER_TYPE (SV_TYPE_MASTER_BROWSER)
-#define DOMCTL_TYPE (SV_TYPE_DOMAIN_CTRL )
-
-extern time_t StartupTime;
-
-extern BOOL updatedlists;
-
-/****************************************************************************
-tell a server to become a backup browser
-state - 0x01 become backup instead of master
- - 0x02 remove all entries in browse list and become non-master
- - 0x04 stop master browser service altogether. NT ignores this
-**************************************************************************/
-void reset_server(char *name, int state, struct in_addr ip)
-{
- char outbuf[20];
- char *p;
-
- bzero(outbuf,sizeof(outbuf));
- p = outbuf;
-
- CVAL(p,0) = ANN_ResetBrowserState;
- CVAL(p,2) = state;
- p += 2;
-
- DEBUG(2,("sending reset to %s %s of state %d\n",
- name,inet_ntoa(ip),state));
-
- send_mailslot_reply(False,BROWSE_MAILSLOT,ClientDGRAM,
- outbuf,PTR_DIFF(p,outbuf),
- myname,name,0x20,0x1d,ip,*iface_ip(ip));
-}
-
-
-/****************************************************************************
-tell a server to become a backup browser
-**************************************************************************/
-void tell_become_backup(void)
-{
- /* XXXX note: this function is currently unsuitable for use, as it
- does not properly check that a server is in a fit state to become
- a backup browser before asking it to be one.
- */
-
- struct subnet_record *d;
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
- {
- struct work_record *work;
- for (work = d->workgrouplist; work; work = work->next)
- {
- struct server_record *s;
- int num_servers = 0;
- int num_backups = 0;
-
- for (s = work->serverlist; s; s = s->next)
- {
- if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
-
- num_servers++;
-
- if (is_myname(s->serv.name)) continue;
-
- if (s->serv.type & SV_TYPE_BACKUP_BROWSER) {
- num_backups++;
- continue;
- }
-
- if (s->serv.type & SV_TYPE_MASTER_BROWSER) continue;
-
- if (!(s->serv.type & SV_TYPE_POTENTIAL_BROWSER)) continue;
-
- DEBUG(3,("num servers: %d num backups: %d\n",
- num_servers, num_backups));
-
- /* make first server a backup server. thereafter make every
- tenth server a backup server */
- if (num_backups != 0 && (num_servers+9) / num_backups > 10)
- {
- continue;
- }
-
- DEBUG(2,("sending become backup to %s %s for %s\n",
- s->serv.name, inet_ntoa(d->bcast_ip),
- work->work_group));
-
- /* type 11 request from MYNAME(20) to WG(1e) for SERVER */
- do_announce_request(s->serv.name, work->work_group,
- ANN_BecomeBackup, 0x20, 0x1e, d->bcast_ip);
- }
- }
- }
-}
-
-
-/*******************************************************************
- same context: scope. should check name_type as well, and makes sure
- we don't process messages from ourselves
- ******************************************************************/
-BOOL same_context(struct dgram_packet *dgram)
-{
- if (!strequal(dgram->dest_name .scope,scope )) return(True);
- if ( is_myname(dgram->source_name.name)) return(True);
-
- return(False);
-}
-
-
-/*******************************************************************
- process a domain announcement frame
-
- Announce frames come in 3 types. Servers send host announcements
- (command=1) to let the master browswer know they are
- available. Master browsers send local master announcements
- (command=15) to let other masters and backups that they are the
- master. They also send domain announcements (command=12) to register
- the domain
-
- The comment field of domain announcements contains the master
- browser name. The servertype is used by NetServerEnum to select
- resources. We just have to pass it to smbd (via browser.dat) and let
- the client choose using bit masks.
- ******************************************************************/
-static void process_localnet_announce(struct packet_struct *p,uint16 command,char *buf)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- struct subnet_record *d = find_subnet(p->ip); /* Explicitly exclude WINS - local nets only */
- int update_count = CVAL(buf,0);
-
- int ttl = IVAL(buf,1)/1000;
- char *name = buf+5;
- int osmajor=CVAL(buf,21);
- int osminor=CVAL(buf,22);
- uint32 servertype = IVAL(buf,23);
- uint32 browse_type= CVAL(buf,27);
- uint32 browse_sig = CVAL(buf,29);
- char *comment = buf+31;
-
- struct work_record *work;
- char *work_name;
- char *serv_name = dgram->source_name.name;
- BOOL add = False;
-
- comment[43] = 0;
-
- DEBUG(4,("Announce(%d) %s(%x)",command,name,name[15]));
- DEBUG(4,("%s count=%d ttl=%d OS=(%d,%d) type=%08x sig=%4x %4x comment=%s\n",
- namestr(&dgram->dest_name),update_count,ttl,osmajor,osminor,
- servertype,browse_type,browse_sig,comment));
-
- name[15] = 0;
-
- if (dgram->dest_name.name_type == 0 && command == ANN_HostAnnouncement)
- {
- DEBUG(2,("Announce to nametype(0) not supported yet\n"));
- return;
- }
-
- if (command == ANN_DomainAnnouncement &&
- ((!strequal(dgram->dest_name.name, MSBROWSE)) ||
- dgram->dest_name.name_type != 0x1))
- {
- DEBUG(0,("Announce(%d) from %s should be __MSBROWSE__(1) not %s\n",
- command, inet_ntoa(p->ip), namestr(&dgram->dest_name)));
- return;
- }
-
- if (!strequal(dgram->dest_name.scope,scope )) return;
-
- if (command == ANN_DomainAnnouncement) {
- /* XXXX if we are a master browser for the workgroup work_name,
- then there is a local subnet configuration problem. only
- we should be sending out such domain announcements, because
- as the master browser, that is our job.
-
- stop being a master browser, and force an election. this will
- sort out the network problem. hopefully.
- */
-
- work_name = name;
- add = True;
- } else {
- work_name = dgram->dest_name.name;
- }
-
- /* we need some way of finding out about new workgroups
- that appear to be sending packets to us. The name_type checks make
- sure we don't add host names as workgroups */
- if (command == ANN_HostAnnouncement &&
- (dgram->dest_name.name_type == 0x1d ||
- dgram->dest_name.name_type == 0x1e))
- add = True;
-
- DEBUG(4,("search for workgroup: %s (add? %s)\n",
- work_name, BOOLSTR(add)));
-
- if (!(work = find_workgroupstruct(d, work_name,add)))
- return;
-
- DEBUG(4, ("workgroup %s on %s\n", work->work_group, serv_name));
-
- ttl = GET_TTL(ttl);
-
- /* add them to our browse list, and update the browse.dat file */
- add_server_entry(d,work,name,servertype|SV_TYPE_LOCAL_LIST_ONLY,ttl,comment,True);
- updatedlists = True;
-
-#if 0
- /* the tell become backup code is broken, no great harm is done by
- disabling it */
- tell_become_backup();
-#endif
-}
-
-/*******************************************************************
- process a master announcement frame
- Domain master browsers recieve these from local masters. The Domain
- master should then issue a sync with the local master, asking for
- that machines local server list.
- ******************************************************************/
-static void process_master_announce(struct packet_struct *p,char *buf)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- char *name = buf;
- struct work_record *work;
- name[15] = 0;
-
- DEBUG(3,("process_master_announce: Master Announce from %s (%s)\n",name,inet_ntoa(p->ip)));
-
- if (same_context(dgram)) return;
-
- if (!wins_subnet)
- {
- DEBUG(3,("process_master_announce: No wins subnet !\n"));
- return;
- }
-
- if (!lp_domain_master())
- {
- DEBUG(3,("process_master_announce: Not configured as domain master - ignoring master announce.\n"));
- return;
- }
-
- for (work = wins_subnet->workgrouplist; work; work = work->next)
- {
- if (AM_MASTER(work) || AM_DOMMST(work))
- {
- /* merge browse lists with them */
- add_browser_entry(name,0x1d, work->work_group,30,wins_subnet,p->ip,True);
- }
- }
-}
-
-/*******************************************************************
- process a receive backup list request
-
- we receive a list of servers, and we attempt to locate them all on
- our local subnet, and sync browse lists with them on the workgroup
- they are said to be in.
-
- XXXX NOTE: this function is in overdrive. it should not really do
- half of what it actually does (it should pick _one_ name from the
- list received and sync with it at regular intervals, rather than
- sync with them all only once!)
-
- ******************************************************************/
-static void process_rcv_backup_list(struct packet_struct *p,char *buf)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- int count = CVAL(buf,0);
- uint32 info = IVAL(buf,1); /* XXXX caller's incremental info */
- char *buf1;
-
- DEBUG(3,("Receive Backup ack for %s from %s total=%d info=%d\n",
- namestr(&dgram->dest_name), inet_ntoa(p->ip),
- count, info));
-
- if (same_context(dgram)) return;
-
- if (count <= 0) return;
-
- /* go through the list of servers attempting to sync browse lists */
- for (buf1 = buf+5; *buf1 && count; buf1 = skip_string(buf1, 1), --count)
- {
- struct in_addr back_ip;
- /* struct subnet_record *d; */
-
- DEBUG(4,("Searching for backup browser %s at %s...\n",
- buf1, inet_ntoa(p->ip)));
-
- /* XXXX assume name is a DNS name NOT a netbios name. a more complete
- approach is to use reply_name_query functionality to find the name */
-
- back_ip = *interpret_addr2(buf1);
-
- if (zero_ip(back_ip))
- {
- DEBUG(4,("Failed to find backup browser server using DNS\n"));
- continue;
- }
-
- DEBUG(4,("Found browser server at %s\n", inet_ntoa(back_ip)));
- DEBUG(4,("END THIS LOOP: CODE NEEDS UPDATING\n"));
-
-#if 0
- /* XXXX function needs work */
- continue;
-
- if ((d = find_subnet(back_ip)))
- {
- struct subnet_record *d1;
- for (d1 = subnetlist; d1; d1 = d1->next)
- {
- struct work_record *work;
- for (work = d1->workgrouplist; work; work = work->next)
- {
- if (work->token == 0 /* token */)
- {
- queue_netbios_packet(d1,ClientNMB,NMB_QUERY,NAME_QUERY_SRV_CHK,
- work->work_group,0x1d,
- 0,0,0,NULL,NULL,
- False,False,back_ip,back_ip);
- return;
- }
- }
- }
- }
-#endif
- }
-}
-
-
-/****************************************************************************
- send a backup list response.
- **************************************************************************/
-static void send_backup_list(char *work_name, struct nmb_name *src_name,
- int token, uint32 info,
- int name_type, struct in_addr ip)
-{
- char outbuf[1024];
- char *p, *countptr, *nameptr;
- int count = 0;
- char *theirname = src_name->name;
-
- DEBUG(3,("sending backup list of %s to %s: %s(%x) %s(%x)\n",
- work_name, inet_ntoa(ip),
- myname,0x0,theirname,0x0));
-
- if (name_type == 0x1d)
- {
- DEBUG(4,("master browsers: "));
- }
- else if (name_type == 0x1b)
- {
- DEBUG(4,("domain controllers: "));
- }
- else
- {
- DEBUG(0,("backup request for unknown type %0x\n", name_type));
- return;
- }
-
- bzero(outbuf,sizeof(outbuf));
- p = outbuf;
-
- CVAL(p,0) = ANN_GetBackupListResp; /* backup list response */
-
- p++;
- countptr = p;
-
- SIVAL(p,1,info); /* the sender's unique info */
-
- p += 5;
-
- nameptr = p;
-
-#if 0
-
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d))
- {
- struct work_record *work;
-
- for (work = d->workgrouplist; work; work = work->next)
- {
- struct server_record *s;
-
- if (!strequal(work->work_group, work_name)) continue;
-
- for (s = work->serverlist; s; s = s->next)
- {
- BOOL found = False;
- char *n;
-
- if (s->serv.type & SV_TYPE_DOMAIN_ENUM) continue;
-
- for (n = nameptr; n < p; n = skip_string(n, 1))
- {
- if (strequal(n, s->serv.name)) found = True;
- }
-
- if (found) continue; /* exclude names already added */
-
- /* workgroup request: include all backup browsers in the list */
- /* domain request: include all domain members in the list */
-
- if ((name_type == 0x1d && (s->serv.type & MASTER_TYPE)) ||
- (name_type == 0x1b && (s->serv.type & DOMCTL_TYPE)))
- {
- DEBUG(4, ("%s ", s->serv.name));
-
- count++;
- strcpy(p,s->serv.name);
- strupper(p);
- p = skip_string(p,1);
- }
- }
- }
- }
-
-#endif
-
- count++;
- strcpy(p,myname);
- strupper(p);
- p = skip_string(p,1);
-
- if (count == 0)
- {
- DEBUG(4, ("none\n"));
- }
- else
- {
- DEBUG(4, (" - count %d\n", count));
- }
-
- CVAL(countptr, 0) = count;
-
- {
- int len = PTR_DIFF(p, outbuf);
- debug_browse_data(outbuf, len);
- }
- send_mailslot_reply(False,BROWSE_MAILSLOT,ClientDGRAM,
- outbuf,PTR_DIFF(p,outbuf),
- myname,theirname,0x0,0x0,ip,*iface_ip(ip));
-}
-
-
-/*******************************************************************
- process a send backup list request
-
- A client sends a backup list request to ask for a list of servers on
- the net that maintain server lists for a domain. A server is then
- chosen from this list to send NetServerEnum commands to to list
- available servers.
-
- Currently samba only sends back one name in the backup list, its
- own. For larger nets we'll have to add backups and send "become
- backup" requests occasionally.
- ******************************************************************/
-static void process_send_backup_list(struct packet_struct *p,char *buf)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- struct in_addr ip = dgram->header.source_ip;
- struct subnet_record *d;
- struct work_record *work;
-
- int token = CVAL(buf,0); /* sender's key index for the workgroup */
- uint32 info = IVAL(buf,1); /* XXXX don't know: some sort of info */
- int name_type = dgram->dest_name.name_type;
-
- if (same_context(dgram)) return;
-
- if (name_type != 0x1b && name_type != 0x1d) {
- DEBUG(0,("backup request to wrong type %d from %s\n",
- name_type,inet_ntoa(ip)));
- return;
- }
-
- for (d = subnetlist; d; d = d->next)
- {
- for (work = d->workgrouplist; work; work = work->next)
- {
- if (strequal(work->work_group, dgram->dest_name.name))
- {
- DEBUG(2,("sending backup list to %s %s id=%x\n",
- namestr(&dgram->dest_name),inet_ntoa(ip),info));
-
- send_backup_list(work->work_group,&dgram->source_name,
- token,info,name_type,ip);
- return;
- }
- }
- }
-}
-
-
-/*******************************************************************
- process a reset browser state
-
- diagnostic packet:
- 0x1 - stop being a master browser and become a backup browser.
- 0x2 - discard browse lists, stop being a master browser, try again.
- 0x4 - stop being a master browser forever. no way. ain't gonna.
-
- ******************************************************************/
-static void process_reset_browser(struct packet_struct *p,char *buf)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- int state = CVAL(buf,0);
-
- DEBUG(1,("received diagnostic browser reset request to %s state=0x%X\n",
- namestr(&dgram->dest_name), state));
-
- /* stop being a master but still deal with being a backup browser */
- if (state & 0x1)
- {
- struct subnet_record *d;
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
- {
- struct work_record *work;
- for (work = d->workgrouplist; work; work = work->next)
- {
- if (AM_MASTER(work))
- {
- unbecome_local_master(d,work,SV_TYPE_MASTER_BROWSER);
- }
- }
- }
- }
-
- /* XXXX documentation inconsistency: the above description does not
- exactly tally with what is implemented for state & 0x2
- */
-
- /* totally delete all servers and start afresh */
- if (state & 0x2)
- {
- struct subnet_record *d;
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_INCLUDING_WINS(d))
- {
- struct work_record *work;
- for (work=d->workgrouplist;work;work=remove_workgroup(d,work,True));
- }
- add_my_subnets(myworkgroup);
- }
-
- /* stop browsing altogether. i don't think this is a good idea! */
- if (state & 0x4)
- {
- DEBUG(1,("ignoring request to stop being a browser. sorry!\n"));
- }
-}
-
-/*******************************************************************
- process a announcement request
-
- clients send these when they want everyone to send an announcement
- immediately. This can cause quite a storm of packets!
- ******************************************************************/
-static void process_announce_request(struct packet_struct *p,char *buf)
-{
- struct dgram_packet *dgram = &p->packet.dgram;
- struct work_record *work;
- struct in_addr ip = dgram->header.source_ip;
- struct subnet_record *d = find_subnet(ip); /* Explicitly NO WINS */
- int token = CVAL(buf,0);
- char *name = buf+1;
-
- name[15] = 0;
-
- DEBUG(3,("process_announce_request: Announce request from %s to %s token=0x%X\n",
- name,namestr(&dgram->dest_name), token));
-
- if (is_myname(dgram->source_name.name)) return;
-
- /* XXXX BUG or FEATURE?: need to ensure that we are a member of
- this workgroup before announcing, particularly as we only
- respond on local interfaces anyway.
-
- if (strequal(dgram->dest_name, myworkgroup) return; ???
- */
-
- if (!d)
- {
- DEBUG(3,("process_announce_request: No local interface to announce to %s\n",
- name));
- return;
- }
-
- for (work = d->workgrouplist; work; work = work->next)
- {
- /* XXXX BUG: the destination name type should also be checked,
- not just the name. e.g if the name is WORKGROUP(0x1d) then
- we should only respond if we own that name */
-
- if (strequal(dgram->dest_name.name,work->work_group))
- {
- work->needannounce = True;
- }
- }
-}
-
-
-
-/****************************************************************************
-process a browse frame
-****************************************************************************/
-void process_browse_packet(struct packet_struct *p,char *buf,int len)
-{
- int command = CVAL(buf,0);
- switch (command)
- {
- case ANN_HostAnnouncement:
- case ANN_DomainAnnouncement:
- case ANN_LocalMasterAnnouncement:
- {
- debug_browse_data(buf, len);
- process_localnet_announce(p,command,buf+1);
- break;
- }
-
- case ANN_AnnouncementRequest:
- {
- process_announce_request(p,buf+1);
- break;
- }
-
- case ANN_Election:
- {
- process_election(p,buf+1);
- break;
- }
-
- case ANN_GetBackupListReq:
- {
- debug_browse_data(buf, len);
- process_send_backup_list(p,buf+1);
- break;
- }
-
- case ANN_GetBackupListResp:
- {
- debug_browse_data(buf, len);
- process_rcv_backup_list(p, buf+1);
- break;
- }
-
- case ANN_ResetBrowserState:
- {
- process_reset_browser(p, buf+1);
- break;
- }
-
- case ANN_MasterAnnouncement:
- {
- process_master_announce(p,buf+1);
- break;
- }
-
- default:
- {
- struct dgram_packet *dgram = &p->packet.dgram;
- DEBUG(4,("ignoring browse packet %d from %s %s to %s\n",
- command, namestr(&dgram->source_name),
- inet_ntoa(p->ip), namestr(&dgram->dest_name)));
- }
- }
-}
-
-
diff --git a/source/namework.doc b/source/namework.doc
deleted file mode 100644
index 958a86c8668..00000000000
--- a/source/namework.doc
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- Unix SMB/Netbios documentation.
- Version 0.1
- Copyright (C) Luke Leighton Andrew Tridgell 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.
-
- Document name: namework.doc
-
- Revision History:
-
- 0.0 - 02jul96 : lkcl@pires.co.uk
- created
-
- 0.1 - 22jul96 Andrew.Tridgell@anu.edu.au
- tridge's comments on first revision
-*/
-
-the module namework.c deals with NetBIOS datagram packets, primarily.
-it deals with nmbd's workgroup browser side and the domain log in
-side. none of the functionality here has specification documents available.
-empirical observation of packet traces has been the order of the day,
-along with some guess-work.
-
-beware!
-
-the receipt of datagram packets for workgroup browsing are dealt with here.
-some of the functions listed here will call others outside of this
-module, or will activate functionality dealt with by other modules
-(namedb, nameannounce, nameelect, namelogon, and namebrowse).
-
-
-/*************************************************************************
- process_browse_packet()
- *************************************************************************/
-
-this function is responsible for further identifying which type of
-browser datagram packet has been received, and dealing with it
-accordingly. if the packet is not dealt with, then an error is
-logged along with the type of packet that has been received.
-
-if listening_type() was in use, then it would be used here.
-
-the types of packets received and dealt with are:
-
-- ANN_HostAnnouncement
-- ANN_DomainAnnouncement
-- ANN_LocalMasterAnnouncement
-
-these are all identical in format and can all be processed by
-process_announce(). an announcement is received from a host
-(either a master browser telling us about itself, a server
-telling us about itself or a master browser telling us about
-a domain / workgroup)
-
-- ANN_AnnouncementRequest
-
-these are sent by master browsers or by servers. it is a
-request to announce ourselves as appropriate by sending
-either a ANN_HostAnnouncement datagram or both an
-ANN_DomainAnnouncement and an ANN_LocalMasterAnnouncement
-if we are a master browser (but not both).
-
-- ANN_Election
-
-this is an election datagram. if samba has been configured
-as a domain master then it will also send out election
-datagrams.
-
-- ANN_GetBackupListReq
-
-this is a request from another server for us to send a
-backup list of all servers that we know about. we respond
-by sending a datagram ANN_GetBackupListResp. the protocol
-here is a little dicey.
-
-- ANN_GetBackupListResp
-
-this is a response from another server that we have sent an
-ANN_GetBackupListReq to. the protocol is a little dicey.
-
-- ANN_BecomeBackup
-
-this is a message sent by a master browser to a
-potential master browser, indicating that it should become
-a backup master browser for the workgroup it is a member
-of. samba does not respond at present to such datagrams,
-and it also sends out such datagrams for the wrong reasons
-(this code has now been disabled until this is fixed).
-
-- ANN_ResetBrowserState
-
-this datagram is sent for trouble-shooting purposes.
-it asks a browser to clear out its server lists, or to
-stop becoming a master browser altogether. NT/AS and
-samba do not implement this latter option.
-
-- ANN_MasterAnnouncement
-
-this datagram is sent by a master browser to a domain master
-browser. it is a way to ensure that master browsers are kept in sync
-with a domain master browser across a wide area network. on
-receipt of an ANN_MasterAnnouncement we should sync browse lists with
-the sender.
-
-(i never got the hang of this one when i was experimenting.
-i forget exactly what it's for, and i never fully worked
-out how to coax a server to send it. :-)
-
-NOTE FROM TRIDGE: The reason you didn't work out how to coax a server
-into sending it is that you can't (or shouldn't try!). Basically these
-"master announce" datagrams are the way that separate netbios subnets
-are linked together to form a complete browse net. The way it works is
-that the local master decides it is going to inform the domain master
-of its presence, then sends this master announce to the domain
-master. The domain master then syncs with the local master using a
-"local only" sync. The whole transaction is initiated by the local
-master, not the domain master, so the domain master should not do any
-of this if it does not first receive a "master announcement". The
-local domain masters need to be configured to know the IP address of
-the domain master.
-
-
-/*************************************************************************
- listening_type()
- *************************************************************************/
-
-
-a datagram packet is sent from one NetBIOS name of a specific type
-to another NetBIOS name of a specific type. certain types of
-datagrams are only expected from certain types of NetBIOS names.
-
-this function is intended to catch errors in the type of datagrams
-received from different NetBIOS names. it is currently incomplete
-due to lack of information on the types of names and the datagrams
-they send.
-
-
-/*************************************************************************
- process_announce_request()
- *************************************************************************/
-
-this function is responsible for dealing with announcement requests.
-if the type of name that the request is sent to matches our current
-status, then we should respond. otherwise, the datagram should be
-ignored.
-
-samba only responds on its local subnets.
-
-at present, just the name is checked to see if the packet is for us.
-what should be done is that if we own the name (e.g WORGROUP(0x1d)
-or WORKGROUP(0x1b) then we should respond, otherwise, ignore the
-datagram.
-
-if the name is for us, and we are a member of that workgroup, then
-samba should respond.
-
-note that samba does not respond immediately. this is to ensure that
-if the master browser for the workgroup that samba is a member of
-sends out a broadcast request announcement, that that master browser
-is not swamped with replies. it is therefore up to samba to reply
-at some random interval. hence, a flag is set indicating the need
-to announce later.
-
-
-/*************************************************************************
- process_reset_browser()
- *************************************************************************/
-
-this function is responsible for dealing with reset state datagrams.
-there are three kinds of diagnostic reset requests:
-
-- stop being a master browser
-- discard browse lists, stop being a master browser, and run for re-election
-- stop being a master browser forever.
-
-samba and windows nt do not implement the latter option.
-
-there appears to be a discrepancy between this description and the
-code actually implemented.
-
-
-/*************************************************************************
- process_send_backup_list()
- *************************************************************************/
-
-this function is part of samba's domain master browser functionality.
-
-it is responsible for giving master browsers a list of other browsers
-that maintain backup lists of servers for that master browser's workgroup.
-
-it is also responsible for giving master browsers a list of domain master
-browsers for that local master browser's domain.
-
-a correct way to think of this function is that it is a 'request to
-send out a backup list for the requested workgroup or domain'.
-
-i have some suspicions and intuitions about this function and how it
-is to actually be used. there is no documentation on this, so it is a
-matter of experimenting until it's right.
-
-
-/*************************************************************************
- send_backup_list()
- *************************************************************************/
-
-this function is responsible for compiling a list of either master
-browsers and backup master browsers or domain master browsers and
-backup domain master browsers. samba constructs this list from its
-workgroup / server database.
-
-the list is then sent to the host that requested it by sending an
-ANN_GetBackupListResp datagram to this host.
-
-
-NOTE FROM TRIDGE: The "backup list" stuff is only relevant to
-local subnets. It has nothing to do with PDCs or domain masters. Its
-function is twofold:
-
-1) spread the browsing load over multiple servers so one server
-doesn't get overloaded with browse requests
-2) make sure the database doesn't get lost completely if the master
-goes down
-
-To accomplish this a few things are supposed to be done:
-
-- the master browser maintains a list of "backup browsers".
-
-- backup browsers are are machines that are just like ordinary servers
-but also maintain a browse list and respond to "NetServerEnum"
-requests
-
-- when a server initially announces itself to the master it may set
-its "maintain browse list" flag to auto.
-
-- when a master browser sees a server announcement with "auto" set it
-may send a "become backup" to that server telling it to become a
-backup.
-
-- the master has a simple algorithm to determine how many backups it wants
-given the number of hosts on the net
-
-- when a client wishes to get a browse list it asks the master for a
-backup list. The master sends it the current list of backup browsers,
-including itself. The client caches this list. The client then sends
-the NetServerEnum to a random member of this list easch time it wants
-to browse. This spreads the load.
-
-
-
-/*************************************************************************
- process_rcv_backup_list()
- *************************************************************************/
-
-this function is implemented with a slightly over-kill algorithm.
-the correct functionality is to pick any three names at random from
-the list that is received from this datagram, and then at intervals
-contact _one_ of them for a list of browser, in order to update
-samba's browse list.
-
-samba contacts every single one of the backup browsers listed, through
-the use of a NAME_QUERY_SRV_CHK 'state'.
-
-
-/*************************************************************************
- process_master_announce()
- *************************************************************************/
-
-this function is responsible for synchronising browse lists with a
-master browser that contacts samba in its capacity as a domain master
-browser.
-
-the function add_browser_entry() is used to add the server that
-contacts us to our list of browser to sync browse lists with at
-some point in the near future.
-
-
-/*************************************************************************
- process_announce()
- *************************************************************************/
-
-this function is responsible for dealing with the three types of
-announcement type datagrams that samba recognises. some appropriate
-type-checking is done on the name that the datagram is sent to.
-
-samba does not at present deal with LanManager announcements.
-
-these announcements are for updating the browse entry records.
-each browse entry has a time-to-live associated with it. each server
-must refresh its entry with all other servers by broadcasting
-Announcements. if it does not do so, then other servers will not
-know about that machine, and the records on each server of that
-other machine will die.
-
-if an ANN_DomainAnnouncement is received, then this will be from
-a master browser. only one machine on any given broadcast area (e.g
-a subnet) should be broadcasting such announcements. the information
-it contains tells other servers that there is a master browser for
-this workgroup. if another server thinks that it is also a master
-browser for the same workgroup, then it should stop being a master
-browser and force an election.
-
-if an ANN_LocalMasterAnnouncement is received, then a master browser
-is telling us that it exists. i am uncertain that anything else
-actually needs to be done with this, other than to shout 'hooray' and
-'thank you for informing me of this fact'.
-
-
-/*************************************************************************
- listening_name()
- *************************************************************************/
-
-this function is an over-simplified way of identifying whether we
-should be responding to a datagram that has been received.
-
-
-/*************************************************************************
- same_context()
- *************************************************************************/
-
-this function helps us to identify whether we should be responding to
-a datagram that has been received.
-
-
-/*************************************************************************
- tell_become_backup()
- *************************************************************************/
-
-this function is part of samba's domain master browser capabilities.
-it is responsible for finding appropriate servers to tell to become a
-backup master browser for the domain that samba controls.
-
-other servers that contact samba asking for a list of backup browsers
-will then be given that server's name, and that server can expect to
-receive NetServerEnum requests for lists of servers and workgroups.
-
-this function must be updated before it is in a fit state to be used.
-it must properly check whether a server is prepared to become a backup
-browser before actually asking it to be one.
-
-
-/*************************************************************************
- reset_server()
- *************************************************************************/
-
-this function is responsible for issuing an ANN_ResetBrowserState to
-the specified server, asking it to reset its browser information.
-
-see process_reset_browser() for details on this function.
-
-
diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c
deleted file mode 100644
index 3f0279908da..00000000000
--- a/source/nmbd/nmbd.c
+++ /dev/null
@@ -1,647 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-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.
-
- Revision History:
-
- 14 jan 96: lkcl@pires.co.uk
- added multiple workgroup domain master support
-
-*/
-
-#include "includes.h"
-
-extern int DEBUGLEVEL;
-
-extern pstring debugf;
-pstring servicesf = CONFIGFILE;
-
-extern pstring scope;
-
-int ClientNMB = -1;
-int ClientDGRAM = -1;
-
-extern pstring myhostname;
-static pstring host_file;
-extern pstring myname;
-extern fstring myworkgroup;
-extern char **my_netbios_names;
-
-/* are we running as a daemon ? */
-static BOOL is_daemon = False;
-
-/* what server type are we currently */
-
-time_t StartupTime =0;
-
-extern struct in_addr ipzero;
-
- /****************************************************************************
- catch a sigterm
- ****************************************************************************/
-static int sig_term()
-{
- BlockSignals(True,SIGTERM);
-
- DEBUG(0,("Got SIGTERM: going down...\n"));
-
- /* write out wins.dat file if samba is a WINS server */
- dump_names();
-
- /* remove all samba names, with wins server if necessary. */
- remove_my_names();
-
- /* announce all server entries as 0 time-to-live, 0 type */
- /* XXXX don't care if we never receive a response back... yet */
- announce_my_servers_removed();
-
- /* XXXX other things: if we are a master browser, force an election? */
-
- exit(0);
- /* Keep compiler happy.. */
- return 0;
-}
-
-
-/****************************************************************************
-catch a sighup
-****************************************************************************/
-static int sig_hup(void)
-{
- BlockSignals(True,SIGHUP);
-
- DEBUG(0,("Got SIGHUP (reload not implemented)\n"));
- dump_names();
- reload_services(True);
-
- set_samba_nb_type();
-
- BlockSignals(False,SIGHUP);
-#ifndef DONT_REINSTALL_SIG
- signal(SIGHUP,SIGNAL_CAST sig_hup);
-#endif
- return(0);
-}
-
-/****************************************************************************
-catch a sigpipe
-****************************************************************************/
-static int sig_pipe(void)
-{
- BlockSignals(True,SIGPIPE);
-
- DEBUG(0,("Got SIGPIPE\n"));
- if (!is_daemon)
- exit(1);
- BlockSignals(False,SIGPIPE);
- return(0);
-}
-
-#if DUMP_CORE
-/*******************************************************************
-prepare to dump a core file - carefully!
-********************************************************************/
-static BOOL dump_core(void)
-{
- char *p;
- pstring dname;
- pstrcpy(dname,debugf);
- if ((p=strrchr(dname,'/'))) *p=0;
- strcat(dname,"/corefiles");
- mkdir(dname,0700);
- sys_chown(dname,getuid(),getgid());
- chmod(dname,0700);
- if (chdir(dname)) return(False);
- umask(~(0700));
-
-#ifndef NO_GETRLIMIT
-#ifdef RLIMIT_CORE
- {
- struct rlimit rlp;
- getrlimit(RLIMIT_CORE, &rlp);
- rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
- setrlimit(RLIMIT_CORE, &rlp);
- getrlimit(RLIMIT_CORE, &rlp);
- DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
- }
-#endif
-#endif
-
-
- DEBUG(0,("Dumping core in %s\n",dname));
- return(True);
-}
-#endif
-
-
-/****************************************************************************
-possibly continue after a fault
-****************************************************************************/
-static void fault_continue(void)
-{
-#if DUMP_CORE
- dump_core();
-#endif
-}
-
-/*******************************************************************
- expire old names from the namelist and server list
- ******************************************************************/
-static void expire_names_and_servers(time_t t)
-{
- static time_t lastrun = 0;
-
- if (!lastrun) lastrun = t;
- if (t < lastrun + 5) return;
- lastrun = t;
-
- expire_names(t);
- expire_servers(t);
-}
-
-/*****************************************************************************
- reload the services file
- **************************************************************************/
-BOOL reload_services(BOOL test)
-{
- BOOL ret;
- extern fstring remote_machine;
-
- strcpy(remote_machine,"nmbd");
-
- if (lp_loaded())
- {
- pstring fname;
- pstrcpy(fname,lp_configfile());
- if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
- {
- pstrcpy(servicesf,fname);
- test = False;
- }
- }
-
- if (test && !lp_file_list_changed())
- return(True);
-
- ret = lp_load(servicesf,True);
-
- /* perhaps the config filename is now set */
- if (!test) {
- DEBUG(3,("services not loaded\n"));
- reload_services(True);
- }
-
- /* Do a sanity check for a misconfigured nmbd */
- if(lp_wins_support() && *lp_wins_server()) {
- DEBUG(0,("ERROR: both 'wins support = true' and 'wins server = <server>' \
-cannot be set in the smb.conf file. nmbd aborting.\n"));
- exit(10);
- }
-
- return(ret);
-}
-
-
-
-/****************************************************************************
-load a netbios hosts file
-****************************************************************************/
-static void load_hosts_file(char *fname)
-{
- FILE *f = fopen(fname,"r");
- pstring line;
- if (!f) {
- DEBUG(2,("Can't open lmhosts file %s\n",fname));
- return;
- }
-
- while (!feof(f))
- {
- pstring ip,name,flags,extra;
- struct subnet_record *d;
- char *ptr;
- int count = 0;
- struct in_addr ipaddr;
- enum name_source source = LMHOSTS;
-
- if (!fgets_slash(line,sizeof(pstring),f)) continue;
-
- if (*line == '#') continue;
-
- strcpy(ip,"");
- strcpy(name,"");
- strcpy(flags,"");
-
- ptr = line;
-
- if (next_token(&ptr,ip ,NULL)) ++count;
- if (next_token(&ptr,name ,NULL)) ++count;
- if (next_token(&ptr,flags,NULL)) ++count;
- if (next_token(&ptr,extra,NULL)) ++count;
-
- if (count <= 0) continue;
-
- if (count > 0 && count < 2) {
- DEBUG(0,("Ill formed hosts line [%s]\n",line));
- continue;
- }
-
- if (count >= 4) {
- DEBUG(0,("too many columns in %s (obsolete syntax)\n",fname));
- continue;
- }
-
- DEBUG(4, ("lmhost entry: %s %s %s\n", ip, name, flags));
-
- if (strchr(flags,'G') || strchr(flags,'S')) {
- DEBUG(0,("group flag in %s ignored (obsolete)\n",fname));
- continue;
- }
-
- if (strchr(flags,'M')) {
- source = SELF;
- pstrcpy(myname,name);
- }
-
- ipaddr = *interpret_addr2(ip);
- d = find_subnet_all(ipaddr);
- if (d) {
- add_netbios_entry(d,name,0x00,NB_ACTIVE,0,source,ipaddr,True,True);
- add_netbios_entry(d,name,0x20,NB_ACTIVE,0,source,ipaddr,True,True);
- }
- }
-
- fclose(f);
-}
-
-
-/****************************************************************************
- The main select loop.
- ***************************************************************************/
-static void process(void)
-{
- BOOL run_election;
-
- while (True)
- {
- time_t t = time(NULL);
- run_election = check_elections();
- listen_for_packets(run_election);
-
- run_packet_queue();
- run_elections(t);
-
- announce_host(t);
- announce_master(t);
- announce_remote(t);
-
- query_refresh_names(t);
-
- expire_names_and_servers(t);
- expire_netbios_response_entries(t);
- refresh_my_names(t);
-
- write_browse_list(t);
- do_browser_lists(t);
- check_master_browser(t);
- add_domain_names(t);
- }
-}
-
-
-/****************************************************************************
- open the socket communication
-****************************************************************************/
-static BOOL open_sockets(BOOL isdaemon, int port)
-{
- struct hostent *hp;
-
- /* get host info */
- if ((hp = Get_Hostbyname(myhostname)) == 0) {
- DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",myhostname));
- return False;
- }
-
- if (isdaemon)
- ClientNMB = open_socket_in(SOCK_DGRAM, port,0,interpret_addr(lp_socket_address()));
- else
- ClientNMB = 0;
-
- ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3,interpret_addr(lp_socket_address()));
-
- if (ClientNMB == -1)
- return(False);
-
- signal(SIGPIPE, SIGNAL_CAST sig_pipe);
-
- set_socket_options(ClientNMB,"SO_BROADCAST");
- set_socket_options(ClientDGRAM,"SO_BROADCAST");
-
- DEBUG(3,("Sockets opened.\n"));
- return True;
-}
-
-
-/****************************************************************************
- initialise connect, service and file structs
-****************************************************************************/
-static BOOL init_structs()
-{
- extern fstring local_machine;
- char *p, *ptr;
- int namecount;
- int n;
- int nodup;
- pstring nbname;
-
- if (! *myname) {
- fstrcpy(myname,myhostname);
- p = strchr(myname,'.');
- if (p) *p = 0;
- }
- strupper(myname);
-
- /* Add any NETBIOS name aliases. Ensure that the first entry
- is equal to myname. */
- /* Work out the max number of netbios aliases that we have */
- ptr=lp_netbios_aliases();
- for (namecount=0; next_token(&ptr,nbname,NULL); namecount++)
- ;
- if (*myname)
- namecount++;
-
- /* Allocate space for the netbios aliases */
- if((my_netbios_names=(char **)malloc(sizeof(char *)*(namecount+1))) == NULL)
- {
- DEBUG(0,("init_structs: malloc fail.\n"));
- return False;
- }
-
- /* Use the myname string first */
- namecount=0;
- if (*myname)
- my_netbios_names[namecount++] = myname;
-
- ptr=lp_netbios_aliases();
- while (next_token(&ptr,nbname,NULL)) {
- strupper(nbname);
- /* Look for duplicates */
- nodup=1;
- for(n=0; n<namecount; n++) {
- if (strcmp(nbname, my_netbios_names[n])==0)
- nodup=0;
- }
- if (nodup)
- my_netbios_names[namecount++]=strdup(nbname);
- }
-
- /* Check the strdups succeeded. */
- for(n = 0; n < namecount; n++)
- if(my_netbios_names[n]==NULL)
- {
- DEBUG(0,("init_structs: malloc fail when allocating names.\n"));
- return False;
- }
-
- /* Terminate name list */
- my_netbios_names[namecount++]=NULL;
-
- fstrcpy(local_machine,myname);
- trim_string(local_machine," "," ");
- p = strchr(local_machine,' ');
- if (p)
- *p = 0;
- strlower(local_machine);
-
- DEBUG(5, ("Netbios name list:-\n"));
- for (n=0; my_netbios_names[n]; n++)
- DEBUG(5, ("my_netbios_names[%d]=\"%s\"\n", n, my_netbios_names[n]));
-
- return True;
-}
-
-/****************************************************************************
-usage on the program
-****************************************************************************/
-static void usage(char *pname)
-{
- DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
-
- printf("Usage: %s [-n name] [-D] [-p port] [-d debuglevel] [-l log basename]\n",pname);
- printf("Version %s\n",VERSION);
- printf("\t-D become a daemon\n");
- printf("\t-p port listen on the specified port\n");
- printf("\t-d debuglevel set the debuglevel\n");
- printf("\t-l log basename. Basename for log/debug files\n");
- printf("\t-n netbiosname. the netbios name to advertise for this host\n");
- printf("\t-H hosts file load a netbios hosts file\n");
- printf("\n");
-}
-
-
-/****************************************************************************
- main program
- **************************************************************************/
- int main(int argc,char *argv[])
-{
- int port = NMB_PORT;
- int opt;
- extern FILE *dbf;
- extern char *optarg;
- char pidFile[100] = { 0 };
-
- *host_file = 0;
-
- StartupTime = time(NULL);
-
- TimeInit();
-
- strcpy(debugf,NMBLOGFILE);
-
- setup_logging(argv[0],False);
-
- charset_initialise();
-
-#ifdef LMHOSTSFILE
- strcpy(host_file,LMHOSTSFILE);
-#endif
-
- /* this is for people who can't start the program correctly */
- while (argc > 1 && (*argv[1] != '-')) {
- argv++;
- argc--;
- }
-
- fault_setup(fault_continue);
-
- signal(SIGHUP ,SIGNAL_CAST sig_hup);
- signal(SIGTERM,SIGNAL_CAST sig_term);
-
- while ((opt = getopt(argc, argv, "s:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:f:")) != EOF)
- {
- switch (opt)
- {
- case 'f':
- strncpy(pidFile, optarg, sizeof(pidFile));
- break;
- case 's':
- pstrcpy(servicesf,optarg);
- break;
- case 'N':
- case 'B':
- case 'I':
- case 'C':
- case 'G':
- DEBUG(0,("Obsolete option '%c' used\n",opt));
- break;
- case 'H':
- pstrcpy(host_file,optarg);
- break;
- case 'n':
- pstrcpy(myname,optarg);
- strupper(myname);
- break;
- case 'l':
- sprintf(debugf,"%s.nmb",optarg);
- break;
- case 'i':
- pstrcpy(scope,optarg);
- strupper(scope);
- break;
- case 'D':
- is_daemon = True;
- break;
- case 'd':
- DEBUGLEVEL = atoi(optarg);
- break;
- case 'p':
- port = atoi(optarg);
- break;
- case 'h':
- usage(argv[0]);
- exit(0);
- break;
- default:
- if (!is_a_socket(0)) {
- usage(argv[0]);
- }
- break;
- }
- }
-
- DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
- DEBUG(1,("Copyright Andrew Tridgell 1994-1997\n"));
-
- if(!get_myname(myhostname,NULL))
- {
- DEBUG(0,("Unable to get my hostname - exiting.\n"));
- return -1;
- }
-
- if (!reload_services(False))
- return(-1);
-
- codepage_initialise(lp_client_code_page());
-
- if(!init_structs())
- return -1;
-
- reload_services(True);
-
- pstrcpy(myworkgroup, lp_workgroup());
-
- if (strequal(myworkgroup,"*")) {
- DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
- exit(1);
- }
-
- set_samba_nb_type();
-
- if (!is_daemon && !is_a_socket(0)) {
- DEBUG(0,("standard input is not a socket, assuming -D option\n"));
- is_daemon = True;
- }
-
- if (is_daemon) {
- DEBUG(2,("%s becoming a daemon\n",timestring()));
- become_daemon();
- }
-
- if (*pidFile)
- {
- int fd;
- char buf[20];
-
- if ((fd = open(pidFile,
-#ifdef O_NONBLOCK
- O_NONBLOCK |
-#endif
- O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
- {
- DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
- exit(1);
- }
- if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
- {
- DEBUG(0,("ERROR: nmbd is already running\n"));
- exit(1);
- }
- sprintf(buf, "%u\n", (unsigned int) getpid());
- if (write(fd, buf, strlen(buf)) < 0)
- {
- DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
- exit(1);
- }
- /* Leave pid file open & locked for the duration... */
- }
-
-
- DEBUG(3,("Opening sockets %d\n", port));
-
- if (!open_sockets(is_daemon,port)) return 1;
-
- load_interfaces();
- add_my_subnets(myworkgroup);
-
- add_my_names();
-
- DEBUG(3,("Checked names\n"));
-
- load_netbios_names();
-
- DEBUG(3,("Loaded names\n"));
-
- if (*host_file) {
- load_hosts_file(host_file);
- DEBUG(3,("Loaded hosts file\n"));
- }
-
- write_browse_list(time(NULL));
-
- DEBUG(3,("Dumped names\n"));
-
- /* We can only take sigterm signals in the select. */
- BlockSignals(True,SIGTERM);
- process();
- close_sockets();
-
- if (dbf)
- fclose(dbf);
- return(0);
-}
diff --git a/source/nmbsync.c b/source/nmbsync.c
deleted file mode 100644
index de2f7aa00f1..00000000000
--- a/source/nmbsync.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines to synchronise browse lists
- Copyright (C) Andrew Tridgell 1994-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.
-
-*/
-
-/* We *must have REPLACE_GETPASS defined here before the includes. */
-#define REPLACE_GETPASS
-#include "includes.h"
-
-extern int ClientNMB;
-extern int ClientDGRAM;
-
-extern int DEBUGLEVEL;
-
-extern pstring myname;
-
-extern int name_type;
-extern int max_protocol;
-extern struct in_addr dest_ip;
-extern int pid;
-extern int gid;
-extern int uid;
-extern int mid;
-extern BOOL got_pass;
-extern BOOL have_ip;
-extern pstring workgroup;
-extern pstring service;
-extern pstring desthost;
-extern BOOL connect_as_ipc;
-
-/****************************************************************************
-fudge for getpass function
-****************************************************************************/
-char *getsmbpass(char *pass)
-{
- return "dummy"; /* return anything: it should be ignored anyway */
-}
-
-/****************************************************************************
-adds information retrieved from a NetServerEnum call
-****************************************************************************/
-static BOOL add_info(struct subnet_record *d, struct work_record *work, int servertype)
-{
- char *rparam = NULL;
- char *rdata = NULL;
- int rdrcnt,rprcnt;
- char *p;
- pstring param;
- int uLevel = 1;
- int count = -1;
-
- /* now send a SMBtrans command with api ServerEnum? */
- p = param;
- SSVAL(p,0,0x68); /* api number */
- p += 2;
- strcpy(p,"WrLehDz");
- p = skip_string(p,1);
-
- strcpy(p,"B16BBDz");
-
- p = skip_string(p,1);
- SSVAL(p,0,uLevel);
- SSVAL(p,2,BUFFER_SIZE - SAFETY_MARGIN); /* buf length */
- p += 4;
- SIVAL(p,0,servertype);
- p += 4;
-
- pstrcpy(p, work->work_group);
- p = skip_string(p,1);
-
- if (cli_call_api(PTR_DIFF(p,param),0, 8,BUFFER_SIZE - SAFETY_MARGIN,
- &rprcnt,&rdrcnt, param,NULL,
- &rparam,&rdata))
- {
- int res = SVAL(rparam,0);
- int converter=SVAL(rparam,2);
- int i;
-
- if (res == 0)
- {
- count=SVAL(rparam,4);
- p = rdata;
-
- for (i = 0;i < count;i++, p += 26)
- {
- char *sname = p;
- uint32 stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY;
- int comment_offset = IVAL(p,22) & 0xFFFF;
- char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
-
- struct work_record *w = work;
-
- DEBUG(4, ("\t%-16.16s %08x %s\n", sname, stype, cmnt));
-
- if (stype & SV_TYPE_DOMAIN_ENUM)
- {
- /* creates workgroup on remote subnet */
- if ((w = find_workgroupstruct(d,sname,True)))
- {
- announce_request(w, d->bcast_ip);
- }
- }
-
- if (w)
- add_server_entry(d,w,sname,stype,lp_max_ttl(),cmnt,False);
- }
- }
- }
-
- if (rparam) free(rparam);
- if (rdata) free(rdata);
-
- return(True);
-}
-
-
-/*******************************************************************
- synchronise browse lists with another browse server.
-
- log in on the remote server's SMB port to their IPC$ service,
- do a NetServerEnum and update our server and workgroup databases.
- ******************************************************************/
-void sync_browse_lists(struct subnet_record *d, struct work_record *work,
- char *name, int nm_type, struct in_addr ip, BOOL local)
-{
- uint32 local_type = local ? SV_TYPE_LOCAL_LIST_ONLY : 0;
-
- if (!d || !work ) return;
-
- if(d != wins_subnet) {
- DEBUG(0,
- ("sync_browse_lists: ERROR sync requested on non-WINS subnet.\n"));
- return;
- }
-
- pid = getpid();
- uid = getuid();
- gid = getgid();
- mid = pid + 100;
- name_type = nm_type;
-
- got_pass = True;
-
- DEBUG(0,("sync_browse_lists: Sync browse lists with %s for %s %s\n",
- name, work->work_group, inet_ntoa(ip)));
-
- strcpy(workgroup,work->work_group);
- fstrcpy(desthost,name);
- dest_ip = ip;
-
- if (zero_ip(dest_ip)) return;
- have_ip = True;
-
- connect_as_ipc = True;
-
- /* connect as server and get domains, then servers */
-
- sprintf(service,"\\\\%s\\IPC$", name);
- strupper(service);
-
- if (cli_open_sockets(SMB_PORT))
- {
- if (cli_send_login(NULL,NULL,True,True))
- {
- add_info(d, work, local_type|SV_TYPE_DOMAIN_ENUM);
- if(local)
- add_info(d, work, SV_TYPE_LOCAL_LIST_ONLY);
- else
- add_info(d, work, SV_TYPE_ALL);
- }
-
- close_sockets();
- }
-}
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
deleted file mode 100644
index edc2d2b65f6..00000000000
--- a/source/param/loadparm.c
+++ /dev/null
@@ -1,2361 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Parameter loading functions
- Copyright (C) Karl Auer 1993,1997
-
- Largely re-written by Andrew Tridgell, September 1994
-
- 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.
-*/
-
-/*
- * Load parameters.
- *
- * This module provides suitable callback functions for the params
- * module. It builds the internal table of service details which is
- * then used by the rest of the server.
- *
- * To add a parameter:
- *
- * 1) add it to the global or service structure definition
- * 2) add it to the parm_table
- * 3) add it to the list of available functions (eg: using FN_GLOBAL_STRING())
- * 4) If it's a global then initialise it in init_globals. If a local
- * (ie. service) parameter then initialise it in the sDefault structure
- *
- *
- * Notes:
- * The configuration file is processed sequentially for speed. It is NOT
- * accessed randomly as happens in 'real' Windows. For this reason, there
- * is a fair bit of sequence-dependent code here - ie., code which assumes
- * that certain things happen before others. In particular, the code which
- * happens at the boundary between sections is delicately poised, so be
- * careful!
- *
- */
-
-#include "includes.h"
-
-/* Set default coding system for KANJI if none specified in Makefile. */
-#ifndef KANJI
-#define KANJI "sjis"
-#endif /* KANJI */
-
-BOOL bLoaded = False;
-
-extern int DEBUGLEVEL;
-extern pstring user_socket_options;
-extern pstring myname;
-
-#ifndef GLOBAL_NAME
-#define GLOBAL_NAME "global"
-#endif
-
-#ifndef PRINTCAP_NAME
-#ifdef AIX
-#define PRINTCAP_NAME "/etc/qconfig"
-#else
-#define PRINTCAP_NAME "/etc/printcap"
-#endif
-#endif
-
-#ifndef PRINTERS_NAME
-#define PRINTERS_NAME "printers"
-#endif
-
-#ifndef HOMES_NAME
-#define HOMES_NAME "homes"
-#endif
-
-/* some helpful bits */
-#define pSERVICE(i) ServicePtrs[i]
-#define iSERVICE(i) (*pSERVICE(i))
-#define LP_SNUM_OK(iService) (((iService) >= 0) && ((iService) < iNumServices) && iSERVICE(iService).valid)
-#define VALID(i) iSERVICE(i).valid
-
-/* these are the types of parameter we have */
-typedef enum
-{
- P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,
- P_STRING,P_USTRING,P_GSTRING,P_UGSTRING
-} parm_type;
-
-typedef enum
-{
- P_LOCAL,P_GLOBAL,P_NONE
-} parm_class;
-
-int keepalive=0;
-extern BOOL use_getwd_cache;
-
-extern int extra_time_offset;
-extern int coding_system;
-
-/*
- * This structure describes global (ie., server-wide) parameters.
- */
-typedef struct
-{
- char *szPrintcapname;
- char *szLockDir;
- char *szRootdir;
- char *szDefaultService;
- char *szDfree;
- char *szMsgCommand;
- char *szHostsEquiv;
- char *szServerString;
- char *szAutoServices;
- char *szPasswdProgram;
- char *szPasswdChat;
- char *szLogFile;
- char *szConfigFile;
- char *szSMBPasswdFile;
- char *szPasswordServer;
- char *szSocketOptions;
- char *szValidChars;
- char *szWorkGroup;
- char *szDomainController;
- char *szUsernameMap;
- char *szCharacterSet;
- char *szLogonScript;
- char *szLogonPath;
- char *szSmbrun;
- char *szWINSserver;
- char *szInterfaces;
- char *szRemoteAnnounce;
- char *szSocketAddress;
- char *szNISHomeMapName;
- char *szAnnounceVersion; /* This is initialised in init_globals */
- char *szNetbiosAliases;
- char *szDomainSID;
- int max_log_size;
- int mangled_stack;
- int max_xmit;
- int max_mux;
- int max_packet;
- int pwordlevel;
- int unamelevel;
- int deadtime;
- int maxprotocol;
- int security;
- int printing;
- int maxdisksize;
- int lpqcachetime;
- int syslog;
- int os_level;
- int max_ttl;
- int ReadSize;
- int shmem_size;
- int shmem_hash_size;
- int client_code_page;
- int announce_as; /* This is initialised in init_globals */
- BOOL bDNSproxy;
- BOOL bWINSsupport;
- BOOL bWINSproxy;
- BOOL bLocalMaster;
- BOOL bPreferredMaster;
- BOOL bDomainMaster;
- BOOL bDomainLogons;
- BOOL bEncryptPasswords;
- BOOL bStripDot;
- BOOL bNullPasswords;
- BOOL bLoadPrinters;
- BOOL bUseRhosts;
- BOOL bReadRaw;
- BOOL bWriteRaw;
- BOOL bReadPrediction;
- BOOL bReadbmpx;
- BOOL bSyslogOnly;
- BOOL bBrowseList;
- BOOL bUnixRealname;
- BOOL bNISHomeMap;
- BOOL bTimeServer;
-} global;
-
-static global Globals;
-
-
-
-/*
- * This structure describes a single service.
- */
-typedef struct
-{
- BOOL valid;
- char *szService;
- char *szPath;
- char *szUsername;
- char *szGuestaccount;
- char *szInvalidUsers;
- char *szValidUsers;
- char *szAdminUsers;
- char *szCopy;
- char *szInclude;
- char *szPreExec;
- char *szPostExec;
- char *szRootPreExec;
- char *szRootPostExec;
- char *szPrintcommand;
- char *szLpqcommand;
- char *szLprmcommand;
- char *szLppausecommand;
- char *szLpresumecommand;
- char *szPrintername;
- char *szPrinterDriver;
- char *szDontdescend;
- char *szHostsallow;
- char *szHostsdeny;
- char *szMagicScript;
- char *szMagicOutput;
- char *szMangledMap;
- char *szVetoFiles;
- char *szHideFiles;
- char *comment;
- char *force_user;
- char *force_group;
- char *readlist;
- char *writelist;
- char *volume;
- int iMinPrintSpace;
- int iCreate_mask;
- int iCreate_force_mode;
- int iDir_mask;
- int iDir_force_mode;
- int iMaxConnections;
- int iDefaultCase;
- BOOL bAlternatePerm;
- BOOL bRevalidate;
- BOOL bCaseSensitive;
- BOOL bCasePreserve;
- BOOL bShortCasePreserve;
- BOOL bCaseMangle;
- BOOL status;
- BOOL bHideDotFiles;
- BOOL bBrowseable;
- BOOL bAvailable;
- BOOL bRead_only;
- BOOL bNo_set_dir;
- BOOL bGuest_only;
- BOOL bGuest_ok;
- BOOL bPrint_ok;
- BOOL bPostscript;
- BOOL bMap_system;
- BOOL bMap_hidden;
- BOOL bMap_archive;
- BOOL bLocking;
- BOOL bStrictLocking;
- BOOL bShareModes;
- BOOL bOpLocks;
- BOOL bOnlyUser;
- BOOL bMangledNames;
- BOOL bWidelinks;
- BOOL bSymlinks;
- BOOL bSyncAlways;
- char magic_char;
- BOOL *copymap;
- BOOL bDeleteReadonly;
- BOOL bFakeOplocks;
- BOOL bDeleteVetoFiles;
- char dummy[3]; /* for alignment */
-} service;
-
-
-/* This is a default service used to prime a services structure */
-static service sDefault =
-{
- True, /* valid */
- NULL, /* szService */
- NULL, /* szPath */
- NULL, /* szUsername */
- NULL, /* szGuestAccount - this is set in init_globals() */
- NULL, /* szInvalidUsers */
- NULL, /* szValidUsers */
- NULL, /* szAdminUsers */
- NULL, /* szCopy */
- NULL, /* szInclude */
- NULL, /* szPreExec */
- NULL, /* szPostExec */
- NULL, /* szRootPreExec */
- NULL, /* szRootPostExec */
- NULL, /* szPrintcommand */
- NULL, /* szLpqcommand */
- NULL, /* szLprmcommand */
- NULL, /* szLppausecommand */
- NULL, /* szLpresumecommand */
- NULL, /* szPrintername */
- NULL, /* szPrinterDriver - this is set in init_globals() */
- NULL, /* szDontdescend */
- NULL, /* szHostsallow */
- NULL, /* szHostsdeny */
- NULL, /* szMagicScript */
- NULL, /* szMagicOutput */
- NULL, /* szMangledMap */
- NULL, /* szVetoFiles */
- NULL, /* szHideFiles */
- NULL, /* comment */
- NULL, /* force user */
- NULL, /* force group */
- NULL, /* readlist */
- NULL, /* writelist */
- NULL, /* volume */
- 0, /* iMinPrintSpace */
- 0744, /* iCreate_mask */
- 0000, /* iCreate_force_mode */
- 0755, /* iDir_mask */
- 0000, /* iDir_force_mode */
- 0, /* iMaxConnections */
- CASE_LOWER, /* iDefaultCase */
- False, /* bAlternatePerm */
- False, /* revalidate */
- False, /* case sensitive */
- False, /* case preserve */
- False, /* short case preserve */
- False, /* case mangle */
- True, /* status */
- True, /* bHideDotFiles */
- True, /* bBrowseable */
- True, /* bAvailable */
- True, /* bRead_only */
- True, /* bNo_set_dir */
- False, /* bGuest_only */
- False, /* bGuest_ok */
- False, /* bPrint_ok */
- False, /* bPostscript */
- False, /* bMap_system */
- False, /* bMap_hidden */
- True, /* bMap_archive */
- True, /* bLocking */
- False, /* bStrictLocking */
- True, /* bShareModes */
- True, /* bOpLocks */
- False, /* bOnlyUser */
- True, /* bMangledNames */
- True, /* bWidelinks */
- True, /* bSymlinks */
- False, /* bSyncAlways */
- '~', /* magic char */
- NULL, /* copymap */
- False, /* bDeleteReadonly */
- False, /* bFakeOplocks */
- False, /* bDeleteVetoFiles */
- "" /* dummy */
-};
-
-
-
-/* local variables */
-static service **ServicePtrs = NULL;
-static int iNumServices = 0;
-static int iServiceIndex = 0;
-static BOOL bInGlobalSection = True;
-static BOOL bGlobalOnly = False;
-static int default_server_announce;
-
-#define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
-
-/* prototypes for the special type handlers */
-static BOOL handle_valid_chars(char *pszParmValue, char **ptr);
-static BOOL handle_include(char *pszParmValue, char **ptr);
-static BOOL handle_copy(char *pszParmValue, char **ptr);
-static BOOL handle_protocol(char *pszParmValue,int *val);
-static BOOL handle_security(char *pszParmValue,int *val);
-static BOOL handle_case(char *pszParmValue,int *val);
-static BOOL handle_printing(char *pszParmValue,int *val);
-static BOOL handle_character_set(char *pszParmValue,int *val);
-static BOOL handle_announce_as(char *pszParmValue, int *val);
-static BOOL handle_coding_system(char *pszParmValue,int *val);
-
-static void set_default_server_announce_type(void);
-
-struct parm_struct
-{
- char *label;
- parm_type type;
- parm_class class;
- void *ptr;
- BOOL (*special)();
-} parm_table[] =
-{
- {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL},
- {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL},
- {"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL},
- {"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL},
- {"protocol", P_INTEGER, P_GLOBAL, &Globals.maxprotocol,handle_protocol},
- {"security", P_INTEGER, P_GLOBAL, &Globals.security,handle_security},
- {"printing", P_INTEGER, P_GLOBAL, &Globals.printing,handle_printing},
- {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL},
- {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL},
- {"announce as", P_INTEGER, P_GLOBAL, &Globals.announce_as, handle_announce_as},
- {"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL},
- {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL},
- {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL},
- {"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL},
- {"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL},
- {"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL},
- {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL},
- {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL},
- {"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL},
- {"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL},
- {"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL},
- {"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL},
- {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL},
- {"netbios name", P_UGSTRING,P_GLOBAL, myname, NULL},
- {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL},
- {"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL},
- {"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL},
- {"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL},
- {"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL},
- {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL},
- {"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL},
- {"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL},
- {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL},
- {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL},
- {"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL},
- {"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL},
- {"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL},
- {"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
- {"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
- {"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL},
- {"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL},
- {"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL},
- {"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL},
- {"dfree command", P_STRING, P_GLOBAL, &Globals.szDfree, NULL},
- {"passwd program", P_STRING, P_GLOBAL, &Globals.szPasswdProgram, NULL},
- {"passwd chat", P_STRING, P_GLOBAL, &Globals.szPasswdChat, NULL},
- {"valid chars", P_STRING, P_GLOBAL, &Globals.szValidChars, handle_valid_chars},
- {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL},
- {"domain sid", P_USTRING, P_GLOBAL, &Globals.szDomainSID, NULL},
- {"domain controller",P_STRING, P_GLOBAL, &Globals.szDomainController,NULL},
- {"username map", P_STRING, P_GLOBAL, &Globals.szUsernameMap, NULL},
- {"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set},
- {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL},
- {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL},
- {"remote announce", P_STRING, P_GLOBAL, &Globals.szRemoteAnnounce, NULL},
- {"socket address", P_STRING, P_GLOBAL, &Globals.szSocketAddress, NULL},
- {"homedir map", P_STRING, P_GLOBAL, &Globals.szNISHomeMapName, NULL},
- {"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL},
- {"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL},
- {"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL},
- {"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL},
- {"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL},
- {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL},
- {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL},
- {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL},
- {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL},
- {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL},
- {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL},
- {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL},
- {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL},
- {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL},
- {"shared file entries", P_INTEGER, P_GLOBAL, &Globals.shmem_hash_size, NULL},
- {"coding system", P_INTEGER, P_GLOBAL, &coding_system, handle_coding_system},
- {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL},
- {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL},
- {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL},
- {"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL},
- {"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL},
- {"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL},
- {"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL},
- {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
- {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL},
- {"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL},
- {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL},
- {"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL},
- {"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL},
- {"unix realname", P_BOOL, P_GLOBAL, &Globals.bUnixRealname, NULL},
- {"NIS homedir", P_BOOL, P_GLOBAL, &Globals.bNISHomeMap, NULL},
- {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL},
- {"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL},
- {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL},
- {"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy},
- {"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include},
- {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL},
- {"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL},
- {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL},
- {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL},
- {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL},
- {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL},
- {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL},
- {"default case", P_INTEGER, P_LOCAL, &sDefault.iDefaultCase, handle_case},
- {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL},
- {"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL},
- {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL},
- {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL},
- {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL},
- {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL},
- {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL},
- {"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL},
- {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL},
- {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL},
- {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL},
- {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
- {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
- {"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL},
- {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL},
- {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL},
- {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL},
- {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL},
- {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL},
- {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL},
- {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL},
- {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL},
- {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL},
- {"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL},
- {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL},
- {"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
- {"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
- {"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL},
- {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL},
- {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL},
- {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL},
- {"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL},
- {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL},
- {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL},
- {"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL},
- {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL},
- {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL},
- {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL},
- {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL},
- {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL},
- {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL},
- {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL},
- {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL},
- {"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL},
- {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL},
- {"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL},
- {"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL},
- {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL},
- {"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL},
- {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL},
- {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL},
- {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL},
- {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL},
- {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL},
- {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL},
- {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL},
- {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL},
- {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL},
- {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL},
- {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL},
- {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL},
- {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL},
- {"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL},
- {"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL},
- {"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL},
- {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL},
- {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL},
- {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL},
- {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL},
- {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL},
- {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL},
- {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL},
- {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL},
- {"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL},
- {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL},
- {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL},
- {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL},
- {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL},
- {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL},
-
- {NULL, P_BOOL, P_NONE, NULL, NULL}
-};
-
-
-
-/***************************************************************************
-Initialise the global parameter structure.
-***************************************************************************/
-static void init_globals(void)
-{
- static BOOL done_init = False;
- pstring s;
-
- if (!done_init)
- {
- int i;
- bzero((void *)&Globals,sizeof(Globals));
-
- for (i = 0; parm_table[i].label; i++)
- if ((parm_table[i].type == P_STRING ||
- parm_table[i].type == P_USTRING) &&
- parm_table[i].ptr)
- string_init(parm_table[i].ptr,"");
-
- string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
- string_set(&sDefault.szPrinterDriver, "NULL");
-
- done_init = True;
- }
-
-
- DEBUG(3,("Initialising global parameters\n"));
-
-#ifdef SMB_PASSWD_FILE
- string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
-#endif
- string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
- string_set(&Globals.szWorkGroup, WORKGROUP);
- string_set(&Globals.szPasswdProgram, SMB_PASSWD);
- string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
- string_set(&Globals.szLockDir, LOCKDIR);
- string_set(&Globals.szRootdir, "/");
- string_set(&Globals.szSmbrun, SMBRUN);
- string_set(&Globals.szSocketAddress, "0.0.0.0");
- sprintf(s,"Samba %s",VERSION);
- string_set(&Globals.szServerString,s);
- sprintf(s,"%d.%d", DEFAULT_MAJOR_VERSION, DEFAULT_MINOR_VERSION);
- string_set(&Globals.szAnnounceVersion,s);
- Globals.bLoadPrinters = True;
- Globals.bUseRhosts = False;
- Globals.max_packet = 65535;
- Globals.mangled_stack = 50;
- Globals.max_xmit = 65535;
- Globals.max_mux = 50; /* This is *needed* for profile support. */
- Globals.lpqcachetime = 10;
- Globals.pwordlevel = 0;
- Globals.unamelevel = 0;
- Globals.deadtime = 0;
- Globals.max_log_size = 5000;
- Globals.maxprotocol = PROTOCOL_NT1;
- Globals.security = SEC_SHARE;
- Globals.bEncryptPasswords = False;
- Globals.printing = DEFAULT_PRINTING;
- Globals.bReadRaw = True;
- Globals.bWriteRaw = True;
- Globals.bReadPrediction = False;
- Globals.bReadbmpx = True;
- Globals.bNullPasswords = False;
- Globals.bStripDot = False;
- Globals.syslog = 1;
- Globals.bSyslogOnly = False;
- Globals.os_level = 0;
- Globals.max_ttl = 60*60*4; /* 2 hours default */
- Globals.ReadSize = 16*1024;
- Globals.shmem_size = SHMEM_SIZE;
- Globals.shmem_hash_size = SHMEM_HASH_SIZE;
- Globals.announce_as = ANNOUNCE_AS_NT;
- Globals.bUnixRealname = False;
-#if (defined(NETGROUP) && defined(AUTOMOUNT))
- Globals.bNISHomeMap = False;
- string_set(&Globals.szNISHomeMapName, "auto.home");
-#endif
- coding_system = interpret_coding_system (KANJI, SJIS_CODE);
- Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE;
- Globals.bTimeServer = False;
-
-/* these parameters are set to defaults that are more appropriate
- for the increasing samba install base:
-
- as a member of the workgroup, that will possibly become a
- _local_ master browser (lm = True). this is opposed to a forced
- local master browser startup (pm = True).
-
- doesn't provide WINS server service by default (wsupp = False),
- and doesn't provide domain master browser services by default, either.
-
-*/
-
- Globals.bPreferredMaster = False;
- Globals.bLocalMaster = True;
- Globals.bDomainMaster = False;
- Globals.bDomainLogons = False;
- Globals.bBrowseList = True;
- Globals.bWINSsupport = False;
- Globals.bWINSproxy = False;
-
-/* this parameter is currently set to the default functionality
- in samba. given that w95 and NT is starting to use DNS for
- server resolution, i expect that at some point it would be
- sensible to default this to False.
-
- this parameter is added because nmbd is a single process, and
- gethostbyname is a blocking call, which can take out nmbd for
- several seconds while a dns lookup is performed.
-
- */
-
- Globals.bDNSproxy = True;
-}
-
-/***************************************************************************
-check if a string is initialised and if not then initialise it
-***************************************************************************/
-static void string_initial(char **s,char *v)
-{
- if (!*s || !**s)
- string_init(s,v);
-}
-
-
-/***************************************************************************
-Initialise the sDefault parameter structure.
-***************************************************************************/
-static void init_locals(void)
-{
- /* choose defaults depending on the type of printing */
- switch (Globals.printing)
- {
- case PRINT_BSD:
- case PRINT_AIX:
- case PRINT_LPRNG:
- case PRINT_PLP:
- string_initial(&sDefault.szLpqcommand,"lpq -P%p");
- string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
- string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
- break;
-
- case PRINT_SYSV:
- case PRINT_HPUX:
- string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
- string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
- string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
-#ifdef SVR4
- string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
- string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
-#endif
- break;
-
- case PRINT_QNX:
- string_initial(&sDefault.szLpqcommand,"lpq -P%p");
- string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
- string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
- break;
-
-
- }
-}
-
-
-/******************************************************************* a
-convenience routine to grab string parameters into a rotating buffer,
-and run standard_sub_basic on them. The buffers can be written to by
-callers without affecting the source string.
-********************************************************************/
-char *lp_string(char *s)
-{
- static char *bufs[10];
- static int buflen[10];
- static int next = -1;
- char *ret;
- int i;
- int len = s?strlen(s):0;
-
- if (next == -1) {
- /* initialisation */
- for (i=0;i<10;i++) {
- bufs[i] = NULL;
- buflen[i] = 0;
- }
- next = 0;
- }
-
- len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
- substitution room */
-
- if (buflen[next] != len) {
- buflen[next] = len;
- if (bufs[next]) free(bufs[next]);
- bufs[next] = (char *)malloc(len);
- if (!bufs[next]) {
- DEBUG(0,("out of memory in lp_string()"));
- exit(1);
- }
- }
-
- ret = &bufs[next][0];
- next = (next+1)%10;
-
- if (!s)
- *ret = 0;
- else
- StrCpy(ret,s);
-
- standard_sub_basic(ret);
- return(ret);
-}
-
-
-/*
- In this section all the functions that are used to access the
- parameters from the rest of the program are defined
-*/
-
-#define FN_GLOBAL_STRING(fn_name,ptr) \
- char *fn_name(void) {return(lp_string(*(char **)(ptr) ? *(char **)(ptr) : ""));}
-#define FN_GLOBAL_BOOL(fn_name,ptr) \
- BOOL fn_name(void) {return(*(BOOL *)(ptr));}
-#define FN_GLOBAL_CHAR(fn_name,ptr) \
- char fn_name(void) {return(*(char *)(ptr));}
-#define FN_GLOBAL_INTEGER(fn_name,ptr) \
- int fn_name(void) {return(*(int *)(ptr));}
-
-#define FN_LOCAL_STRING(fn_name,val) \
- char *fn_name(int i) {return(lp_string((LP_SNUM_OK(i)&&pSERVICE(i)->val)?pSERVICE(i)->val : sDefault.val));}
-#define FN_LOCAL_BOOL(fn_name,val) \
- BOOL fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
-#define FN_LOCAL_CHAR(fn_name,val) \
- char fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
-#define FN_LOCAL_INTEGER(fn_name,val) \
- int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
-
-FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
-FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
-FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
-FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
-FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
-FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
-FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
-FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
-FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
-FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
-FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree)
-FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
-FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
-FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
-FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
-FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
-FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
-FN_GLOBAL_STRING(lp_domain_controller,&Globals.szDomainController)
-FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
-FN_GLOBAL_STRING(lp_character_set,&Globals.szCharacterSet)
-FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
-FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath)
-FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
-FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
-FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
-FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
-FN_GLOBAL_STRING(lp_nis_home_map_name,&Globals.szNISHomeMapName)
-FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
-FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
-
-FN_GLOBAL_STRING(lp_domainsid,&Globals.szDomainSID)
-
-FN_GLOBAL_BOOL(lp_dns_proxy,&Globals.bDNSproxy)
-FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
-FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
-FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
-FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
-FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
-FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
-FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
-FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
-FN_GLOBAL_BOOL(lp_getwdcache,&use_getwd_cache)
-FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
-FN_GLOBAL_BOOL(lp_readbmpx,&Globals.bReadbmpx)
-FN_GLOBAL_BOOL(lp_readraw,&Globals.bReadRaw)
-FN_GLOBAL_BOOL(lp_writeraw,&Globals.bWriteRaw)
-FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
-FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
-FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
-FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
-FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
-FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
-FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
-FN_GLOBAL_BOOL(lp_time_server,&Globals.bTimeServer)
-
-FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
-FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
-FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
-FN_GLOBAL_INTEGER(lp_mangledstack,&Globals.mangled_stack)
-FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
-FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
-FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet)
-FN_GLOBAL_INTEGER(lp_keepalive,&keepalive)
-FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
-FN_GLOBAL_INTEGER(lp_usernamelevel,&Globals.unamelevel)
-FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize)
-FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size)
-FN_GLOBAL_INTEGER(lp_shmem_hash_size,&Globals.shmem_hash_size)
-FN_GLOBAL_INTEGER(lp_deadtime,&Globals.deadtime)
-FN_GLOBAL_INTEGER(lp_maxprotocol,&Globals.maxprotocol)
-FN_GLOBAL_INTEGER(lp_security,&Globals.security)
-FN_GLOBAL_INTEGER(lp_printing,&Globals.printing)
-FN_GLOBAL_INTEGER(lp_maxdisksize,&Globals.maxdisksize)
-FN_GLOBAL_INTEGER(lp_lpqcachetime,&Globals.lpqcachetime)
-FN_GLOBAL_INTEGER(lp_syslog,&Globals.syslog)
-FN_GLOBAL_INTEGER(lp_client_code_page,&Globals.client_code_page)
-FN_GLOBAL_INTEGER(lp_announce_as,&Globals.announce_as)
-
-FN_LOCAL_STRING(lp_preexec,szPreExec)
-FN_LOCAL_STRING(lp_postexec,szPostExec)
-FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
-FN_LOCAL_STRING(lp_rootpostexec,szRootPostExec)
-FN_LOCAL_STRING(lp_servicename,szService)
-FN_LOCAL_STRING(lp_pathname,szPath)
-FN_LOCAL_STRING(lp_dontdescend,szDontdescend)
-FN_LOCAL_STRING(lp_username,szUsername)
-FN_LOCAL_STRING(lp_guestaccount,szGuestaccount)
-FN_LOCAL_STRING(lp_invalid_users,szInvalidUsers)
-FN_LOCAL_STRING(lp_valid_users,szValidUsers)
-FN_LOCAL_STRING(lp_admin_users,szAdminUsers)
-FN_LOCAL_STRING(lp_printcommand,szPrintcommand)
-FN_LOCAL_STRING(lp_lpqcommand,szLpqcommand)
-FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand)
-FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand)
-FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand)
-FN_LOCAL_STRING(lp_printername,szPrintername)
-FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver)
-FN_LOCAL_STRING(lp_hostsallow,szHostsallow)
-FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny)
-FN_LOCAL_STRING(lp_magicscript,szMagicScript)
-FN_LOCAL_STRING(lp_magicoutput,szMagicOutput)
-FN_LOCAL_STRING(lp_comment,comment)
-FN_LOCAL_STRING(lp_force_user,force_user)
-FN_LOCAL_STRING(lp_force_group,force_group)
-FN_LOCAL_STRING(lp_readlist,readlist)
-FN_LOCAL_STRING(lp_writelist,writelist)
-FN_LOCAL_STRING(lp_volume,volume)
-FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
-FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
-FN_LOCAL_STRING(lp_hide_files,szHideFiles)
-
-FN_LOCAL_BOOL(lp_alternate_permissions,bAlternatePerm)
-FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
-FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
-FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
-FN_LOCAL_BOOL(lp_shortpreservecase,bShortCasePreserve)
-FN_LOCAL_BOOL(lp_casemangle,bCaseMangle)
-FN_LOCAL_BOOL(lp_status,status)
-FN_LOCAL_BOOL(lp_hide_dot_files,bHideDotFiles)
-FN_LOCAL_BOOL(lp_browseable,bBrowseable)
-FN_LOCAL_BOOL(lp_readonly,bRead_only)
-FN_LOCAL_BOOL(lp_no_set_dir,bNo_set_dir)
-FN_LOCAL_BOOL(lp_guest_ok,bGuest_ok)
-FN_LOCAL_BOOL(lp_guest_only,bGuest_only)
-FN_LOCAL_BOOL(lp_print_ok,bPrint_ok)
-FN_LOCAL_BOOL(lp_postscript,bPostscript)
-FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
-FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
-FN_LOCAL_BOOL(lp_locking,bLocking)
-FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
-FN_LOCAL_BOOL(lp_share_modes,bShareModes)
-FN_LOCAL_BOOL(lp_oplocks,bOpLocks)
-FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
-FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
-FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
-FN_LOCAL_BOOL(lp_symlinks,bSymlinks)
-FN_LOCAL_BOOL(lp_syncalways,bSyncAlways)
-FN_LOCAL_BOOL(lp_map_system,bMap_system)
-FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly)
-FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks)
-FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles)
-
-FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
-FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
-FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
-FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
-FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
-FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
-FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
-
-FN_LOCAL_CHAR(lp_magicchar,magic_char)
-
-
-
-/* local prototypes */
-static int strwicmp( char *psz1, char *psz2 );
-static int map_parameter( char *pszParmName);
-static BOOL set_boolean( BOOL *pb, char *pszParmValue );
-static int getservicebyname(char *pszServiceName, service *pserviceDest);
-static void copy_service( service *pserviceDest,
- service *pserviceSource,
- BOOL *pcopymapDest );
-static BOOL service_ok(int iService);
-static BOOL do_parameter(char *pszParmName, char *pszParmValue);
-static BOOL do_section(char *pszSectionName);
-static void init_copymap(service *pservice);
-
-
-/***************************************************************************
-initialise a service to the defaults
-***************************************************************************/
-static void init_service(service *pservice)
-{
- bzero((char *)pservice,sizeof(service));
- copy_service(pservice,&sDefault,NULL);
-}
-
-
-/***************************************************************************
-free the dynamically allocated parts of a service struct
-***************************************************************************/
-static void free_service(service *pservice)
-{
- int i;
- if (!pservice)
- return;
-
- for (i=0;parm_table[i].label;i++)
- if ((parm_table[i].type == P_STRING ||
- parm_table[i].type == P_STRING) &&
- parm_table[i].class == P_LOCAL)
- string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
-}
-
-/***************************************************************************
-add a new service to the services array initialising it with the given
-service
-***************************************************************************/
-static int add_a_service(service *pservice, char *name)
-{
- int i;
- service tservice;
- int num_to_alloc = iNumServices+1;
-
- tservice = *pservice;
-
- /* it might already exist */
- if (name)
- {
- i = getservicebyname(name,NULL);
- if (i >= 0)
- return(i);
- }
-
- /* find an invalid one */
- for (i=0;i<iNumServices;i++)
- if (!pSERVICE(i)->valid)
- break;
-
- /* if not, then create one */
- if (i == iNumServices)
- {
- ServicePtrs = (service **)Realloc(ServicePtrs,sizeof(service *)*num_to_alloc);
- if (ServicePtrs)
- pSERVICE(iNumServices) = (service *)malloc(sizeof(service));
-
- if (!ServicePtrs || !pSERVICE(iNumServices))
- return(-1);
-
- iNumServices++;
- }
- else
- free_service(pSERVICE(i));
-
- pSERVICE(i)->valid = True;
-
- init_service(pSERVICE(i));
- copy_service(pSERVICE(i),&tservice,NULL);
- if (name)
- string_set(&iSERVICE(i).szService,name);
-
- return(i);
-}
-
-/***************************************************************************
-add a new home service, with the specified home directory, defaults coming
-from service ifrom
-***************************************************************************/
-BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir)
-{
- int i = add_a_service(pSERVICE(iDefaultService),pszHomename);
-
- if (i < 0)
- return(False);
-
- if (!(*(iSERVICE(i).szPath)) || strequal(iSERVICE(i).szPath,lp_pathname(-1)))
- string_set(&iSERVICE(i).szPath,pszHomedir);
- if (!(*(iSERVICE(i).comment)))
- {
- pstring comment;
- sprintf(comment,"Home directory of %s",pszHomename);
- string_set(&iSERVICE(i).comment,comment);
- }
- iSERVICE(i).bAvailable = sDefault.bAvailable;
- iSERVICE(i).bBrowseable = sDefault.bBrowseable;
-
- DEBUG(3,("adding home directory %s at %s\n", pszHomename, pszHomedir));
-
- return(True);
-}
-
-/***************************************************************************
-add a new service, based on an old one
-***************************************************************************/
-int lp_add_service(char *pszService, int iDefaultService)
-{
- return(add_a_service(pSERVICE(iDefaultService),pszService));
-}
-
-
-/***************************************************************************
-add the IPC service
-***************************************************************************/
-static BOOL lp_add_ipc(void)
-{
- pstring comment;
- int i = add_a_service(&sDefault,"IPC$");
-
- if (i < 0)
- return(False);
-
- sprintf(comment,"IPC Service (%s)",lp_serverstring());
-
- string_set(&iSERVICE(i).szPath,tmpdir());
- string_set(&iSERVICE(i).szUsername,"");
- string_set(&iSERVICE(i).comment,comment);
- iSERVICE(i).status = False;
- iSERVICE(i).iMaxConnections = 0;
- iSERVICE(i).bAvailable = True;
- iSERVICE(i).bRead_only = True;
- iSERVICE(i).bGuest_only = False;
- iSERVICE(i).bGuest_ok = True;
- iSERVICE(i).bPrint_ok = False;
- iSERVICE(i).bBrowseable = sDefault.bBrowseable;
-
- DEBUG(3,("adding IPC service\n"));
-
- return(True);
-}
-
-
-/***************************************************************************
-add a new printer service, with defaults coming from service iFrom
-***************************************************************************/
-BOOL lp_add_printer(char *pszPrintername, int iDefaultService)
-{
- char *comment = "From Printcap";
- int i = add_a_service(pSERVICE(iDefaultService),pszPrintername);
-
- if (i < 0)
- return(False);
-
- /* note that we do NOT default the availability flag to True - */
- /* we take it from the default service passed. This allows all */
- /* dynamic printers to be disabled by disabling the [printers] */
- /* entry (if/when the 'available' keyword is implemented!). */
-
- /* the printer name is set to the service name. */
- string_set(&iSERVICE(i).szPrintername,pszPrintername);
- string_set(&iSERVICE(i).comment,comment);
- iSERVICE(i).bBrowseable = sDefault.bBrowseable;
- /* Printers cannot be read_only. */
- iSERVICE(i).bRead_only = False;
- /* No share modes on printer services. */
- iSERVICE(i).bShareModes = False;
- /* No oplocks on printer services. */
- iSERVICE(i).bOpLocks = False;
- /* Printer services must be printable. */
- iSERVICE(i).bPrint_ok = True;
-
- DEBUG(3,("adding printer service %s\n",pszPrintername));
-
- return(True);
-}
-
-
-/***************************************************************************
-Do a case-insensitive, whitespace-ignoring string compare.
-***************************************************************************/
-static int strwicmp(char *psz1, char *psz2)
-{
- /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
- /* appropriate value. */
- if (psz1 == psz2)
- return (0);
- else
- if (psz1 == NULL)
- return (-1);
- else
- if (psz2 == NULL)
- return (1);
-
- /* sync the strings on first non-whitespace */
- while (1)
- {
- while (isspace(*psz1))
- psz1++;
- while (isspace(*psz2))
- psz2++;
- if (toupper(*psz1) != toupper(*psz2) || *psz1 == '\0' || *psz2 == '\0')
- break;
- psz1++;
- psz2++;
- }
- return (*psz1 - *psz2);
-}
-
-/***************************************************************************
-Map a parameter's string representation to something we can use.
-Returns False if the parameter string is not recognised, else TRUE.
-***************************************************************************/
-static int map_parameter(char *pszParmName)
-{
- int iIndex;
-
- if (*pszParmName == '-')
- return(-1);
-
- for (iIndex = 0; parm_table[iIndex].label; iIndex++)
- if (strwicmp(parm_table[iIndex].label, pszParmName) == 0)
- return(iIndex);
-
- DEBUG(0,( "Unknown parameter encountered: \"%s\"\n", pszParmName));
- return(-1);
-}
-
-
-/***************************************************************************
-Set a boolean variable from the text value stored in the passed string.
-Returns True in success, False if the passed string does not correctly
-represent a boolean.
-***************************************************************************/
-static BOOL set_boolean(BOOL *pb, char *pszParmValue)
-{
- BOOL bRetval;
-
- bRetval = True;
- if (strwicmp(pszParmValue, "yes") == 0 ||
- strwicmp(pszParmValue, "true") == 0 ||
- strwicmp(pszParmValue, "1") == 0)
- *pb = True;
- else
- if (strwicmp(pszParmValue, "no") == 0 ||
- strwicmp(pszParmValue, "False") == 0 ||
- strwicmp(pszParmValue, "0") == 0)
- *pb = False;
- else
- {
- DEBUG(0,( "Badly formed boolean in configuration file: \"%s\".\n",
- pszParmValue));
- bRetval = False;
- }
- return (bRetval);
-}
-
-/***************************************************************************
-Find a service by name. Otherwise works like get_service.
-***************************************************************************/
-static int getservicebyname(char *pszServiceName, service *pserviceDest)
-{
- int iService;
-
- for (iService = iNumServices - 1; iService >= 0; iService--)
- if (VALID(iService) &&
- strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
- {
- if (pserviceDest != NULL)
- copy_service(pserviceDest, pSERVICE(iService), NULL);
- break;
- }
-
- return (iService);
-}
-
-
-
-/***************************************************************************
-Copy a service structure to another
-
-If pcopymapDest is NULL then copy all fields
-***************************************************************************/
-static void copy_service(service *pserviceDest,
- service *pserviceSource,
- BOOL *pcopymapDest)
-{
- int i;
- BOOL bcopyall = (pcopymapDest == NULL);
-
- for (i=0;parm_table[i].label;i++)
- if (parm_table[i].ptr && parm_table[i].class == P_LOCAL &&
- (bcopyall || pcopymapDest[i]))
- {
- void *def_ptr = parm_table[i].ptr;
- void *src_ptr =
- ((char *)pserviceSource) + PTR_DIFF(def_ptr,&sDefault);
- void *dest_ptr =
- ((char *)pserviceDest) + PTR_DIFF(def_ptr,&sDefault);
-
- switch (parm_table[i].type)
- {
- case P_BOOL:
- case P_BOOLREV:
- *(BOOL *)dest_ptr = *(BOOL *)src_ptr;
- break;
-
- case P_INTEGER:
- case P_OCTAL:
- *(int *)dest_ptr = *(int *)src_ptr;
- break;
-
- case P_CHAR:
- *(char *)dest_ptr = *(char *)src_ptr;
- break;
-
- case P_STRING:
- string_set(dest_ptr,*(char **)src_ptr);
- break;
-
- case P_USTRING:
- string_set(dest_ptr,*(char **)src_ptr);
- strupper(*(char **)dest_ptr);
- break;
- default:
- break;
- }
- }
-
- if (bcopyall)
- {
- init_copymap(pserviceDest);
- if (pserviceSource->copymap)
- memcpy((void *)pserviceDest->copymap,
- (void *)pserviceSource->copymap,sizeof(BOOL)*NUMPARAMETERS);
- }
-}
-
-/***************************************************************************
-Check a service for consistency. Return False if the service is in any way
-incomplete or faulty, else True.
-***************************************************************************/
-static BOOL service_ok(int iService)
-{
- BOOL bRetval;
-
- bRetval = True;
- if (iSERVICE(iService).szService[0] == '\0')
- {
- DEBUG(0,( "The following message indicates an internal error:\n"));
- DEBUG(0,( "No service name in service entry.\n"));
- bRetval = False;
- }
-
- /* The [printers] entry MUST be printable. I'm all for flexibility, but */
- /* I can't see why you'd want a non-printable printer service... */
- if (strwicmp(iSERVICE(iService).szService,PRINTERS_NAME) == 0)
- if (!iSERVICE(iService).bPrint_ok)
- {
- DEBUG(0,( "WARNING: [%s] service MUST be printable!\n",
- iSERVICE(iService).szService));
- iSERVICE(iService).bPrint_ok = True;
- }
-
- if (iSERVICE(iService).szPath[0] == '\0' &&
- strwicmp(iSERVICE(iService).szService,HOMES_NAME) != 0)
- {
- DEBUG(0,("No path in service %s - using %s\n",iSERVICE(iService).szService,tmpdir()));
- string_set(&iSERVICE(iService).szPath,tmpdir());
- }
-
- /* If a service is flagged unavailable, log the fact at level 0. */
- if (!iSERVICE(iService).bAvailable)
- DEBUG(1,( "NOTE: Service %s is flagged unavailable.\n",
- iSERVICE(iService).szService));
-
- return (bRetval);
-}
-
-static struct file_lists {
- struct file_lists *next;
- char *name;
- time_t modtime;
-} *file_lists = NULL;
-
-/*******************************************************************
-keep a linked list of all config files so we know when one has changed
-it's date and needs to be reloaded
-********************************************************************/
-static void add_to_file_list(char *fname)
-{
- struct file_lists *f=file_lists;
-
- while (f) {
- if (f->name && !strcmp(f->name,fname)) break;
- f = f->next;
- }
-
- if (!f) {
- f = (struct file_lists *)malloc(sizeof(file_lists[0]));
- if (!f) return;
- f->next = file_lists;
- f->name = strdup(fname);
- if (!f->name) {
- free(f);
- return;
- }
- file_lists = f;
- }
-
- {
- pstring n2;
- pstrcpy(n2,fname);
- standard_sub_basic(n2);
- f->modtime = file_modtime(n2);
- }
-
-}
-
-/*******************************************************************
-check if a config file has changed date
-********************************************************************/
-BOOL lp_file_list_changed(void)
-{
- struct file_lists *f = file_lists;
- DEBUG(6,("lp_file_list_changed()\n"));
-
- while (f)
- {
- pstring n2;
- time_t mod_time;
-
- pstrcpy(n2,f->name);
- standard_sub_basic(n2);
-
- DEBUG(6,("file %s -> %s last mod_time: %s\n",
- f->name, n2, ctime(&f->modtime)));
-
- mod_time = file_modtime(n2);
-
- if (f->modtime != mod_time)
- {
- DEBUG(6,("file %s modified: %s\n", n2, ctime(&mod_time)));
- return(True);
- }
- f = f->next;
- }
- return(False);
-}
-
-/***************************************************************************
- handle the interpretation of the coding system parameter
- *************************************************************************/
-static BOOL handle_coding_system(char *pszParmValue,int *val)
-{
- *val = interpret_coding_system(pszParmValue,*val);
- return(True);
-}
-
-/***************************************************************************
-handle the interpretation of the character set system parameter
-***************************************************************************/
-static BOOL handle_character_set(char *pszParmValue,int *val)
-{
- string_set(&Globals.szCharacterSet,pszParmValue);
- *val = interpret_character_set(pszParmValue,*val);
- return(True);
-}
-
-
-/***************************************************************************
-handle the interpretation of the protocol parameter
-***************************************************************************/
-static BOOL handle_protocol(char *pszParmValue,int *val)
-{
- *val = interpret_protocol(pszParmValue,*val);
- return(True);
-}
-
-/***************************************************************************
-handle the interpretation of the security parameter
-***************************************************************************/
-static BOOL handle_security(char *pszParmValue,int *val)
-{
- *val = interpret_security(pszParmValue,*val);
- return(True);
-}
-
-/***************************************************************************
-handle the interpretation of the default case
-***************************************************************************/
-static BOOL handle_case(char *pszParmValue,int *val)
-{
- if (strnequal(pszParmValue,"LOWER", 5))
- *val = CASE_LOWER;
- else if (strnequal(pszParmValue,"UPPER", 5))
- *val = CASE_UPPER;
- return(True);
-}
-
-/***************************************************************************
-handle the interpretation of the printing system
-***************************************************************************/
-static BOOL handle_printing(char *pszParmValue,int *val)
-{
- if (strnequal(pszParmValue,"sysv", 4))
- *val = PRINT_SYSV;
- else if (strnequal(pszParmValue,"aix", 3))
- *val = PRINT_AIX;
- else if (strnequal(pszParmValue,"hpux", 4))
- *val = PRINT_HPUX;
- else if (strnequal(pszParmValue,"bsd", 3))
- *val = PRINT_BSD;
- else if (strnequal(pszParmValue,"qnx",3))
- *val = PRINT_QNX;
- else if (strnequal(pszParmValue,"plp", 3))
- *val = PRINT_PLP;
- else if (strnequal(pszParmValue,"lprng", 5))
- *val = PRINT_LPRNG;
- return(True);
-}
-
-/***************************************************************************
-handle the announce as parameter
-***************************************************************************/
-static BOOL handle_announce_as(char *pszParmValue,int *val)
-{
- if (strnequal(pszParmValue,"NT", 2))
- *val = ANNOUNCE_AS_NT;
- else if (strnequal(pszParmValue,"win95", 5))
- *val = ANNOUNCE_AS_WIN95;
- else if (strnequal(pszParmValue,"WfW", 3))
- *val = ANNOUNCE_AS_WFW;
- return True;
-}
-
-/***************************************************************************
-handle the valid chars lines
-***************************************************************************/
-static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
-{
- string_set(ptr,pszParmValue);
-
- /* A dependency here is that the parameter client code page must be
- set before this is called - as calling codepage_initialise()
- would overwrite the valid char lines.
- */
- codepage_initialise(lp_client_code_page());
-
- add_char_string(pszParmValue);
- return(True);
-}
-
-
-/***************************************************************************
-handle the include operation
-***************************************************************************/
-static BOOL handle_include(char *pszParmValue,char **ptr)
-{
- pstring fname;
- pstrcpy(fname,pszParmValue);
-
- add_to_file_list(fname);
-
- standard_sub_basic(fname);
-
- string_set(ptr,fname);
-
- if (file_exist(fname,NULL))
- return(pm_process(fname, do_section, do_parameter));
-
- DEBUG(2,("Can't find include file %s\n",fname));
-
- return(False);
-}
-
-
-/***************************************************************************
-handle the interpretation of the copy parameter
-***************************************************************************/
-static BOOL handle_copy(char *pszParmValue,char **ptr)
-{
- BOOL bRetval;
- int iTemp;
- service serviceTemp;
-
- string_set(ptr,pszParmValue);
-
- init_service(&serviceTemp);
-
- bRetval = False;
-
- DEBUG(3,("Copying service from service %s\n",pszParmValue));
-
- if ((iTemp = getservicebyname(pszParmValue, &serviceTemp)) >= 0)
- {
- if (iTemp == iServiceIndex)
- {
- DEBUG(0,("Can't copy service %s - unable to copy self!\n",
- pszParmValue));
- }
- else
- {
- copy_service(pSERVICE(iServiceIndex),
- &serviceTemp,
- iSERVICE(iServiceIndex).copymap);
- bRetval = True;
- }
- }
- else
- {
- DEBUG(0,( "Unable to copy service - source not found: %s\n",
- pszParmValue));
- bRetval = False;
- }
-
- free_service(&serviceTemp);
- return (bRetval);
-}
-
-
-/***************************************************************************
-initialise a copymap
-***************************************************************************/
-static void init_copymap(service *pservice)
-{
- int i;
- if (pservice->copymap) free(pservice->copymap);
- pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
- if (!pservice->copymap)
- DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
-
- for (i=0;i<NUMPARAMETERS;i++)
- pservice->copymap[i] = True;
-}
-
-
-/***************************************************************************
-Process a parameter for a particular service number. If snum < 0
-then assume we are in the globals
-***************************************************************************/
-BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
-{
- int parmnum;
- void *parm_ptr=NULL; /* where we are going to store the result */
- void *def_ptr=NULL;
-
- parmnum = map_parameter(pszParmName);
-
- if (parmnum < 0)
- {
- DEBUG(0,( "Ignoring unknown parameter \"%s\"\n", pszParmName));
- return(True);
- }
-
- def_ptr = parm_table[parmnum].ptr;
-
- /* we might point at a service, the default service or a global */
- if (snum < 0) {
- parm_ptr = def_ptr;
- } else {
- if (parm_table[parmnum].class == P_GLOBAL) {
- DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName));
- return(True);
- }
- parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault);
- }
-
- if (snum >= 0) {
- int i;
- if (!iSERVICE(snum).copymap)
- init_copymap(pSERVICE(snum));
-
- /* this handles the aliases - set the copymap for other entries with
- the same data pointer */
- for (i=0;parm_table[i].label;i++)
- if (parm_table[i].ptr == parm_table[parmnum].ptr)
- iSERVICE(snum).copymap[i] = False;
- }
-
- /* if it is a special case then go ahead */
- if (parm_table[parmnum].special) {
- parm_table[parmnum].special(pszParmValue,parm_ptr);
- return(True);
- }
-
- /* now switch on the type of variable it is */
- switch (parm_table[parmnum].type)
- {
- case P_BOOL:
- set_boolean(parm_ptr,pszParmValue);
- break;
-
- case P_BOOLREV:
- set_boolean(parm_ptr,pszParmValue);
- *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
- break;
-
- case P_INTEGER:
- *(int *)parm_ptr = atoi(pszParmValue);
- break;
-
- case P_CHAR:
- *(char *)parm_ptr = *pszParmValue;
- break;
-
- case P_OCTAL:
- sscanf(pszParmValue,"%o",(int *)parm_ptr);
- break;
-
- case P_STRING:
- string_set(parm_ptr,pszParmValue);
- break;
-
- case P_USTRING:
- string_set(parm_ptr,pszParmValue);
- strupper(*(char **)parm_ptr);
- break;
-
- case P_GSTRING:
- strcpy((char *)parm_ptr,pszParmValue);
- break;
-
- case P_UGSTRING:
- strcpy((char *)parm_ptr,pszParmValue);
- strupper((char *)parm_ptr);
- break;
- }
-
- return(True);
-}
-
-/***************************************************************************
-Process a parameter.
-***************************************************************************/
-static BOOL do_parameter(char *pszParmName, char *pszParmValue)
-{
- if (!bInGlobalSection && bGlobalOnly) return(True);
-
- DEBUG(3,("doing parameter %s = %s\n",pszParmName,pszParmValue));
-
- return lp_do_parameter(bInGlobalSection?-2:iServiceIndex, pszParmName, pszParmValue);
-}
-
-
-/***************************************************************************
-print a parameter of the specified type
-***************************************************************************/
-static void print_parameter(parm_type type,void *ptr, FILE *f)
-{
- switch (type)
- {
- case P_BOOL:
- fprintf(f,"%s",BOOLSTR(*(BOOL *)ptr));
- break;
-
- case P_BOOLREV:
- fprintf(f,"%s",BOOLSTR(! *(BOOL *)ptr));
- break;
-
- case P_INTEGER:
- fprintf(f,"%d",*(int *)ptr);
- break;
-
- case P_CHAR:
- fprintf(f,"%c",*(char *)ptr);
- break;
-
- case P_OCTAL:
- fprintf(f,"0%o",*(int *)ptr);
- break;
-
- case P_GSTRING:
- case P_UGSTRING:
- if ((char *)ptr)
- fprintf(f,"%s",(char *)ptr);
- break;
-
- case P_STRING:
- case P_USTRING:
- if (*(char **)ptr)
- fprintf(f,"%s",*(char **)ptr);
- break;
- }
-}
-
-
-/***************************************************************************
-print a parameter of the specified type
-***************************************************************************/
-static void parameter_string(parm_type type,void *ptr,char *s)
-{
- s[0] = 0;
-
- switch (type)
- {
- case P_BOOL:
- sprintf(s, "%s",BOOLSTR(*(BOOL *)ptr));
- break;
-
- case P_BOOLREV:
- sprintf(s, "%s",BOOLSTR(! *(BOOL *)ptr));
- break;
-
- case P_INTEGER:
- sprintf(s, "%d",*(int *)ptr);
- break;
-
- case P_CHAR:
- sprintf(s, "%c",*(char *)ptr);
- break;
-
- case P_OCTAL:
- sprintf(s, "0%o",*(int *)ptr);
- break;
-
- case P_GSTRING:
- case P_UGSTRING:
- if ((char *)ptr)
- sprintf(s, "%s",(char *)ptr);
- break;
-
- case P_STRING:
- case P_USTRING:
- if (*(char **)ptr)
- sprintf(s, "%s",*(char **)ptr);
- break;
- }
-}
-
-
-/***************************************************************************
-check if two parameters are equal
-***************************************************************************/
-static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
-{
- switch (type)
- {
- case P_BOOL:
- case P_BOOLREV:
- return(*((BOOL *)ptr1) == *((BOOL *)ptr2));
-
- case P_INTEGER:
- case P_OCTAL:
- return(*((int *)ptr1) == *((int *)ptr2));
-
- case P_CHAR:
- return(*((char *)ptr1) == *((char *)ptr2));
-
- case P_GSTRING:
- case P_UGSTRING:
- {
- char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
- if (p1 && !*p1) p1 = NULL;
- if (p2 && !*p2) p2 = NULL;
- return(p1==p2 || strequal(p1,p2));
- }
- case P_STRING:
- case P_USTRING:
- {
- char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
- if (p1 && !*p1) p1 = NULL;
- if (p2 && !*p2) p2 = NULL;
- return(p1==p2 || strequal(p1,p2));
- }
- }
- return(False);
-}
-
-/***************************************************************************
-Process a new section (service). At this stage all sections are services.
-Later we'll have special sections that permit server parameters to be set.
-Returns True on success, False on failure.
-***************************************************************************/
-static BOOL do_section(char *pszSectionName)
-{
- BOOL bRetval;
- BOOL isglobal = ((strwicmp(pszSectionName, GLOBAL_NAME) == 0) ||
- (strwicmp(pszSectionName, GLOBAL_NAME2) == 0));
- bRetval = False;
-
- /* if we were in a global section then do the local inits */
- if (bInGlobalSection && !isglobal)
- init_locals();
-
- /* if we've just struck a global section, note the fact. */
- bInGlobalSection = isglobal;
-
- /* check for multiple global sections */
- if (bInGlobalSection)
- {
- DEBUG(3,( "Processing section \"[%s]\"\n", pszSectionName));
- return(True);
- }
-
- if (!bInGlobalSection && bGlobalOnly) return(True);
-
- /* if we have a current service, tidy it up before moving on */
- bRetval = True;
-
- if (iServiceIndex >= 0)
- bRetval = service_ok(iServiceIndex);
-
- /* if all is still well, move to the next record in the services array */
- if (bRetval)
- {
- /* We put this here to avoid an odd message order if messages are */
- /* issued by the post-processing of a previous section. */
- DEBUG(2,( "Processing section \"[%s]\"\n", pszSectionName));
-
- if ((iServiceIndex=add_a_service(&sDefault,pszSectionName)) < 0)
- {
- DEBUG(0,("Failed to add a new service\n"));
- return(False);
- }
- }
-
- return (bRetval);
-}
-
-/***************************************************************************
-Display the contents of the global structure.
-***************************************************************************/
-static void dump_globals(FILE *f)
-{
- int i;
- fprintf(f, "# Global parameters\n");
-
- for (i=0;parm_table[i].label;i++)
- if (parm_table[i].class == P_GLOBAL &&
- parm_table[i].ptr &&
- (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
- {
- fprintf(f,"\t%s = ",parm_table[i].label);
- print_parameter(parm_table[i].type,parm_table[i].ptr, f);
- fprintf(f,"\n");
- }
-}
-
-/***************************************************************************
-Display the contents of a single services record.
-***************************************************************************/
-static void dump_a_service(service *pService, FILE *f)
-{
- int i;
- if (pService == &sDefault)
- fprintf(f,"\n\n# Default service parameters\n");
- else
- fprintf(f,"\n[%s]\n",pService->szService);
-
- for (i=0;parm_table[i].label;i++)
- if (parm_table[i].class == P_LOCAL &&
- parm_table[i].ptr &&
- (*parm_table[i].label != '-') &&
- (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
- {
- int pdiff = PTR_DIFF(parm_table[i].ptr,&sDefault);
-
- if (pService == &sDefault || !equal_parameter(parm_table[i].type,
- ((char *)pService) + pdiff,
- ((char *)&sDefault) + pdiff))
- {
- fprintf(f,"\t%s = ",parm_table[i].label);
- print_parameter(parm_table[i].type,
- ((char *)pService) + pdiff, f);
- fprintf(f,"\n");
- }
- }
-}
-
-
-/***************************************************************************
-return info about the next service in a service. snum==-1 gives the default
-serice and snum==-2 gives the globals
-
-return 0 when out of parameters
-***************************************************************************/
-int lp_next_parameter(int snum, int *i, char *label,
- char *value, int allparameters)
-{
- if (snum == -2) {
- /* do the globals */
- for (;parm_table[*i].label;(*i)++)
- if (parm_table[*i].class == P_GLOBAL &&
- parm_table[*i].ptr &&
- (*parm_table[*i].label != '-') &&
- ((*i) == 0 ||
- (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
- strcpy(label, parm_table[*i].label);
- parameter_string(parm_table[*i].type,
- parm_table[*i].ptr,
- value);
- (*i)++;
- return 1;
- }
- return 0;
- } else {
- service *pService = (snum==-1?&sDefault:pSERVICE(snum));
-
- for (;parm_table[*i].label;(*i)++)
- if (parm_table[*i].class == P_LOCAL &&
- parm_table[*i].ptr &&
- (*parm_table[*i].label != '-') &&
- ((*i) == 0 ||
- (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) {
- int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault);
-
- if (snum == -1 || allparameters ||
- !equal_parameter(parm_table[*i].type,
- ((char *)pService) + pdiff,
- ((char *)&sDefault) + pdiff)) {
- strcpy(label, parm_table[*i].label);
- parameter_string(parm_table[*i].type,
- ((char *)pService) + pdiff,
- value);
- (*i)++;
- return 1;
- }
- }
- }
-
- return 0;
-}
-
-
-#if 0
-/***************************************************************************
-Display the contents of a single copy structure.
-***************************************************************************/
-static void dump_copy_map(BOOL *pcopymap)
-{
- int i;
- if (!pcopymap) return;
-
- printf("\n\tNon-Copied parameters:\n");
-
- for (i=0;parm_table[i].label;i++)
- if (parm_table[i].class == P_LOCAL &&
- parm_table[i].ptr && !pcopymap[i] &&
- (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr)))
- {
- printf("\t\t%s\n",parm_table[i].label);
- }
-}
-#endif
-
-/***************************************************************************
-Return TRUE if the passed service number is within range.
-***************************************************************************/
-BOOL lp_snum_ok(int iService)
-{
- return (LP_SNUM_OK(iService) && iSERVICE(iService).bAvailable);
-}
-
-
-/***************************************************************************
-auto-load some homes and printer services
-***************************************************************************/
-static void lp_add_auto_services(char *str)
-{
- char *s;
- char *p;
- int homes = lp_servicenumber(HOMES_NAME);
- int printers = lp_servicenumber(PRINTERS_NAME);
-
- if (!str)
- return;
-
- s = strdup(str);
- if (!s) return;
-
- for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP))
- {
- char *home = get_home_dir(p);
-
- if (lp_servicenumber(p) >= 0) continue;
-
- if (home && homes >= 0)
- {
- lp_add_home(p,homes,home);
- continue;
- }
-
- if (printers >= 0 && pcap_printername_ok(p,NULL))
- lp_add_printer(p,printers);
- }
- free(s);
-}
-
-/***************************************************************************
-auto-load one printer
-***************************************************************************/
-static void lp_add_one_printer(char *name,char *comment)
-{
- int printers = lp_servicenumber(PRINTERS_NAME);
- int i;
-
- if (lp_servicenumber(name) < 0)
- {
- lp_add_printer(name,printers);
- if ((i=lp_servicenumber(name)) >= 0)
- string_set(&iSERVICE(i).comment,comment);
- }
-}
-
-
-/***************************************************************************
-auto-load printer services
-***************************************************************************/
-static void lp_add_all_printers(void)
-{
- int printers = lp_servicenumber(PRINTERS_NAME);
-
- if (printers < 0) return;
-
- pcap_printer_fn(lp_add_one_printer);
-}
-
-/***************************************************************************
-have we loaded a services file yet?
-***************************************************************************/
-BOOL lp_loaded(void)
-{
- return(bLoaded);
-}
-
-/***************************************************************************
-unload unused services
-***************************************************************************/
-void lp_killunused(BOOL (*snumused)(int ))
-{
- int i;
- for (i=0;i<iNumServices;i++)
- if (VALID(i) && (!snumused || !snumused(i)))
- {
- iSERVICE(i).valid = False;
- free_service(pSERVICE(i));
- }
-}
-
-/***************************************************************************
-Load the services array from the services file. Return True on success,
-False on failure.
-***************************************************************************/
-BOOL lp_load(char *pszFname,BOOL global_only)
-{
- pstring n2;
- BOOL bRetval;
-
- add_to_file_list(pszFname);
-
- bRetval = False;
-
- bInGlobalSection = True;
- bGlobalOnly = global_only;
-
- init_globals();
-
- pstrcpy(n2,pszFname);
- standard_sub_basic(n2);
-
- /* We get sections first, so have to start 'behind' to make up */
- iServiceIndex = -1;
- bRetval = pm_process(n2, do_section, do_parameter);
-
- /* finish up the last section */
- DEBUG(3,("pm_process() returned %s\n", BOOLSTR(bRetval)));
- if (bRetval)
- if (iServiceIndex >= 0)
- bRetval = service_ok(iServiceIndex);
-
- lp_add_auto_services(lp_auto_services());
- if (lp_load_printers())
- lp_add_all_printers();
-
- lp_add_ipc();
-
- set_default_server_announce_type();
-
- bLoaded = True;
-
- return (bRetval);
-}
-
-
-/***************************************************************************
-return the max number of services
-***************************************************************************/
-int lp_numservices(void)
-{
- return(iNumServices);
-}
-
-/***************************************************************************
-Display the contents of the services array in human-readable form.
-***************************************************************************/
-void lp_dump(FILE *f)
-{
- int iService;
-
- dump_globals(f);
-
- dump_a_service(&sDefault, f);
-
- for (iService = 0; iService < iNumServices; iService++)
- {
- if (VALID(iService))
- {
- if (iSERVICE(iService).szService[0] == '\0')
- break;
- dump_a_service(pSERVICE(iService), f);
- }
- }
-}
-
-
-/***************************************************************************
-Return the number of the service with the given name, or -1 if it doesn't
-exist. Note that this is a DIFFERENT ANIMAL from the internal function
-getservicebyname()! This works ONLY if all services have been loaded, and
-does not copy the found service.
-***************************************************************************/
-int lp_servicenumber(char *pszServiceName)
-{
- int iService;
-
- for (iService = iNumServices - 1; iService >= 0; iService--)
- if (VALID(iService) &&
- strwicmp(iSERVICE(iService).szService, pszServiceName) == 0)
- break;
-
- if (iService < 0)
- DEBUG(7,("lp_servicenumber: couldn't find %s\n",pszServiceName));
-
- return (iService);
-}
-
-/*******************************************************************
- a useful volume label function
- ******************************************************************/
-char *volume_label(int snum)
-{
- char *ret = lp_volume(snum);
- if (!*ret) return(lp_servicename(snum));
- return(ret);
-}
-
-#if 0
-/*
- * nmbd only loads the global section. There seems to be no way to
- * determine exactly is a service is printable by only looking at the
- * [global] section so for now always announce as a print server. This
- * will need looking at in the future. Jeremy (jallison@whistle.com).
- */
-/*******************************************************************
- Return true if any printer services are defined.
- ******************************************************************/
-static BOOL lp_printer_services(void)
-{
- int iService;
-
- for (iService = iNumServices - 1; iService >= 0; iService--)
- if (VALID(iService) && iSERVICE(iService).bPrint_ok)
- return True;
- return False;
-}
-#endif
-
-/*******************************************************************
- Set the server type we will announce as via nmbd.
-********************************************************************/
-static void set_default_server_announce_type()
-{
- default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
- SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
- if(lp_announce_as() == ANNOUNCE_AS_NT)
- default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
- else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
- default_server_announce |= SV_TYPE_WIN95_PLUS;
- else if(lp_announce_as() == ANNOUNCE_AS_WFW)
- default_server_announce |= SV_TYPE_WFW;
- default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
-/*
- * nmbd only loads the [global] section. There seems to be no way to
- * determine exactly if any service is printable by only looking at the
- * [global] section so for now always announce as a print server. This
- * will need looking at in the future. Jeremy (jallison@whistle.com).
- */
-#if 0
- default_server_announce |= (lp_printer_services() ? SV_TYPE_PRINTQ_SERVER : 0);
-#endif
-}
-
-
-/*******************************************************************
-rename a service
-********************************************************************/
-void lp_rename_service(int snum, char *new_name)
-{
- string_set(&pSERVICE(snum)->szService, new_name);
-}
-
-/*******************************************************************
-remove a service
-********************************************************************/
-void lp_remove_service(int snum)
-{
- pSERVICE(snum)->valid = False;
-}
-
-/*******************************************************************
-copy a service
-********************************************************************/
-void lp_copy_service(int snum, char *new_name)
-{
- char *oldname = lp_servicename(snum);
- do_section(new_name);
- if (snum >= 0) {
- snum = lp_servicenumber(new_name);
- if (snum >= 0)
- lp_do_parameter(snum, "copy", oldname);
- }
-}
-
-
-/*******************************************************************
- Get the default server type we will announce as via nmbd.
-********************************************************************/
-int lp_default_server_announce(void)
-{
- return default_server_announce;
-}
-
-/*******************************************************************
- Split the announce version into major and minor numbers.
-********************************************************************/
-int lp_major_announce_version(void)
-{
- static BOOL got_major = False;
- static int major_version = DEFAULT_MAJOR_VERSION;
- char *vers;
- char *p;
-
- if(got_major)
- return major_version;
-
- got_major = True;
- if((vers = lp_announce_version()) == NULL)
- return major_version;
-
- if((p = strchr(vers, '.')) == 0)
- return major_version;
-
- *p = '\0';
- major_version = atoi(vers);
- return major_version;
-}
-
-int lp_minor_announce_version(void)
-{
- static BOOL got_minor = False;
- static int minor_version = DEFAULT_MINOR_VERSION;
- char *vers;
- char *p;
-
- if(got_minor)
- return minor_version;
-
- got_minor = True;
- if((vers = lp_announce_version()) == NULL)
- return minor_version;
-
- if((p = strchr(vers, '.')) == 0)
- return minor_version;
-
- p++;
- minor_version = atoi(p);
- return minor_version;
-}
-
diff --git a/source/param/params.c b/source/param/params.c
deleted file mode 100644
index 4d1c191b479..00000000000
--- a/source/param/params.c
+++ /dev/null
@@ -1,566 +0,0 @@
-/* -------------------------------------------------------------------------- **
- * Microsoft Network Services for Unix, AKA., Andrew Tridgell's SAMBA.
- *
- * This module Copyright (C) 1990, 1991, 1992, 1993, 1994 Karl Auer
- *
- * Rewritten almost completely by Christopher R. Hertel
- * at the University of Minnesota, September, 1997.
- * This module Copyright (C) 1997 by the University of Minnesota
- * -------------------------------------------------------------------------- **
- *
- * 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.
- *
- * -------------------------------------------------------------------------- **
- *
- * Module name: params
- *
- * -------------------------------------------------------------------------- **
- *
- * This module performs lexical analysis and initial parsing of a
- * Windows-like parameter file. It recognizes and handles four token
- * types: section-name, parameter-name, parameter-value, and
- * end-of-file. Comments and line continuation are handled
- * internally.
- *
- * The entry point to the module is function pm_process(). This
- * function opens the source file, calls the Parse() function to parse
- * the input, and then closes the file when either the EOF is reached
- * or a fatal error is encountered.
- *
- * A sample parameter file might look like this:
- *
- * [section one]
- * parameter one = value string
- * parameter two = another value
- * [section two]
- * new parameter = some value or t'other
- *
- * The parameter file is divided into sections by section headers:
- * section names enclosed in square brackets (eg. [section one]).
- * Each section contains parameter lines, each of which consist of a
- * parameter name and value delimited by an equal sign. Roughly, the
- * syntax is:
- *
- * <file> :== { <section> } EOF
- *
- * <section> :== <section header> { <parameter line> }
- *
- * <section header> :== '[' NAME ']'
- *
- * <parameter line> :== NAME '=' VALUE '\n'
- *
- * Blank lines and comment lines are ignored. Comment lines are lines
- * beginning with either a semicolon (';') or a pound sign ('#').
- *
- * All whitespace in section names and parameter names is compressed
- * to single spaces. Leading and trailing whitespace is stipped from
- * both names and values.
- *
- * Only the first equals sign in a parameter line is significant.
- * Parameter values may contain equals signs, square brackets and
- * semicolons. Internal whitespace is retained in parameter values,
- * with the exception of the '\r' character, which is stripped for
- * historic reasons. Parameter names may not start with a left square
- * bracket, an equal sign, a pound sign, or a semicolon, because these
- * are used to identify other tokens.
- *
- * -------------------------------------------------------------------------- **
- */
-
-#include "includes.h"
-
-/* -------------------------------------------------------------------------- **
- * Constants...
- */
-
-#define BUFR_INC 1024
-
-
-/* -------------------------------------------------------------------------- **
- * Variables...
- *
- * DEBUGLEVEL - The ubiquitous DEBUGLEVEL. This determines which DEBUG()
- * messages will be produced.
- * bufr - pointer to a global buffer. This is probably a kludge,
- * but it was the nicest kludge I could think of (for now).
- * bSize - The size of the global buffer <bufr>.
- */
-
-extern int DEBUGLEVEL;
-
-static char *bufr = NULL;
-static int bSize = 0;
-
-/* -------------------------------------------------------------------------- **
- * Functions...
- */
-
-static int EatWhitespace( FILE *InFile )
- /* ------------------------------------------------------------------------ **
- * Scan past whitespace (see ctype(3C)) and return the first non-whitespace
- * character, or newline, or EOF.
- *
- * Input: InFile - Input source.
- *
- * Output: The next non-whitespace character in the input stream.
- *
- * Notes: Because the config files use a line-oriented grammar, we
- * explicitly exclude the newline character from the list of
- * whitespace characters.
- * - Note that both EOF (-1) and the nul character ('\0') are
- * considered end-of-file markers.
- *
- * ------------------------------------------------------------------------ **
- */
- {
- int c;
-
- for( c = getc( InFile ); isspace( c ) && ('\n' != c); c = getc( InFile ) )
- ;
- return( c );
- } /* EatWhitespace */
-
-static int EatComment( FILE *InFile )
- /* ------------------------------------------------------------------------ **
- * Scan to the end of a comment.
- *
- * Input: InFile - Input source.
- *
- * Output: The character that marks the end of the comment. Normally,
- * this will be a newline, but it *might* be an EOF.
- *
- * Notes: Because the config files use a line-oriented grammar, we
- * explicitly exclude the newline character from the list of
- * whitespace characters.
- * - Note that both EOF (-1) and the nul character ('\0') are
- * considered end-of-file markers.
- *
- * ------------------------------------------------------------------------ **
- */
- {
- int c;
-
- for( c = getc( InFile ); ('\n'!=c) && (EOF!=c) && (c>0); c = getc( InFile ) )
- ;
- return( c );
- } /* EatComment */
-
-static int Continuation( char *line, int pos )
- /* ------------------------------------------------------------------------ **
- * Scan backards within a string to discover if the last non-whitespace
- * character is a line-continuation character ('\\').
- *
- * Input: line - A pointer to a buffer containing the string to be
- * scanned.
- * pos - This is taken to be the offset of the end of the
- * string. This position is *not* scanned.
- *
- * Output: The offset of the '\\' character if it was found, or -1 to
- * indicate that it was not.
- *
- * ------------------------------------------------------------------------ **
- */
- {
- pos--;
- while( (pos >= 0) && isspace(line[pos]) )
- pos--;
-
- return( ((pos >= 0) && ('\\' == line[pos])) ? pos : -1 );
- } /* Continuation */
-
-
-static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
- /* ------------------------------------------------------------------------ **
- * Scan a section name, and pass the name to function sfunc().
- *
- * Input: InFile - Input source.
- * sfunc - Pointer to the function to be called if the section
- * name is successfully read.
- *
- * Output: True if the section name was read and True was returned from
- * <sfunc>. False if <sfunc> failed or if a lexical error was
- * encountered.
- *
- * ------------------------------------------------------------------------ **
- */
- {
- int c;
- int i;
- int end;
- char *func = "params.c:Section() -";
-
- i = 0; /* <i> is the offset of the next free byte in bufr[] and */
- end = 0; /* <end> is the current "end of string" offset. In most */
- /* cases these will be the same, but if the last */
- /* character written to bufr[] is a space, then <end> */
- /* will be one less than <i>. */
-
- c = EatWhitespace( InFile ); /* We've already got the '['. Scan */
- /* past initial white space. */
-
- while( (EOF != c) && (c > 0) )
- {
-
- /* Check that the buffer is big enough for the next character. */
- if( i > (bSize - 2) )
- {
- bSize += BUFR_INC;
- bufr = Realloc( bufr, bSize );
- if( NULL == bufr )
- {
- DEBUG(0, ("%s Memory re-allocation failure.", func) );
- return( False );
- }
- }
-
- /* Handle a single character. */
- switch( c )
- {
- case ']': /* Found the closing bracket. */
- bufr[end] = '\0';
- if( 0 == end ) /* Don't allow an empty name. */
- {
- DEBUG(0, ("%s Empty section name in configuration file.\n", func ));
- return( False );
- }
- if( !sfunc( bufr ) ) /* Got a valid name. Deal with it. */
- return( False );
- (void)EatComment( InFile ); /* Finish off the line. */
- return( True );
-
- case '\n': /* Got newline before closing ']'. */
- i = Continuation( bufr, i ); /* Check for line continuation. */
- if( i < 0 )
- {
- bufr[end] = '\0';
- DEBUG(0, ("%s Badly formed line in configuration file: %s\n",
- func, bufr ));
- return( False );
- }
- end = ( (i > 0) && (' ' == bufr[i - 1]) ) ? (i - 1) : (i);
- c = getc( InFile ); /* Continue with next line. */
- break;
-
- default: /* All else are a valid name chars. */
- if( isspace( c ) ) /* One space per whitespace region. */
- {
- bufr[end] = ' ';
- i = end + 1;
- c = EatWhitespace( InFile );
- }
- else /* All others copy verbatim. */
- {
- bufr[i++] = c;
- end = i;
- c = getc( InFile );
- }
- }
- }
-
- /* We arrive here if we've met the EOF before the closing bracket. */
- DEBUG(0, ("%s Unexpected EOF in the configuration file: %s\n", func, bufr ));
- return( False );
- } /* Section */
-
-static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c )
- /* ------------------------------------------------------------------------ **
- * Scan a parameter name and value, and pass these two fields to pfunc().
- *
- * Input: InFile - The input source.
- * pfunc - A pointer to the function that will be called to
- * process the parameter, once it has been scanned.
- * c - The first character of the parameter name, which
- * would have been read by Parse(). Unlike a comment
- * line or a section header, there is no lead-in
- * character that can be discarded.
- *
- * Output: True if the parameter name and value were scanned and processed
- * successfully, else False.
- *
- * Notes: This function is in two parts. The first loop scans the
- * parameter name. Internal whitespace is compressed, and an
- * equal sign (=) terminates the token. Leading and trailing
- * whitespace is discarded. The second loop scans the parameter
- * value. When both have been successfully identified, they are
- * passed to pfunc() for processing.
- *
- * ------------------------------------------------------------------------ **
- */
- {
- int i = 0; /* Position within bufr. */
- int end = 0; /* bufr[end] is current end-of-string. */
- int vstart = 0; /* Starting position of the parameter value. */
- char *func = "params.c:Parameter() -";
-
- /* Read the parameter name. */
- while( 0 == vstart ) /* Loop until we've found the start of the value. */
- {
-
- if( i > (bSize - 2) ) /* Ensure there's space for next char. */
- {
- bSize += BUFR_INC;
- bufr = Realloc( bufr, bSize );
- if( NULL == bufr )
- {
- DEBUG(0, ("%s Memory re-allocation failure.", func) );
- return( False );
- }
- }
-
- switch( c )
- {
- case '=': /* Equal sign marks end of param name. */
- if( 0 == end ) /* Don't allow an empty name. */
- {
- DEBUG(0, ("%s Invalid parameter name in config. file.\n", func ));
- return( False );
- }
- bufr[end++] = '\0'; /* Mark end of string & advance. */
- i = end; /* New string starts here. */
- vstart = end; /* New string is parameter value. */
- bufr[i] = '\0'; /* New string is nul, for now. */
- break;
-
- case '\n': /* Find continuation char, else error. */
- i = Continuation( bufr, i );
- if( i < 0 )
- {
- bufr[end] = '\0';
- DEBUG(1,("%s Ignoring badly formed line in configuration file: %s\n",
- func, bufr ));
- return( True );
- }
- end = ( (i > 0) && (' ' == bufr[i - 1]) ) ? (i - 1) : (i);
- c = getc( InFile ); /* Read past eoln. */
- break;
-
- case '\0': /* Shouldn't have EOF within param name. */
- case EOF:
- bufr[i] = '\0';
- DEBUG(1,("%s Unexpected end-of-file at: %s\n", func, bufr ));
- return( True );
-
- default:
- if( isspace( c ) ) /* One ' ' per whitespace region. */
- {
- bufr[end] = ' ';
- i = end + 1;
- c = EatWhitespace( InFile );
- }
- else /* All others verbatim. */
- {
- bufr[i++] = c;
- end = i;
- c = getc( InFile );
- }
- }
- }
-
- /* Now parse the value. */
- c = EatWhitespace( InFile ); /* Again, trim leading whitespace. */
- while( (EOF !=c) && (c > 0) )
- {
-
- if( i > (bSize - 2) ) /* Make sure there's enough room. */
- {
- bSize += BUFR_INC;
- bufr = Realloc( bufr, bSize );
- if( NULL == bufr )
- {
- DEBUG(0, ("%s Memory re-allocation failure.", func) );
- return( False );
- }
- }
-
- switch( c )
- {
- case '\r': /* Explicitly remove '\r' because the older */
- c = getc( InFile ); /* version called fgets_slash() which also */
- break; /* removes them. */
-
- case '\n': /* Marks end of value unless there's a '\'. */
- i = Continuation( bufr, i );
- if( i < 0 )
- c = 0;
- else
- {
- for( end = i; (end >= 0) && isspace(bufr[end]); end-- )
- ;
- c = getc( InFile );
- }
- break;
-
- default: /* All others verbatim. Note that spaces do */
- bufr[i++] = c; /* not advance <end>. This allows trimming */
- if( !isspace( c ) ) /* of whitespace at the end of the line. */
- end = i;
- c = getc( InFile );
- break;
- }
- }
- bufr[end] = '\0'; /* End of value. */
-
- return( pfunc( bufr, &bufr[vstart] ) ); /* Pass name & value to pfunc(). */
- } /* Parameter */
-
-static BOOL Parse( FILE *InFile,
- BOOL (*sfunc)(char *),
- BOOL (*pfunc)(char *, char *) )
- /* ------------------------------------------------------------------------ **
- * Scan & parse the input.
- *
- * Input: InFile - Input source.
- * sfunc - Function to be called when a section name is scanned.
- * See Section().
- * pfunc - Function to be called when a parameter is scanned.
- * See Parameter().
- *
- * Output: True if the file was successfully scanned, else False.
- *
- * Notes: The input can be viewed in terms of 'lines'. There are four
- * types of lines:
- * Blank - May contain whitespace, otherwise empty.
- * Comment - First non-whitespace character is a ';' or '#'.
- * The remainder of the line is ignored.
- * Section - First non-whitespace character is a '['.
- * Parameter - The default case.
- *
- * ------------------------------------------------------------------------ **
- */
- {
- int c;
-
- c = EatWhitespace( InFile );
- while( (EOF != c) && (c > 0) )
- {
- switch( c )
- {
- case '\n': /* Blank line. */
- c = EatWhitespace( InFile );
- break;
-
- case ';': /* Comment line. */
- case '#':
- c = EatComment( InFile );
- break;
-
- case '[': /* Section Header. */
- if( !Section( InFile, sfunc ) )
- return( False );
- c = EatWhitespace( InFile );
- break;
-
- case '\\': /* Bogus backslash. */
- c = EatWhitespace( InFile );
- break;
-
- default: /* Parameter line. */
- if( !Parameter( InFile, pfunc, c ) )
- return( False );
- c = EatWhitespace( InFile );
- break;
- }
- }
- return( True );
- } /* Parse */
-
-static FILE *OpenConfFile( char *FileName )
- /* ------------------------------------------------------------------------ **
- * Open a configuration file.
- *
- * Input: FileName - The pathname of the config file to be opened.
- *
- * Output: A pointer of type (FILE *) to the opened file, or NULL if the
- * file could not be opened.
- *
- * ------------------------------------------------------------------------ **
- */
- {
- FILE *OpenedFile;
- char *func = "params.c:OpenConfFile() -";
-
- if( NULL == FileName || 0 == *FileName )
- {
- DEBUG( 0, ("%s No configuration filename specified.\n", func) );
- return( NULL );
- }
-
- OpenedFile = fopen( FileName, "r" );
- if( NULL == OpenedFile )
- {
- DEBUG( 0,
- ("%s Unable to open configuration file \"%s\":\n\t%s\n",
- func, FileName, strerror(errno)) );
- }
-
- return( OpenedFile );
- } /* OpenConfFile */
-
-BOOL pm_process( char *FileName,
- BOOL (*sfunc)(char *),
- BOOL (*pfunc)(char *, char *) )
- /* ------------------------------------------------------------------------ **
- * Process the named parameter file.
- *
- * Input: FileName - The pathname of the parameter file to be opened.
- * sfunc - A pointer to a function that will be called when
- * a section name is discovered.
- * pfunc - A pointer to a function that will be called when
- * a parameter name and value are discovered.
- *
- * Output: TRUE if the file was successfully parsed, else FALSE.
- *
- * ------------------------------------------------------------------------ **
- */
- {
- int result;
- FILE *InFile;
- char *func = "params.c:pm_process() -";
-
- InFile = OpenConfFile( FileName ); /* Open the config file. */
- if( NULL == InFile )
- return( False );
-
- DEBUG( 3, ("%s Processing configuration file \"%s\"\n", func, FileName) );
-
- if( NULL != bufr ) /* If we already have a buffer */
- result = Parse( InFile, sfunc, pfunc ); /* (recursive call), then just */
- /* use it. */
-
- else /* If we don't have a buffer */
- { /* allocate one, then parse, */
- bSize = BUFR_INC; /* then free. */
- bufr = (char *)malloc( bSize );
- if( NULL == bufr )
- {
- DEBUG(0,("%s memory allocation failure.\n", func));
- return( False );
- }
- result = Parse( InFile, sfunc, pfunc );
- free( bufr );
- bufr = NULL;
- bSize = 0;
- }
-
- if( !result ) /* Generic failure. */
- {
- DEBUG(0,("%s Failed. Error returned from params.c:parse().\n", func));
- return( False );
- }
-
- return( True ); /* Generic success. */
- } /* pm_process */
-
-/* -------------------------------------------------------------------------- */
diff --git a/source/passdb/smbpass.c b/source/passdb/smbpass.c
deleted file mode 100644
index 441ab94ffbb..00000000000
--- a/source/passdb/smbpass.c
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
- * Copyright (C) Andrew Tridgell 1992-1997 Modified by Jeremy Allison 1995.
- *
- * This program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 675
- * Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "includes.h"
-
-extern int DEBUGLEVEL;
-
-int gotalarm;
-
-void
-gotalarm_sig()
-{
- gotalarm = 1;
-}
-
-int
-do_pw_lock(int fd, int waitsecs, int type)
-{
- struct flock lock;
- int ret;
-
- gotalarm = 0;
- signal(SIGALRM, SIGNAL_CAST gotalarm_sig);
-
- lock.l_type = type;
- lock.l_whence = SEEK_SET;
- lock.l_start = 0;
- lock.l_len = 1;
- lock.l_pid = 0;
-
- alarm(5);
- ret = fcntl(fd, F_SETLKW, &lock);
- alarm(0);
- signal(SIGALRM, SIGNAL_CAST SIG_DFL);
-
- if (gotalarm) {
- DEBUG(0, ("do_pw_lock: failed to %s SMB passwd file.\n",
- type == F_UNLCK ? "unlock" : "lock"));
- return -1;
- }
- return ret;
-}
-
-int pw_file_lock(char *name, int type, int secs)
-{
- int fd = open(name, O_RDWR | O_CREAT, 0600);
- if (fd < 0)
- return (-1);
- if (do_pw_lock(fd, secs, type)) {
- close(fd);
- return -1;
- }
- return fd;
-}
-
-int pw_file_unlock(int fd)
-{
- do_pw_lock(fd, 5, F_UNLCK);
- return close(fd);
-}
-
-/*
- * Routine to get the next 32 hex characters and turn them
- * into a 16 byte array.
- */
-
-static int gethexpwd(char *p, char *pwd)
-{
- int i;
- unsigned char lonybble, hinybble;
- char *hexchars = "0123456789ABCDEF";
- char *p1, *p2;
-
- for (i = 0; i < 32; i += 2) {
- hinybble = toupper(p[i]);
- lonybble = toupper(p[i + 1]);
-
- p1 = strchr(hexchars, hinybble);
- p2 = strchr(hexchars, lonybble);
- if (!p1 || !p2)
- return (False);
- hinybble = PTR_DIFF(p1, hexchars);
- lonybble = PTR_DIFF(p2, hexchars);
-
- pwd[i / 2] = (hinybble << 4) | lonybble;
- }
- return (True);
-}
-
-/*
- * Routine to search the smbpasswd file for an entry matching the username.
- */
-struct smb_passwd *get_smbpwnam(char *name)
-{
- /* Static buffers we will return. */
- static struct smb_passwd pw_buf;
- static pstring user_name;
- static unsigned char smbpwd[16];
- static unsigned char smbntpwd[16];
- char linebuf[256];
- char readbuf[16 * 1024];
- unsigned char c;
- unsigned char *p;
- long uidval;
- long linebuf_len;
- FILE *fp;
- int lockfd;
- char *pfile = lp_smb_passwd_file();
-
- if (!*pfile) {
- DEBUG(0, ("No SMB password file set\n"));
- return (NULL);
- }
- DEBUG(10, ("get_smbpwnam: opening file %s\n", pfile));
-
- fp = fopen(pfile, "r");
-
- if (fp == NULL) {
- DEBUG(0, ("get_smbpwnam: unable to open file %s\n", pfile));
- return NULL;
- }
- /* Set a 16k buffer to do more efficient reads */
- setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
-
- if ((lockfd = pw_file_lock(pfile, F_RDLCK, 5)) < 0) {
- DEBUG(0, ("get_smbpwnam: unable to lock file %s\n", pfile));
- fclose(fp);
- return NULL;
- }
- /* make sure it is only rw by the owner */
- chmod(pfile, 0600);
-
- /* We have a read lock on the file. */
- /*
- * Scan the file, a line at a time and check if the name matches.
- */
- while (!feof(fp)) {
- linebuf[0] = '\0';
-
- fgets(linebuf, 256, fp);
- if (ferror(fp)) {
- fclose(fp);
- pw_file_unlock(lockfd);
- return NULL;
- }
- /*
- * Check if the string is terminated with a newline - if not
- * then we must keep reading and discard until we get one.
- */
- linebuf_len = strlen(linebuf);
- if (linebuf[linebuf_len - 1] != '\n') {
- c = '\0';
- while (!ferror(fp) && !feof(fp)) {
- c = fgetc(fp);
- if (c == '\n')
- break;
- }
- } else
- linebuf[linebuf_len - 1] = '\0';
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100, ("get_smbpwnam: got line |%s|\n", linebuf));
-#endif
- if ((linebuf[0] == 0) && feof(fp)) {
- DEBUG(4, ("get_smbpwnam: end of file reached\n"));
- break;
- }
- /*
- * The line we have should be of the form :-
- *
- * username:uid:[32hex bytes]:....other flags presently
- * ignored....
- *
- * or,
- *
- * username:uid:[32hex bytes]:[32hex bytes]:....ignored....
- *
- * if Windows NT compatible passwords are also present.
- */
-
- if (linebuf[0] == '#' || linebuf[0] == '\0') {
- DEBUG(6, ("get_smbpwnam: skipping comment or blank line\n"));
- continue;
- }
- p = (unsigned char *) strchr(linebuf, ':');
- if (p == NULL) {
- DEBUG(0, ("get_smbpwnam: malformed password entry (no :)\n"));
- continue;
- }
- /*
- * As 256 is shorter than a pstring we don't need to check
- * length here - if this ever changes....
- */
- strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
- user_name[PTR_DIFF(p, linebuf)] = '\0';
- if (!strequal(user_name, name))
- continue;
-
- /* User name matches - get uid and password */
- p++; /* Go past ':' */
- if (!isdigit(*p)) {
- DEBUG(0, ("get_smbpwnam: malformed password entry (uid not number)\n"));
- fclose(fp);
- pw_file_unlock(lockfd);
- return NULL;
- }
- uidval = atoi((char *) p);
- while (*p && isdigit(*p))
- p++;
- if (*p != ':') {
- DEBUG(0, ("get_smbpwnam: malformed password entry (no : after uid)\n"));
- fclose(fp);
- pw_file_unlock(lockfd);
- return NULL;
- }
- /*
- * Now get the password value - this should be 32 hex digits
- * which are the ascii representations of a 16 byte string.
- * Get two at a time and put them into the password.
- */
- p++;
- if (*p == '*' || *p == 'X') {
- /* Password deliberately invalid - end here. */
- DEBUG(10, ("get_smbpwnam: entry invalidated for user %s\n", user_name));
- fclose(fp);
- pw_file_unlock(lockfd);
- return NULL;
- }
- if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
- DEBUG(0, ("get_smbpwnam: malformed password entry (passwd too short)\n"));
- fclose(fp);
- pw_file_unlock(lockfd);
- return (False);
- }
- if (p[32] != ':') {
- DEBUG(0, ("get_smbpwnam: malformed password entry (no terminating :)\n"));
- fclose(fp);
- pw_file_unlock(lockfd);
- return NULL;
- }
- if (!strncasecmp((char *) p, "NO PASSWORD", 11)) {
- pw_buf.smb_passwd = NULL;
- } else {
- if(!gethexpwd((char *)p,(char *)smbpwd)) {
- DEBUG(0, ("Malformed Lanman password entry (non hex chars)\n"));
- fclose(fp);
- pw_file_unlock(lockfd);
- return NULL;
- }
- pw_buf.smb_passwd = smbpwd;
- }
- pw_buf.smb_name = user_name;
- pw_buf.smb_userid = uidval;
- pw_buf.smb_nt_passwd = NULL;
-
- /* Now check if the NT compatible password is
- available. */
- p += 33; /* Move to the first character of the line after
- the lanman password. */
- if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
- if (*p != '*' && *p != 'X') {
- if(gethexpwd((char *)p,(char *)smbntpwd))
- pw_buf.smb_nt_passwd = smbntpwd;
- }
- }
-
- fclose(fp);
- pw_file_unlock(lockfd);
- DEBUG(5, ("get_smbpwname: returning passwd entry for user %s, uid %d\n",
- user_name, uidval));
- return &pw_buf;
- }
-
- fclose(fp);
- pw_file_unlock(lockfd);
- return NULL;
-}
diff --git a/source/printing/pcap.c b/source/printing/pcap.c
deleted file mode 100644
index 65195ab1af6..00000000000
--- a/source/printing/pcap.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- printcap parsing
- Copyright (C) Karl Auer 1993-1997
-
- Re-working by Martin Kiff, 1994
-
- Re-written again by Andrew Tridgell
-
- 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.
-*/
-
-/*
- * Parse printcap file.
- *
- * This module does exactly one thing - it looks into the printcap file
- * and tells callers if a specified string appears as a printer name.
- *
- * The way this module looks at the printcap file is very simplistic.
- * Only the local printcap file is inspected (no searching of NIS
- * databases etc).
- *
- * There are assumed to be one or more printer names per record, held
- * as a set of sub-fields separated by vertical bar symbols ('|') in the
- * first field of the record. The field separator is assumed to be a colon
- * ':' and the record separator a newline.
- *
- * Lines ending with a backspace '\' are assumed to flag that the following
- * line is a continuation line so that a set of lines can be read as one
- * printcap entry.
- *
- * A line stating with a hash '#' is assumed to be a comment and is ignored
- * Comments are discarded before the record is strung together from the
- * set of continuation lines.
- *
- * Opening a pipe for "lpc status" and reading that would probably
- * be pretty effective. Code to do this already exists in the freely
- * distributable PCNFS server code.
- */
-
-#include "includes.h"
-
-#include "smb.h"
-
-extern int DEBUGLEVEL;
-
-#ifdef AIX
-/* ******************************************
- Extend for AIX system and qconfig file
- from 'boulard@univ-rennes1.fr
- ****************************************** */
-static int strlocate(char *xpLine,char *xpS)
-{
- int iS,iL,i,iRet;
- char *p;
- iS = strlen(xpS);
- iL = strlen(xpLine);
-
- iRet = 0;
- p = xpLine;
- while (iL >= iS)
- {
- if (strncmp(p,xpS,iS) == 0) {iRet =1;break;};
- p++;
- iL--;
- }
- /*DEBUG(3,(" strlocate %s in line '%s',ret=%d\n",xpS,xpLine,iRet));*/
-
- return(iRet);
-}
-
-
-/* ******************************************************************* */
-/* * Scan qconfig and search all virtual printer (device printer) * */
-/* ******************************************************************* */
-static void ScanQconfig_fn(char *psz,void (*fn)())
-{
- int iLg,iEtat;
- FILE *pfile;
- char *line,*p;
- pstring name,comment;
- line = NULL;
- *name = 0;
- *comment = 0;
-
- if ((pfile = fopen(psz, "r")) == NULL)
- {
- DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz));
- return;
- }
-
- iEtat = 0;
- /* scan qconfig file for searching <printername>: */
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line))
- {
- if (*line == '*' || *line == 0)
- continue;
- switch (iEtat)
- {
- case 0: /* locate an entry */
- if (*line == '\t' || *line == ' ') continue;
- if ((p=strchr(line,':')))
- {
- *p = '\0';
- p = strtok(line,":");
- if (strcmp(p,"bsh")!=0)
- {
- strcpy(name,p);
- iEtat = 1;
- continue;
- }
- }
- break;
- case 1: /* scanning device stanza */
- if (*line == '*' || *line == 0) continue;
- if (*line != '\t' && *line != ' ')
- {
- /* name is found without stanza device */
- /* probably a good printer ??? */
- fn(name,comment);
- iEtat = 0;
- continue;
- }
-
- if (strlocate(line,"backend"))
- {
- /* it's a device, not a virtual printer*/
- iEtat = 0;
- }
- else if (strlocate(line,"device"))
- {
- /* it's a good virtual printer */
- fn(name,comment);
- iEtat = 0;
- continue;
- }
- break;
- }
- }
- fclose(pfile);
-}
-
-/* Scan qconfig file and locate de printername */
-
-static BOOL ScanQconfig(char *psz,char *pszPrintername)
-{
- int iLg,iEtat;
- FILE *pfile;
- char *pName;
- char *line;
-
- pName = NULL;
- line = NULL;
- if ((pszPrintername!= NULL) && ((iLg = strlen(pszPrintername)) > 0))
- pName = malloc(iLg+10);
- if (pName == NULL)
- {
- DEBUG(0,(" Unable to allocate memory for printer %s\n",pszPrintername));
- return(False);
- }
- if ((pfile = fopen(psz, "r")) == NULL)
- {
- DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz));
- free(pName);
- return(False);
- }
- sprintf(pName,"%s:",pszPrintername);
- iLg = strlen(pName);
- /*DEBUG(3,( " Looking for entry %s\n",pName));*/
- iEtat = 0;
- /* scan qconfig file for searching <printername>: */
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line))
- {
- if (*line == '*' || *line == 0)
- continue;
- switch (iEtat)
- {
- case 0: /* scanning entry */
- if (strncmp(line,pName,iLg) == 0)
- {
- iEtat = 1;
- continue;
- }
- break;
- case 1: /* scanning device stanza */
- if (*line == '*' || *line == 0) continue;
- if (*line != '\t' && *line != ' ')
- {
- /* name is found without stanza device */
- /* probably a good printer ??? */
- free (line);
- free(pName);
- fclose(pfile);
- return(True);
- }
-
- if (strlocate(line,"backend"))
- {
- /* it's a device, not a virtual printer*/
- iEtat = 0;
- }
- else if (strlocate(line,"device"))
- {
- /* it's a good virtual printer */
- free (line);
- free(pName);
- fclose(pfile);
- return(True);
- }
- break;
- }
- }
- free (pName);
- fclose(pfile);
- return(False);
-}
-
-#endif
-/***************************************************************************
-Scan printcap file pszPrintcapname for a printer called pszPrintername.
-Return True if found, else False. Returns False on error, too, after logging
-the error at level 0. For generality, the printcap name may be passed - if
-passed as NULL, the configuration will be queried for the name.
-***************************************************************************/
-BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname)
-{
- char *line=NULL;
- char *psz;
- char *p,*q;
- FILE *pfile;
-
- if (pszPrintername == NULL || pszPrintername[0] == '\0')
- {
- DEBUG(0,( "Attempt to locate null printername! Internal error?\n"));
- return(False);
- }
-
- /* only go looking if no printcap name supplied */
- if ((psz = pszPrintcapname) == NULL || psz[0] == '\0')
- if (((psz = lp_printcapname()) == NULL) || (psz[0] == '\0'))
- {
- DEBUG(0,( "No printcap file name configured!\n"));
- return(False);
- }
-#ifdef AIX
- if (strlocate(psz,"/qconfig") != NULL)
- return(ScanQconfig(psz,pszPrintername));
-#endif
- if ((pfile = fopen(psz, "r")) == NULL)
- {
- DEBUG(0,( "Unable to open printcap file %s for read!\n", psz));
- return(False);
- }
-
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line))
- {
- if (*line == '#' || *line == 0)
- continue;
-
- /* now we have a real printer line - cut it off at the first : */
- p = strchr(line,':');
- if (p) *p = 0;
-
- /* now just check if the name is in the list */
- /* NOTE: I avoid strtok as the fn calling this one may be using it */
- for (p=line; p; p=q)
- {
- if ((q = strchr(p,'|'))) *q++ = 0;
-
- if (strequal(p,pszPrintername))
- {
- /* normalise the case */
- strcpy(pszPrintername,p);
- free(line);
- fclose(pfile);
- return(True);
- }
- p = q;
- }
- }
-
-
- fclose(pfile);
- return(False);
-}
-
-
-/***************************************************************************
-run a function on each printer name in the printcap file. The function is
-passed the primary name and the comment (if possible)
-***************************************************************************/
-void pcap_printer_fn(void (*fn)())
-{
- pstring name,comment;
- char *line;
- char *psz;
- char *p,*q;
- FILE *pfile;
-
- /* only go looking if no printcap name supplied */
- if (((psz = lp_printcapname()) == NULL) || (psz[0] == '\0'))
- {
- DEBUG(0,( "No printcap file name configured!\n"));
- return;
- }
-
-#ifdef AIX
- if (strlocate(psz,"/qconfig") != NULL)
- {
- ScanQconfig_fn(psz,fn);
- return;
- }
-#endif
- if ((pfile = fopen(psz, "r")) == NULL)
- {
- DEBUG(0,( "Unable to open printcap file %s for read!\n", psz));
- return;
- }
-
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); free(line))
- {
- if (*line == '#' || *line == 0)
- continue;
-
- /* now we have a real printer line - cut it off at the first : */
- p = strchr(line,':');
- if (p) *p = 0;
-
- /* now find the most likely printer name and comment
- this is pure guesswork, but it's better than nothing */
- *name = 0;
- *comment = 0;
- for (p=line; p; p=q)
- {
- BOOL has_punctuation;
- if ((q = strchr(p,'|'))) *q++ = 0;
-
- has_punctuation = (strchr(p,' ') || strchr(p,'(') || strchr(p,')'));
-
- if (strlen(p)>strlen(comment) && has_punctuation)
- {
- StrnCpy(comment,p,sizeof(comment)-1);
- continue;
- }
-
- if (strlen(p) <= 8 && strlen(p)>strlen(name) && !has_punctuation)
- {
- if (!*comment) pstrcpy(comment,name);
- pstrcpy(name,p);
- continue;
- }
-
- if (!strchr(comment,' ') &&
- strlen(p) > strlen(comment))
- {
- StrnCpy(comment,p,sizeof(comment)-1);
- continue;
- }
- }
-
- comment[60] = 0;
- name[8] = 0;
-
- if (*name)
- fn(name,comment);
- }
- fclose(pfile);
-}
diff --git a/source/printing/printing.c b/source/printing/printing.c
deleted file mode 100644
index 51fd3a992eb..00000000000
--- a/source/printing/printing.c
+++ /dev/null
@@ -1,1102 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- printing routines
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-
-#include "includes.h"
-extern int DEBUGLEVEL;
-extern connection_struct Connections[];
-extern files_struct Files[];
-
-static BOOL * lpq_cache_reset=NULL;
-
-static int check_lpq_cache(int snum) {
- static int lpq_caches=0;
-
- if (lpq_caches <= snum) {
- BOOL * p;
- p = (BOOL *) Realloc(lpq_cache_reset,(snum+1)*sizeof(BOOL));
- if (p) {
- lpq_cache_reset=p;
- lpq_caches = snum+1;
- }
- }
- return lpq_caches;
-}
-
-void lpq_reset(int snum)
-{
- if (check_lpq_cache(snum) > snum) lpq_cache_reset[snum]=True;
-}
-
-
-/****************************************************************************
-Build the print command in the supplied buffer. This means getting the
-print command for the service and inserting the printer name and the
-print file name. Return NULL on error, else the passed buffer pointer.
-****************************************************************************/
-static char *build_print_command(int cnum, char *command, char *syscmd, char *filename1)
-{
- int snum = SNUM(cnum);
- char *tstr;
- pstring filename;
-
- /* get the print command for the service. */
- tstr = command;
- if (!syscmd || !tstr) {
- DEBUG(0,("No print command for service `%s'\n", SERVICE(snum)));
- return (NULL);
- }
-
- /* copy the command into the buffer for extensive meddling. */
- StrnCpy(syscmd, tstr, sizeof(pstring) - 1);
-
- /* look for "%s" in the string. If there is no %s, we cannot print. */
- if (!strstr(syscmd, "%s") && !strstr(syscmd, "%f")) {
- DEBUG(2,("WARNING! No placeholder for the filename in the print command for service %s!\n", SERVICE(snum)));
- }
-
- if (strstr(syscmd,"%s")) {
- int iOffset = PTR_DIFF(strstr(syscmd, "%s"),syscmd);
-
- /* construct the full path for the filename, shouldn't be necessary unless
- the subshell causes a "cd" to be executed.
- Only use the full path if there isn't a / preceding the %s */
- if (iOffset==0 || syscmd[iOffset-1] != '/') {
- StrnCpy(filename,Connections[cnum].connectpath,sizeof(filename)-1);
- trim_string(filename,"","/");
- strcat(filename,"/");
- strcat(filename,filename1);
- }
- else
- pstrcpy(filename,filename1);
-
- string_sub(syscmd, "%s", filename);
- }
-
- string_sub(syscmd, "%f", filename1);
-
- /* Does the service have a printername? If not, make a fake and empty */
- /* printer name. That way a %p is treated sanely if no printer */
- /* name was specified to replace it. This eventuality is logged. */
- tstr = PRINTERNAME(snum);
- if (tstr == NULL || tstr[0] == '\0') {
- DEBUG(3,( "No printer name - using %s.\n", SERVICE(snum)));
- tstr = SERVICE(snum);
- }
-
- string_sub(syscmd, "%p", tstr);
-
- standard_sub(cnum,syscmd);
-
- return (syscmd);
-}
-
-
-/****************************************************************************
-print a file - called on closing the file
-****************************************************************************/
-void print_file(int fnum)
-{
- pstring syscmd;
- int cnum = Files[fnum].cnum;
- int snum=SNUM(cnum);
- char *tempstr;
-
- *syscmd = 0;
-
- if (file_size(Files[fnum].name) <= 0) {
- DEBUG(3,("Discarding null print job %s\n",Files[fnum].name));
- sys_unlink(Files[fnum].name);
- return;
- }
-
- tempstr = build_print_command(cnum, PRINTCOMMAND(snum), syscmd, Files[fnum].name);
- if (tempstr != NULL)
- {
- int ret = smbrun(syscmd,NULL,False);
- DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
- }
- else
- DEBUG(0,("Null print command?\n"));
-
- lpq_reset(snum);
-}
-
-static char *Months[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Err"};
-
-
-/*******************************************************************
-process time fields
-********************************************************************/
-static time_t EntryTime(string tok[], int ptr, int count, int minimum)
-{
- time_t jobtime,jobtime1;
-
- jobtime = time(NULL); /* default case: take current time */
- if (count >= minimum) {
- struct tm *t;
- int i, day, hour, min, sec;
- char *c;
-
- for (i=0; i<13; i++) if (!strncmp(tok[ptr], Months[i],3)) break; /* Find month */
- if (i<12) {
- t = localtime(&jobtime);
- day = atoi(tok[ptr+1]);
- c=(char *)(tok[ptr+2]);
- *(c+2)=0;
- hour = atoi(c);
- *(c+5)=0;
- min = atoi(c+3);
- if(*(c+6) != 0)sec = atoi(c+6);
- else sec=0;
-
- if ((t->tm_mon < i)||
- ((t->tm_mon == i)&&
- ((t->tm_mday < day)||
- ((t->tm_mday == day)&&
- (t->tm_hour*60+t->tm_min < hour*60+min)))))
- t->tm_year--; /* last year's print job */
-
- t->tm_mon = i;
- t->tm_mday = day;
- t->tm_hour = hour;
- t->tm_min = min;
- t->tm_sec = sec;
- jobtime1 = mktime(t);
- if (jobtime1 != (time_t)-1)
- jobtime = jobtime1;
- }
- }
- return jobtime;
-}
-
-
-/****************************************************************************
-parse a lpq line
-
-here is an example of lpq output under bsd
-
-Warning: no daemon present
-Rank Owner Job Files Total Size
-1st tridge 148 README 8096 bytes
-
-here is an example of lpq output under osf/1
-
-Warning: no daemon present
-Rank Pri Owner Job Files Total Size
-1st 0 tridge 148 README 8096 bytes
-****************************************************************************/
-static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first)
-{
-#ifdef OSF1
-#define RANKTOK 0
-#define PRIOTOK 1
-#define USERTOK 2
-#define JOBTOK 3
-#define FILETOK 4
-#define TOTALTOK 5
-#define NTOK 6
-#else /* OSF1 */
-#define RANKTOK 0
-#define USERTOK 1
-#define JOBTOK 2
-#define FILETOK 3
-#define TOTALTOK 4
-#define NTOK 5
-#endif /* OSF1 */
-
- string tok[NTOK];
- int count=0;
-
-#ifdef OSF1
- int length;
- length = strlen(line);
- if (line[length-3] == ':')
- return(False);
-#endif /* OSF1 */
-
- /* handle the case of "(standard input)" as a filename */
- string_sub(line,"standard input","STDIN");
- string_sub(line,"(","\"");
- string_sub(line,")","\"");
-
- for (count=0; count<NTOK && next_token(&line,tok[count],NULL); count++) ;
-
- /* we must get NTOK tokens */
- if (count < NTOK)
- return(False);
-
- /* the Job and Total columns must be integer */
- if (!isdigit(*tok[JOBTOK]) || !isdigit(*tok[TOTALTOK])) return(False);
-
- /* if the fname contains a space then use STDIN */
- if (strchr(tok[FILETOK],' '))
- strcpy(tok[FILETOK],"STDIN");
-
- /* only take the last part of the filename */
- {
- string tmp;
- char *p = strrchr(tok[FILETOK],'/');
- if (p)
- {
- strcpy(tmp,p+1);
- fstrcpy(tok[FILETOK],tmp);
- }
- }
-
-
- buf->job = atoi(tok[JOBTOK]);
- buf->size = atoi(tok[TOTALTOK]);
- buf->status = strequal(tok[RANKTOK],"active")?LPQ_PRINTING:LPQ_QUEUED;
- buf->time = time(NULL);
- StrnCpy(buf->user,tok[USERTOK],sizeof(buf->user)-1);
- StrnCpy(buf->file,tok[FILETOK],sizeof(buf->file)-1);
-#ifdef PRIOTOK
- buf->priority = atoi(tok[PRIOTOK]);
-#else
- buf->priority = 1;
-#endif
- return(True);
-}
-
-/*
-<magnus@hum.auc.dk>
-LPRng_time modifies the current date by inserting the hour and minute from
-the lpq output. The lpq time looks like "23:15:07"
-*/
-static time_t LPRng_time(string tok[],int pos)
-{
- time_t jobtime;
- struct tm *t;
- char tmp_time[9];
-
- jobtime = time(NULL); /* default case: take current time */
- t = localtime(&jobtime);
- t->tm_hour = atoi(tok[pos]);
- StrnCpy(tmp_time,tok[pos],sizeof(tmp_time));
- t->tm_min = atoi(tmp_time+3);
- t->tm_sec = atoi(tmp_time+6);
- jobtime = mktime(t);
-
- return jobtime;
-}
-
-
-/****************************************************************************
- parse a lpq line
- <magnus@hum.auc.dk>
- Most of the code is directly reused from parse_lpq_bsd()
-
-here are two examples of lpq output under lprng (LPRng-2.3.0)
-
-Printer: humprn@hum-fak
- Queue: 1 printable job
- Server: pid 4840 active, Unspooler: pid 4841 active
- Status: job 'cfA659hum-fak', closing device at Fri Jun 21 10:10:21 1996
- Rank Owner Class Job Files Size Time
-active magnus@hum-fak A 659 /var/spool/smb/Notesblok-ikke-na4024 10:03:31
-
-Printer: humprn@hum-fak (printing disabled)
- Queue: 1 printable job
- Warning: no server present
- Status: finished operations at Fri Jun 21 10:10:32 1996
- Rank Owner Class Job Files Size Time
-1 magnus@hum-fak A 387 /var/spool/smb/netbudget.xls 21230 10:50:53
-
-****************************************************************************/
-static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first)
-{
-#define LPRNG_RANKTOK 0
-#define LPRNG_USERTOK 1
-#define LPRNG_PRIOTOK 2
-#define LPRNG_JOBTOK 3
-#define LPRNG_FILETOK 4
-#define LPRNG_TOTALTOK 5
-#define LPRNG_TIMETOK 6
-#define LPRNG_NTOK 7
-
-/****************************************************************************
-From lpd_status.c in LPRng source.
-0 1 2 3 4 5 6 7
-12345678901234567890123456789012345678901234567890123456789012345678901234
-" Rank Owner Class Job Files Size Time"
- plp_snprintf( msg, sizeof(msg), "%-6s %-19s %c %03d %-32s",
- number, line, priority, cfp->number, error );
- plp_snprintf( msg + len, sizeof(msg)-len, "%4d",
- cfp->jobsize );
- plp_snprintf( msg+len, sizeof(msg)-len, " %s",
- Time_str( 1, cfp->statb.st_ctime ) );
-****************************************************************************/
- /* The following define's are to be able to adjust the values if the
-LPRng source changes. This is from version 2.3.0. Magnus */
-#define SPACE_W 1
-#define RANK_W 6
-#define OWNER_W 19
-#define CLASS_W 1
-#define JOB_W 3
-#define FILE_W 32
-/* The JOBSIZE_W is too small for big jobs, so time is pushed to the right */
-#define JOBSIZE_W 4
-
-#define RANK_POS 0
-#define OWNER_POS RANK_POS+RANK_W+SPACE_W
-#define CLASS_POS OWNER_POS+OWNER_W+SPACE_W
-#define JOB_POS CLASS_POS+CLASS_W+SPACE_W
-#define FILE_POS JOB_POS+JOB_W+SPACE_W
-#define JOBSIZE_POS FILE_POS+FILE_W
-
-
- string tok[LPRNG_NTOK];
- int count=0;
-
-/*
-Need to insert one space in front of the size, to be able to use
-next_token() unchanged. I would have liked to be able to insert a
-space instead, to prevent losing that one char, but perl has spoiled
-me :-\ So I did it the easiest way.
-
-HINT: Use as short a path as possible for the samba spool directory.
-A long spool-path will just waste significant chars of the file name.
-*/
-
- line[JOBSIZE_POS-1]=' ';
-
- /* handle the case of "(stdin)" as a filename */
- string_sub(line,"stdin","STDIN");
- string_sub(line,"(","\"");
- string_sub(line,")","\"");
-
- for (count=0; count<LPRNG_NTOK && next_token(&line,tok[count],NULL); count++) ;
-
- /* we must get LPRNG_NTOK tokens */
- if (count < LPRNG_NTOK)
- return(False);
-
- /* the Job and Total columns must be integer */
- if (!isdigit(*tok[LPRNG_JOBTOK]) || !isdigit(*tok[LPRNG_TOTALTOK])) return(False);
-
- /* if the fname contains a space then use STDIN */
- /* I do not understand how this would be possible. Magnus. */
- if (strchr(tok[LPRNG_FILETOK],' '))
- strcpy(tok[LPRNG_FILETOK],"STDIN");
-
- /* only take the last part of the filename */
- {
- string tmp;
- char *p = strrchr(tok[LPRNG_FILETOK],'/');
- if (p)
- {
- fstrcpy(tmp,p+1);
- fstrcpy(tok[LPRNG_FILETOK],tmp);
- }
- }
-
-
- buf->job = atoi(tok[LPRNG_JOBTOK]);
- buf->size = atoi(tok[LPRNG_TOTALTOK]);
- buf->status = strequal(tok[LPRNG_RANKTOK],"active")?LPQ_PRINTING:LPQ_QUEUED;
- /* buf->time = time(NULL); */
- buf->time = LPRng_time(tok,LPRNG_TIMETOK);
-DEBUG(3,("Time reported for job %d is %s", buf->job, ctime(&buf->time)));
- StrnCpy(buf->user,tok[LPRNG_USERTOK],sizeof(buf->user)-1);
- StrnCpy(buf->file,tok[LPRNG_FILETOK],sizeof(buf->file)-1);
-#ifdef LPRNG_PRIOTOK
- /* Here I try to map the CLASS char to a number, but the number
- is never shown in Print Manager under NT anyway... Magnus. */
- buf->priority = atoi(tok[LPRNG_PRIOTOK]-('A'-1));
-#else
- buf->priority = 1;
-#endif
- return(True);
-}
-
-
-
-/*******************************************************************
-parse lpq on an aix system
-
-Queue Dev Status Job Files User PP % Blks Cp Rnk
-------- ----- --------- --- ------------------ ---------- ---- -- ----- --- ---
-lazer lazer READY
-lazer lazer RUNNING 537 6297doc.A kvintus@IE 0 10 2445 1 1
- QUEUED 538 C.ps root@IEDVB 124 1 2
- QUEUED 539 E.ps root@IEDVB 28 1 3
- QUEUED 540 L.ps root@IEDVB 172 1 4
- QUEUED 541 P.ps root@IEDVB 22 1 5
-********************************************************************/
-static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
-{
- string tok[11];
- int count=0;
-
- /* handle the case of "(standard input)" as a filename */
- string_sub(line,"standard input","STDIN");
- string_sub(line,"(","\"");
- string_sub(line,")","\"");
-
- for (count=0; count<10 && next_token(&line,tok[count],NULL); count++) ;
-
- /* we must get 6 tokens */
- if (count < 10)
- {
- if ((count == 7) && (strcmp(tok[0],"QUEUED") == 0))
- {
- /* the 2nd and 5th columns must be integer */
- if (!isdigit(*tok[1]) || !isdigit(*tok[4])) return(False);
- buf->size = atoi(tok[4]) * 1024;
- /* if the fname contains a space then use STDIN */
- if (strchr(tok[2],' '))
- strcpy(tok[2],"STDIN");
-
- /* only take the last part of the filename */
- {
- string tmp;
- char *p = strrchr(tok[2],'/');
- if (p)
- {
- fstrcpy(tmp,p+1);
- fstrcpy(tok[2],tmp);
- }
- }
-
-
- buf->job = atoi(tok[1]);
- buf->status = LPQ_QUEUED;
- buf->priority = 0;
- buf->time = time(NULL);
- StrnCpy(buf->user,tok[3],sizeof(buf->user)-1);
- StrnCpy(buf->file,tok[2],sizeof(buf->file)-1);
- }
- else
- {
- DEBUG(6,("parse_lpq_aix count=%d\n", count));
- return(False);
- }
- }
- else
- {
- /* the 4th and 9th columns must be integer */
- if (!isdigit(*tok[3]) || !isdigit(*tok[8])) return(False);
- buf->size = atoi(tok[8]) * 1024;
- /* if the fname contains a space then use STDIN */
- if (strchr(tok[4],' '))
- strcpy(tok[4],"STDIN");
-
- /* only take the last part of the filename */
- {
- string tmp;
- char *p = strrchr(tok[4],'/');
- if (p)
- {
- fstrcpy(tmp,p+1);
- fstrcpy(tok[4],tmp);
- }
- }
-
-
- buf->job = atoi(tok[3]);
- buf->status = strequal(tok[2],"RUNNING")?LPQ_PRINTING:LPQ_QUEUED;
- buf->priority = 0;
- buf->time = time(NULL);
- StrnCpy(buf->user,tok[5],sizeof(buf->user)-1);
- StrnCpy(buf->file,tok[4],sizeof(buf->file)-1);
- }
-
-
- return(True);
-}
-
-
-/****************************************************************************
-parse a lpq line
-here is an example of lpq output under hpux; note there's no space after -o !
-$> lpstat -oljplus
-ljplus-2153 user priority 0 Jan 19 08:14 on ljplus
- util.c 125697 bytes
- server.c 110712 bytes
-ljplus-2154 user priority 0 Jan 19 08:14 from client
- (standard input) 7551 bytes
-****************************************************************************/
-static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first)
-{
- /* must read two lines to process, therefore keep some values static */
- static BOOL header_line_ok=False, base_prio_reset=False;
- static string jobuser;
- static int jobid;
- static int jobprio;
- static time_t jobtime;
- static int jobstat=LPQ_QUEUED;
- /* to store minimum priority to print, lpstat command should be invoked
- with -p option first, to work */
- static int base_prio;
-
- int count;
- char TAB = '\011';
- string tok[12];
-
- /* If a line begins with a horizontal TAB, it is a subline type */
-
- if (line[0] == TAB) { /* subline */
- /* check if it contains the base priority */
- if (!strncmp(line,"\tfence priority : ",18)) {
- base_prio=atoi(&line[18]);
- DEBUG(4, ("fence priority set at %d\n", base_prio));
- }
- if (!header_line_ok) return (False); /* incorrect header line */
- /* handle the case of "(standard input)" as a filename */
- string_sub(line,"standard input","STDIN");
- string_sub(line,"(","\"");
- string_sub(line,")","\"");
-
- for (count=0; count<2 && next_token(&line,tok[count],NULL); count++) ;
- /* we must get 2 tokens */
- if (count < 2) return(False);
-
- /* the 2nd column must be integer */
- if (!isdigit(*tok[1])) return(False);
-
- /* if the fname contains a space then use STDIN */
- if (strchr(tok[0],' '))
- strcpy(tok[0],"STDIN");
-
- buf->size = atoi(tok[1]);
- StrnCpy(buf->file,tok[0],sizeof(buf->file)-1);
-
- /* fill things from header line */
- buf->time = jobtime;
- buf->job = jobid;
- buf->status = jobstat;
- buf->priority = jobprio;
- StrnCpy(buf->user,jobuser,sizeof(buf->user)-1);
-
- return(True);
- }
- else { /* header line */
- header_line_ok=False; /* reset it */
- if (first) {
- if (!base_prio_reset) {
- base_prio=0; /* reset it */
- base_prio_reset=True;
- }
- }
- else if (base_prio) base_prio_reset=False;
-
- /* handle the dash in the job id */
- string_sub(line,"-"," ");
-
- for (count=0; count<12 && next_token(&line,tok[count],NULL); count++) ;
-
- /* we must get 8 tokens */
- if (count < 8) return(False);
-
- /* first token must be printer name (cannot check ?) */
- /* the 2nd, 5th & 7th column must be integer */
- if (!isdigit(*tok[1]) || !isdigit(*tok[4]) || !isdigit(*tok[6])) return(False);
- jobid = atoi(tok[1]);
- StrnCpy(jobuser,tok[2],sizeof(buf->user)-1);
- jobprio = atoi(tok[4]);
-
- /* process time */
- jobtime=EntryTime(tok, 5, count, 8);
- if (jobprio < base_prio) {
- jobstat = LPQ_PAUSED;
- DEBUG (4, ("job %d is paused: prio %d < %d; jobstat=%d\n", jobid, jobprio, base_prio, jobstat));
- }
- else {
- jobstat = LPQ_QUEUED;
- if ((count >8) && (((strequal(tok[8],"on")) ||
- ((strequal(tok[8],"from")) &&
- ((count > 10)&&(strequal(tok[10],"on")))))))
- jobstat = LPQ_PRINTING;
- }
-
- header_line_ok=True; /* information is correct */
- return(False); /* need subline info to include into queuelist */
- }
-}
-
-
-/****************************************************************************
-parse a lpq line
-
-here is an example of "lpstat -o dcslw" output under sysv
-
-dcslw-896 tridge 4712 Dec 20 10:30:30 on dcslw
-dcslw-897 tridge 4712 Dec 20 10:30:30 being held
-
-****************************************************************************/
-static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first)
-{
- string tok[9];
- int count=0;
- char *p;
-
- /* handle the dash in the job id */
- string_sub(line,"-"," ");
-
- for (count=0; count<9 && next_token(&line,tok[count],NULL); count++) ;
-
- /* we must get 7 tokens */
- if (count < 7)
- return(False);
-
- /* the 2nd and 4th, 6th columns must be integer */
- if (!isdigit(*tok[1]) || !isdigit(*tok[3])) return(False);
- if (!isdigit(*tok[5])) return(False);
-
- /* if the user contains a ! then trim the first part of it */
- if ((p=strchr(tok[2],'!')))
- {
- string tmp;
- fstrcpy(tmp,p+1);
- fstrcpy(tok[2],tmp);
- }
-
-
- buf->job = atoi(tok[1]);
- buf->size = atoi(tok[3]);
- if (count > 7 && strequal(tok[7],"on"))
- buf->status = LPQ_PRINTING;
- else if (count > 8 && strequal(tok[7],"being") && strequal(tok[8],"held"))
- buf->status = LPQ_PAUSED;
- else
- buf->status = LPQ_QUEUED;
- buf->priority = 0;
- buf->time = EntryTime(tok, 4, count, 7);
- StrnCpy(buf->user,tok[2],sizeof(buf->user)-1);
- StrnCpy(buf->file,tok[2],sizeof(buf->file)-1);
- return(True);
-}
-
-/****************************************************************************
-parse a lpq line
-
-here is an example of lpq output under qnx
-Spooler: /qnx/spooler, on node 1
-Printer: txt (ready)
-0000: root [job #1 ] active 1146 bytes /etc/profile
-0001: root [job #2 ] ready 2378 bytes /etc/install
-0002: root [job #3 ] ready 1146 bytes -- standard input --
-****************************************************************************/
-static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first)
-{
- string tok[7];
- int count=0;
-
- DEBUG(0,("antes [%s]\n", line));
-
- /* handle the case of "-- standard input --" as a filename */
- string_sub(line,"standard input","STDIN");
- DEBUG(0,("despues [%s]\n", line));
- string_sub(line,"-- ","\"");
- string_sub(line," --","\"");
- DEBUG(0,("despues 1 [%s]\n", line));
-
- string_sub(line,"[job #","");
- string_sub(line,"]","");
- DEBUG(0,("despues 2 [%s]\n", line));
-
-
-
- for (count=0; count<7 && next_token(&line,tok[count],NULL); count++) ;
-
- /* we must get 7 tokens */
- if (count < 7)
- return(False);
-
- /* the 3rd and 5th columns must be integer */
- if (!isdigit(*tok[2]) || !isdigit(*tok[4])) return(False);
-
- /* only take the last part of the filename */
- {
- string tmp;
- char *p = strrchr(tok[6],'/');
- if (p)
- {
- fstrcpy(tmp,p+1);
- fstrcpy(tok[6],tmp);
- }
- }
-
-
- buf->job = atoi(tok[2]);
- buf->size = atoi(tok[4]);
- buf->status = strequal(tok[3],"active")?LPQ_PRINTING:LPQ_QUEUED;
- buf->priority = 0;
- buf->time = time(NULL);
- StrnCpy(buf->user,tok[1],sizeof(buf->user)-1);
- StrnCpy(buf->file,tok[6],sizeof(buf->file)-1);
- return(True);
-}
-
-
-/****************************************************************************
- parse a lpq line for the plp printing system
- Bertrand Wallrich <Bertrand.Wallrich@loria.fr>
-
-redone by tridge. Here is a sample queue:
-
-Local Printer 'lp2' (fjall):
- Printing (started at Jun 15 13:33:58, attempt 1).
- Rank Owner Pr Opt Job Host Files Size Date
- active tridge X - 6 fjall /etc/hosts 739 Jun 15 13:33
- 3rd tridge X - 7 fjall /etc/hosts 739 Jun 15 13:33
-
-****************************************************************************/
-static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first)
-{
- string tok[11];
- int count=0;
-
- /* handle the case of "(standard input)" as a filename */
- string_sub(line,"stdin","STDIN");
- string_sub(line,"(","\"");
- string_sub(line,")","\"");
-
- for (count=0; count<11 && next_token(&line,tok[count],NULL); count++) ;
-
- /* we must get 11 tokens */
- if (count < 11)
- return(False);
-
- /* the first must be "active" or begin with an integer */
- if (strcmp(tok[0],"active") && !isdigit(tok[0][0]))
- return(False);
-
- /* the 5th and 8th must be integer */
- if (!isdigit(*tok[4]) || !isdigit(*tok[7]))
- return(False);
-
- /* if the fname contains a space then use STDIN */
- if (strchr(tok[6],' '))
- strcpy(tok[6],"STDIN");
-
- /* only take the last part of the filename */
- {
- string tmp;
- char *p = strrchr(tok[6],'/');
- if (p)
- {
- fstrcpy(tmp,p+1);
- fstrcpy(tok[6],tmp);
- }
- }
-
-
- buf->job = atoi(tok[4]);
-
- buf->size = atoi(tok[7]);
- if (strchr(tok[7],'K'))
- buf->size *= 1024;
- if (strchr(tok[7],'M'))
- buf->size *= 1024*1024;
-
- buf->status = strequal(tok[0],"active")?LPQ_PRINTING:LPQ_QUEUED;
- buf->priority = 0;
- buf->time = time(NULL);
- StrnCpy(buf->user,tok[1],sizeof(buf->user)-1);
- StrnCpy(buf->file,tok[6],sizeof(buf->file)-1);
- return(True);
-}
-
-
-
-char *stat0_strings[] = { "enabled", "online", "idle", "no entries", "free", "ready", NULL };
-char *stat1_strings[] = { "offline", "disabled", "down", "off", "waiting", "no daemon", NULL };
-char *stat2_strings[] = { "jam", "paper", "error", "responding", "not accepting", "not running", "turned off", NULL };
-
-/****************************************************************************
-parse a lpq line. Choose printing style
-****************************************************************************/
-static BOOL parse_lpq_entry(int snum,char *line,
- print_queue_struct *buf,
- print_status_struct *status,BOOL first)
-{
- BOOL ret;
-
- switch (lp_printing())
- {
- case PRINT_SYSV:
- ret = parse_lpq_sysv(line,buf,first);
- break;
- case PRINT_AIX:
- ret = parse_lpq_aix(line,buf,first);
- break;
- case PRINT_HPUX:
- ret = parse_lpq_hpux(line,buf,first);
- break;
- case PRINT_QNX:
- ret = parse_lpq_qnx(line,buf,first);
- break;
- case PRINT_LPRNG:
- ret = parse_lpq_lprng(line,buf,first);
- break;
- case PRINT_PLP:
- ret = parse_lpq_plp(line,buf,first);
- break;
- default:
- ret = parse_lpq_bsd(line,buf,first);
- break;
- }
-
-#ifdef LPQ_GUEST_TO_USER
- if (ret) {
- extern pstring sesssetup_user;
- /* change guest entries to the current logged in user to make
- them appear deletable to windows */
- if (sesssetup_user[0] && strequal(buf->user,lp_guestaccount(snum)))
- pstrcpy(buf->user,sesssetup_user);
- }
-#endif
-
- /* We don't want the newline in the status message. */
- {
- char *p = strchr(line,'\n');
- if (p) *p = 0;
- }
-
- if (status && !ret)
- {
- /* a few simple checks to see if the line might be a
- printer status line:
- handle them so that most severe condition is shown */
- int i;
- strlower(line);
-
- switch (status->status) {
- case LPSTAT_OK:
- for (i=0; stat0_strings[i]; i++)
- if (strstr(line,stat0_strings[i])) {
- StrnCpy(status->message,line,sizeof(status->message)-1);
- status->status=LPSTAT_OK;
- }
- case LPSTAT_STOPPED:
- for (i=0; stat1_strings[i]; i++)
- if (strstr(line,stat1_strings[i])) {
- StrnCpy(status->message,line,sizeof(status->message)-1);
- status->status=LPSTAT_STOPPED;
- }
- case LPSTAT_ERROR:
- for (i=0; stat2_strings[i]; i++)
- if (strstr(line,stat2_strings[i])) {
- StrnCpy(status->message,line,sizeof(status->message)-1);
- status->status=LPSTAT_ERROR;
- }
- break;
- }
- }
-
- return(ret);
-}
-
-/****************************************************************************
-get a printer queue
-****************************************************************************/
-int get_printqueue(int snum,int cnum,print_queue_struct **queue,
- print_status_struct *status)
-{
- char *lpq_command = lp_lpqcommand(snum);
- char *printername = PRINTERNAME(snum);
- int ret=0,count=0;
- pstring syscmd;
- fstring outfile;
- pstring line;
- FILE *f;
- struct stat sbuf;
- BOOL dorun=True;
- int cachetime = lp_lpqcachetime();
-
- *line = 0;
- check_lpq_cache(snum);
-
- if (!printername || !*printername)
- {
- DEBUG(6,("xx replacing printer name with service (snum=(%s,%d))\n",
- lp_servicename(snum),snum));
- printername = lp_servicename(snum);
- }
-
- if (!lpq_command || !(*lpq_command))
- {
- DEBUG(5,("No lpq command\n"));
- return(0);
- }
-
- pstrcpy(syscmd,lpq_command);
- string_sub(syscmd,"%p",printername);
-
- standard_sub(cnum,syscmd);
-
- sprintf(outfile,"%s/lpq.%08x",tmpdir(),str_checksum(syscmd));
-
- if (!lpq_cache_reset[snum] && cachetime && !stat(outfile,&sbuf))
- {
- if (time(NULL) - sbuf.st_mtime < cachetime) {
- DEBUG(3,("Using cached lpq output\n"));
- dorun = False;
- }
- }
-
- if (dorun) {
- ret = smbrun(syscmd,outfile,True);
- DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
- }
-
- lpq_cache_reset[snum] = False;
-
- f = fopen(outfile,"r");
- if (!f) {
- return(0);
- }
-
- if (status) {
- strcpy(status->message,"");
- status->status = LPSTAT_OK;
- }
-
- while (fgets(line,sizeof(pstring),f))
- {
- DEBUG(6,("QUEUE2: %s\n",line));
-
- *queue = Realloc(*queue,sizeof(print_queue_struct)*(count+1));
- if (! *queue)
- {
- count = 0;
- break;
- }
-
- bzero((char *)&(*queue)[count],sizeof(**queue));
-
- /* parse it */
- if (!parse_lpq_entry(snum,line,&(*queue)[count],status,count==0))
- continue;
-
- count++;
- }
-
- fclose(f);
-
- if (!cachetime) {
- unlink(outfile);
- } else {
- /* we only expect this to succeed on trapdoor systems, on normal systems
- the file is owned by root */
- chmod(outfile,0666);
- }
- return(count);
-}
-
-
-/****************************************************************************
-delete a printer queue entry
-****************************************************************************/
-void del_printqueue(int cnum,int snum,int jobid)
-{
- char *lprm_command = lp_lprmcommand(snum);
- char *printername = PRINTERNAME(snum);
- pstring syscmd;
- char jobstr[20];
- int ret;
-
- if (!printername || !*printername)
- {
- DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n",
- lp_servicename(snum),snum));
- printername = lp_servicename(snum);
- }
-
- if (!lprm_command || !(*lprm_command))
- {
- DEBUG(5,("No lprm command\n"));
- return;
- }
-
- sprintf(jobstr,"%d",jobid);
-
- pstrcpy(syscmd,lprm_command);
- string_sub(syscmd,"%p",printername);
- string_sub(syscmd,"%j",jobstr);
- standard_sub(cnum,syscmd);
-
- ret = smbrun(syscmd,NULL,False);
- DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
- lpq_reset(snum); /* queue has changed */
-}
-
-/****************************************************************************
-change status of a printer queue entry
-****************************************************************************/
-void status_printjob(int cnum,int snum,int jobid,int status)
-{
- char *lpstatus_command =
- (status==LPQ_PAUSED?lp_lppausecommand(snum):lp_lpresumecommand(snum));
- char *printername = PRINTERNAME(snum);
- pstring syscmd;
- char jobstr[20];
- int ret;
-
- if (!printername || !*printername)
- {
- DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n",
- lp_servicename(snum),snum));
- printername = lp_servicename(snum);
- }
-
- if (!lpstatus_command || !(*lpstatus_command))
- {
- DEBUG(5,("No lpstatus command to %s job\n",
- (status==LPQ_PAUSED?"pause":"resume")));
- return;
- }
-
- sprintf(jobstr,"%d",jobid);
-
- pstrcpy(syscmd,lpstatus_command);
- string_sub(syscmd,"%p",printername);
- string_sub(syscmd,"%j",jobstr);
- standard_sub(cnum,syscmd);
-
- ret = smbrun(syscmd,NULL,False);
- DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
- lpq_reset(snum); /* queue has changed */
-}
-
-
-
-/****************************************************************************
-we encode print job numbers over the wire so that when we get them back we can
-tell not only what print job they are but also what service it belongs to,
-this is to overcome the problem that windows clients tend to send the wrong
-service number when doing print queue manipulation!
-****************************************************************************/
-int printjob_encode(int snum, int job)
-{
- return ((snum&0xFF)<<8) | (job & 0xFF);
-}
-
-/****************************************************************************
-and now decode them again ...
-****************************************************************************/
-void printjob_decode(int jobid, int *snum, int *job)
-{
- (*snum) = (jobid >> 8) & 0xFF;
- (*job) = jobid & 0xFF;
-}
diff --git a/source/script/addtosmbpass b/source/script/addtosmbpass
deleted file mode 100644
index 42af518397c..00000000000
--- a/source/script/addtosmbpass
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/usr/bin/awk -f
-# edit the line above to point to your real location of awk interpreter
-
-# awk program for adding new entries in smbpasswd files
-# arguments are account names to add; feed it an existent Samba password
-# file on stdin, results will be written on stdout
-#
-# Michal Jaegermann, michal@ellpspace.math.ualberta.ca, 1995-11-09
-
-BEGIN {
- me = "addtosmbpass";
- count = ARGC;
- FS = ":";
-
- if (count == 1) {
- print "Usage:", me,
- "name1 [name2 ....] < smbpasswd.in > smbpasswd.out";
- ARGV[1] = "/dev/null";
- ARGC = 2;
- exit;
- }
-
- for(i = 1; i < count; i++) {
- names[ARGV[i]] = " ";
- delete ARGV[i];
- }
-# sane awk should work simply with 'ARGC = 1', but not every awk
-# implementation is sane - big sigh!!
- ARGV[1] = "-";
- ARGC = 2;
-#
-# If you have ypmatch but is not RPC registered (some Linux systems
-# for example) comment out the next line.
-# "which ypmatch" | getline ypmatch;
- if (1 != match(ypmatch, /^\//)) {
- ypmatch = "";
- }
- pwdf = "/etc/passwd";
-}
-#check for names already present in input
-{
- print $0;
- for(name in names) {
- if($1 ~ name) {
- delete names[name];
- }
- }
-}
-END {
- fmt = "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:";
- fmt = fmt "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:%s:%s:%s\n";
- for(name in names) {
- while ((getline < pwdf) > 0) {
- if ($1 == name) {
- printf(fmt, $1, $3, $5, $6, $7);
- close(pwdf);
- notfound = "";
- break;
- }
- notfound = "n";
- }
- $0 = "";
- if (notfound && ypmatch) {
-# try to find in NIS databases
- command = ypmatch " " name " passwd";
- command | getline;
- if (NF > 0) {
- printf(fmt, $1, $3, $5, $6, $7);
- }
- close(command);
- }
- }
-}
-
diff --git a/source/script/installbin.sh b/source/script/installbin.sh
deleted file mode 100755
index b976a3e5ea8..00000000000
--- a/source/script/installbin.sh
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/bin/sh
-INSTALLPERMS=$1
-BASEDIR=$2
-BINDIR=$3
-LIBDIR=$4
-VARDIR=$5
-shift
-shift
-shift
-shift
-shift
-
-for d in $BASEDIR $BINDIR $LIBDIR $VARDIR; do
-if [ ! -d $d ]; then
-mkdir $d
-if [ ! -d $d ]; then
- echo Failed to make directory $d
- exit 1
-fi
-fi
-done
-
-
-for p in $*; do
- echo Installing $p as $BINDIR/$p
- if [ -f $BINDIR/$p ]; then
- mv $BINDIR/$p $BINDIR/$p.old
- fi
- cp $p $BINDIR/$p
- chmod $INSTALLPERMS $BINDIR/$p
-done
-
-
-cat << EOF
-======================================================================
-The binaries are installed. You may restore the old binaries (if there
-were any) using the command "make revert". You may uninstall the binaries
-using the command "make uninstallbin" or "make uninstall" to uninstall
-binaries, man pages and shell scripts.
-======================================================================
-EOF
-
-exit 0
-
diff --git a/source/script/installcp.sh b/source/script/installcp.sh
deleted file mode 100755
index bafd84146d7..00000000000
--- a/source/script/installcp.sh
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/bin/sh
-LIBDIR=$1
-CODEPAGEDIR=$2
-BINDIR=$3
-
-shift
-shift
-shift
-
-echo Installing codepage files in $CODEPAGEDIR
-for d in $LIBDIR $CODEPAGEDIR; do
-if [ ! -d $d ]; then
-mkdir $d
-if [ ! -d $d ]; then
- echo Failed to make directory $d
- exit 1
-fi
-fi
-done
-
-for p in $*; do
- echo Creating codepage file $CODEPAGEDIR/codepage.$p from codepage_def.$p
- $BINDIR/make_smbcodepage c $p codepage_def.$p $CODEPAGEDIR/codepage.$p
-done
-
-
-cat << EOF
-======================================================================
-The code pages have been installed. You may uninstall them using the command
-the command "make uninstallcp" or make "uninstall" to uninstall binaries,
-man pages, shell scripts and code pages.
-======================================================================
-EOF
-
-exit 0
-
diff --git a/source/script/installman.sh b/source/script/installman.sh
deleted file mode 100755
index 3c8fc718654..00000000000
--- a/source/script/installman.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/sh
-#5 July 96 Dan.Shearer@unisa.edu.au removed hardcoded values
-
-MANDIR=$1
-SRCDIR=$2
-
-echo Installing man pages in $MANDIR
-
-for d in $MANDIR $MANDIR/man1 $MANDIR/man5 $MANDIR/man7 $MANDIR/man8; do
-if [ ! -d $d ]; then
-mkdir $d
-if [ ! -d $d ]; then
- echo Failed to make directory $d, does $USER have privileges?
- exit 1
-fi
-fi
-done
-
-for sect in 1 5 7 8 ; do
- for m in $MANDIR/man$sect ; do
- for s in $SRCDIR../docs/*$sect; do
- FNAME=$m/`basename $s`
- cp $s $m || echo Cannot create $FNAME... does $USER have privileges?
- chmod 0644 $FNAME
- done
- done
-done
-
-cat << EOF
-======================================================================
-The man pages have been installed. You may uninstall them using the command
-the command "make uninstallman" or make "uninstall" to uninstall binaries,
-man pages and shell scripts.
-======================================================================
-EOF
-
-exit 0
-
diff --git a/source/script/installscripts.sh b/source/script/installscripts.sh
deleted file mode 100755
index 1a230c8cfa2..00000000000
--- a/source/script/installscripts.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/sh
-# this script courtesy of James_K._Foote.PARC@xerox.com
-# 5 July 96 Dan.Shearer@UniSA.Edu.Au Don't hardcode script names, get from Make
-
-INSTALLPERMS=$1
-BINDIR=$2
-
-shift
-shift
-
-echo Installing scripts in $BINDIR
-
-for d in $BINDIR; do
- if [ ! -d $d ]; then
- mkdir $d
- if [ ! -d $d ]; then
- echo Failed to make directory $d
- echo Have you run installbin first?
- exit 1
- fi
- fi
-done
-
-for p in $*; do
- echo Installing $BINDIR/$p
- cp $p $BINDIR/$p
- if [ ! -f $BINDIR/$p ]; then
- echo Cannot copy $p... does $USER have privileges?
- fi
- echo Setting permissions on $BINDIR/$p
- chmod $INSTALLPERMS $BINDIR/$p
-done
-
-cat << EOF
-======================================================================
-The scripts have been installed. You may uninstall them using
-the command "make uninstallscripts" or "make install" to install binaries,
-man pages and shell scripts. You may recover the previous version (if any
-by "make revert".
-======================================================================
-EOF
-
-exit 0
diff --git a/source/script/mkproto.awk b/source/script/mkproto.awk
deleted file mode 100644
index 1ccf2fb2b0a..00000000000
--- a/source/script/mkproto.awk
+++ /dev/null
@@ -1,82 +0,0 @@
-BEGIN {
- inheader=0;
- current_file="";
- print "/* This file is automatically generated with \"make proto\". DO NOT EDIT */"
- print ""
-}
-
-{
- if (FILENAME!=current_file) {
- print ""
- print "/*The following definitions come from ",FILENAME," */"
- print ""
- current_file=FILENAME
- }
- if (inheader) {
- if (match($0,"[)][ \t]*$")) {
- inheader = 0;
- printf "%s;\n",$0;
- } else {
- printf "%s\n",$0;
- }
- next;
- }
-}
-
-# we handle the loadparm.c fns separately
-
-/^FN_LOCAL_BOOL/ {
- split($0,a,"[,()]")
- printf "BOOL %s(int );\n", a[2]
-}
-
-/^FN_LOCAL_STRING/ {
- split($0,a,"[,()]")
- printf "char *%s(int );\n", a[2]
-}
-
-/^FN_LOCAL_INT/ {
- split($0,a,"[,()]")
- printf "int %s(int );\n", a[2]
-}
-
-/^FN_LOCAL_CHAR/ {
- split($0,a,"[,()]")
- printf "char %s(int );\n", a[2]
-}
-
-/^FN_GLOBAL_BOOL/ {
- split($0,a,"[,()]")
- printf "BOOL %s(void);\n", a[2]
-}
-
-/^FN_GLOBAL_STRING/ {
- split($0,a,"[,()]")
- printf "char *%s(void);\n", a[2]
-}
-
-/^FN_GLOBAL_INT/ {
- split($0,a,"[,()]")
- printf "int %s(void);\n", a[2]
-}
-
-/^static|^extern/ || !/^[a-zA-Z]/ || /[;]/ {
- next;
-}
-
-!/^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^enum remote_arch_types|arc4_key/ {
- next;
-}
-
-
-/[(].*[)][ \t]*$/ {
- printf "%s;\n",$0;
- next;
-}
-
-/[(]/ {
- inheader=1;
- printf "%s\n",$0;
- next;
-}
-
diff --git a/source/script/mksmbpasswd.sh b/source/script/mksmbpasswd.sh
deleted file mode 100755
index 6e592acd652..00000000000
--- a/source/script/mksmbpasswd.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh
-awk 'BEGIN {FS=":"
- printf("#\n# SMB password file.\n#\n")
- }
-{ printf( "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:%s:%s:%s\n", $1, $3, $5, $6, $7) }
-'
diff --git a/source/script/revert.sh b/source/script/revert.sh
deleted file mode 100755
index 68b47bf39d0..00000000000
--- a/source/script/revert.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-BINDIR=$1
-shift
-
-for p in $*; do
- if [ -f $BINDIR/$p.old ]; then
- echo Restoring $BINDIR/$p.old as $BINDIR/$p
- mv $BINDIR/$p $BINDIR/$p.new
- mv $BINDIR/$p.old $BINDIR/$p
- rm -f $BINDIR/$p.new
- fi
-done
-
-exit 0
-
diff --git a/source/script/smbtar b/source/script/smbtar
deleted file mode 100644
index dcf01edb208..00000000000
--- a/source/script/smbtar
+++ /dev/null
@@ -1,140 +0,0 @@
-#!/bin/sh
-#
-# smbtar script - front end to smbclient
-#
-# Authors: Martin.Kraemer <Martin.Kraemer@mch.sni.de>
-# and Ricky Poulten (ricky@logcam.co.uk)
-#
-# (May need to change shell to ksh for HPUX or OSF for better getopts)
-
-case $0 in
- # when called by absolute path, assume smbclient is in the same directory
- /*)
- SMBCLIENT="`dirname $0`/smbclient";;
- *) # you may need to edit this to show where your smbclient is
- SMBCLIENT="smbclient";;
-esac
-
-# These are the default values. You could fill them in if you know what
-# you're doing, but beware: better not store a plain text password!
-server=""
-service="backup" # Default: a service called "backup"
-password=""
-username=$LOGNAME # Default: same user name as in *nix
-verbose="2>/dev/null" # Default: no echo to stdout
-log="-d 2"
-newer=""
-blocksize=""
-tarcmd="c"
-tarargs=""
-cdcmd="\\"
-tapefile=${TAPE-tar.out}
-
-Usage(){
- ex=$1
- shift
-echo >&2 "Usage: `basename $0` [<options>] [<include/exclude files>]
-Function: backup/restore a Windows PC directories to a local tape file
-Options: (Description) (Default)
- -r Restore from tape file to PC Save from PC to tapefile
- -i Incremental mode Full backup mode
- -v Verbose mode: echo command Don't echo anything
- -s <server> Specify PC Server $server
- -p <password> Specify PC Password $password
- -x <share> Specify PC Share $service
- -X Exclude mode Include
- -N <newer> File for date comparison `set -- $newer; echo $2`
- -b <blocksize> Specify tape's blocksize `set -- $blocksize; echo $2`
- -d <dir> Specify a directory in share $cdcmd
- -l <log> Specify a Samba Log Level `set -- $log; echo $2`
- -u <user> Specify User Name $username
- -t <tape> Specify Tape device $tapefile
-"
- echo >&2 "$@"
- exit $ex
-}
-
-while getopts rivl:b:d:N:s:p:x:u:Xt: c; do
- case $c in
- r) # [r]estore to Windows (instead of the default "Save from Windows")
- tarcmd="x"
- ;;
- i) # [i]ncremental
- tarargs=${tarargs}g
- ;;
- l) # specify [l]og file
- log="-d $OPTARG"
- case "$OPTARG" in
- [0-9]*) ;;
- *) echo >&2 "$0: Error, log level not numeric: -l $OPTARG"
- exit 1
- esac
- ;;
- d) # specify [d]irectory to change to in server's share
- cdcmd="$OPTARG"
- ;;
- N) # compare with a file, test if [n]ewer
- if [ -f $OPTARG ]; then
- newer=$OPTARG
- tarargs=${tarargs}N
- else
- echo >&2 $0: Warning, $OPTARG not found
- fi
- ;;
- X) # Add exclude flag
- tarargs=${tarargs}X
- ;;
- s) # specify [s]erver's share to connect to - this MUST be given.
- server="$OPTARG"
- ;;
- b) # specify [b]locksize
- blocksize="$OPTARG"
- case "$OPTARG" in
- [0-9]*) ;;
- *) echo >&2 "$0: Error, block size not numeric: -b $OPTARG"
- exit 1
- esac
- tarargs=${tarargs}b
- ;;
- p) # specify [p]assword to use
- password="$OPTARG"
- ;;
- x) # specify windows [s]hare to use
- service="$OPTARG"
- ;;
- t) # specify [t]apefile on local host
- tapefile="$OPTARG"
- ;;
- u) # specify [u]sername for connection
- username="$OPTARG"
- ;;
- v) # be [v]erbose and display what's going on
- verbose=""
- ;;
- '?') # any other switch
- Usage 2 "Invalid switch specified - abort."
- ;;
- esac
-done
-
-shift `expr $OPTIND - 1`
-
-if [ "$server" = "" ] || [ "$service" = "" ]; then
- Usage 1 "No server or no service specified - abort."
-fi
-
-# if the -v switch is set, the echo the current parameters
-if [ -z "$verbose" ]; then
- echo "server is $server"
-# echo "share is $service"
- echo "share is $service\\$cdcmd"
- echo "tar args is $tarargs"
-# echo "password is $password" # passwords should never be sent to screen
- echo "tape is $tapefile"
- echo "blocksize is $blocksize"
-fi
-
-eval $SMBCLIENT "'\\\\$server\\$service'" "'$password'" -U "'$username'" \
--E -N $log -D "'$cdcmd'" \
--T${tarcmd}${tarargs} $blocksize $newer $tapefile $* $verbose
-
diff --git a/source/script/uninstallbin.sh b/source/script/uninstallbin.sh
deleted file mode 100755
index fab36804a29..00000000000
--- a/source/script/uninstallbin.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/sh
-#4 July 96 Dan.Shearer@UniSA.edu.au
-
-INSTALLPERMS=$1
-BASEDIR=$2
-BINDIR=$3
-LIBDIR=$4
-VARDIR=$5
-shift
-shift
-shift
-shift
-shift
-
-if [ ! -d $BINDIR ]; then
- echo Directory $BINDIR does not exist!
- echo Do a "make installbin" or "make install" first.
- exit 1
-fi
-
-for p in $*; do
- if [ ! -f $BINDIR/$p ]; then
- echo $BINDIR/$p does not exist!
- else
- echo Removing $BINDIR/$p
- rm -f $BINDIR/$p
- if [ -f $BINDIR/$p ]; then
- echo Cannot remove $BINDIR/$p... does $USER have privileges?
- fi
- fi
-done
-
-
-cat << EOF
-======================================================================
-The binaries have been uninstalled. You may restore the binaries using
-the command "make installbin" or "make install" to install binaries,
-man pages and shell scripts. You can restore a previous version of the
-binaries (if there were any) using "make revert".
-======================================================================
-EOF
-
-exit 0
diff --git a/source/script/uninstallcp.sh b/source/script/uninstallcp.sh
deleted file mode 100755
index bd7013c358f..00000000000
--- a/source/script/uninstallcp.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/bin/sh
-
-CPDIR=$1
-shift
-
-if [ ! -d $CPDIR ]; then
- echo Directory $CPDIR does not exist!
- echo Do a "make installcp" or "make install" first.
- exit 1
-fi
-
-for p in $*; do
- if [ ! -f $CPDIR/codepage.$p ]; then
- echo $CPDIR/codepage.$p does not exist!
- else
- echo Removing $CPDIR/codepage.$p
- rm -f $CPDIR/codepage.$p
- if [ -f $CPDIR/codepage.$p ]; then
- echo Cannot remove $CPDIR/codepage.$p... does $USER have privileges?
- fi
- fi
-done
-
-cat << EOF
-======================================================================
-The code pages have been uninstalled. You may reinstall them using
-the command "make installcp" or "make install" to install binaries,
-man pages, shell scripts and code pages. You may recover a previous version
-(if any with "make revert").
-======================================================================
-EOF
-
-exit 0
diff --git a/source/script/uninstallman.sh b/source/script/uninstallman.sh
deleted file mode 100755
index b4d4bfc1f92..00000000000
--- a/source/script/uninstallman.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/sh
-#4 July 96 Dan.Shearer@UniSA.edu.au
-
-MANDIR=$1
-SRCDIR=$2
-
-echo Uninstalling man pages from $MANDIR
-
-for sect in 1 5 7 8 ; do
- for m in $MANDIR/man$sect ; do
- for s in $SRCDIR../docs/*$sect; do
- FNAME=$m/`basename $s`
- if test -f $FNAME; then
- echo Deleting $FNAME
- rm -f $FNAME
- test -f $FNAME && echo Cannot remove $FNAME... does $USER have privileges?
- else
- echo $FNAME does not exist! Check defines in the Makefile
- fi
- done
- done
-done
-
-cat << EOF
-======================================================================
-The man pages have been uninstalled. You may install them again using
-the command "make installman" or make "install" to install binaries,
-man pages and shell scripts.
-======================================================================
-EOF
-exit 0
diff --git a/source/script/uninstallscripts.sh b/source/script/uninstallscripts.sh
deleted file mode 100755
index ae907546f2e..00000000000
--- a/source/script/uninstallscripts.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/sh
-# 5 July 96 Dan.Shearer@UniSA.Edu.Au - almost identical to uninstallbin.sh
-
-INSTALLPERMS=$1
-BINDIR=$2
-
-shift
-shift
-
-if [ ! -d $BINDIR ]; then
- echo Directory $BINDIR does not exist!
- echo Do a "make installscripts" or "make install" first.
- exit 1
-fi
-
-for p in $*; do
- if [ ! -f $BINDIR/$p ]; then
- echo $BINDIR/$p does not exist!
- else
- echo Removing $BINDIR/$p
- rm -f $BINDIR/$p
- if [ -f $BINDIR/$p ]; then
- echo Cannot remove $BINDIR/$p... does $USER have privileges?
- fi
- fi
-done
-
-cat << EOF
-======================================================================
-The scripts have been uninstalled. You may reinstall them using
-the command "make installscripts" or "make install" to install binaries,
-man pages and shell scripts. You may recover a previous version (if any
-with "make revert".
-======================================================================
-EOF
-
-exit 0
diff --git a/source/script/updatesmbpasswd.sh b/source/script/updatesmbpasswd.sh
deleted file mode 100755
index 1d7e0d7332f..00000000000
--- a/source/script/updatesmbpasswd.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-nawk 'BEGIN {FS=":"}
-{
- if( $0 ~ "^#" ) {
- print $0
- } else if( (length($4) == 32) && (($4 ~ "^[0-9A-F]*$") || ($4 ~ "^[X]*$") || ( $4 ~ "^[*]*$"))) {
- print $0
- } else {
- printf( "%s:%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:", $1, $2, $3);
- for(i = 4; i <= NF; i++)
- printf("%s:", $i)
- printf("\n")
- }
-}'
diff --git a/source/smbadduser b/source/smbadduser
deleted file mode 100755
index 789cc927eb1..00000000000
--- a/source/smbadduser
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/bin/csh
-#
-# smbadduser - Written by Mike Zakharoff
-#
-unalias *
-set path = ($path /usr/local/samba/bin)
-
-set smbpasswd = /usr/local/samba/private/smbpasswd
-set user_map = /usr/local/samba/lib/users.map
-#
-# Set to site specific passwd command
-#
-#set passwd = "cat /etc/passwd"
-#set passwd = "niscat passwd.org_dir"
-set passwd = "ypcat passwd"
-
-set line = "----------------------------------------------------------"
-if ($#argv == 0) then
- echo $line
- echo "Written: Mike Zakharoff email: michael.j.zakharoff@boeing.com"
- echo ""
- echo " 1) Updates $smbpasswd"
- echo " 2) Updates $user_map"
- echo " 3) Executes smbpasswd for each new user"
- echo ""
- echo "smbadduser unixid:ntid unixid:ntid ..."
- echo ""
- echo "Example: smbadduser zak:zakharoffm johns:smithj"
- echo $line
- exit 1
-endif
-
-touch $smbpasswd $user_map
-set new = ()
-foreach one ($argv)
- echo $one | grep ':' >& /dev/null
- if ($status != 0) then
- echo "ERROR: Must use unixid:ntid like -> zak:zakharoffm"
- continue
- endif
- set unix = `echo $one | awk -F: '{print $1}'`
- set ntid = `echo $one | awk -F: '{print $2}'`
-
- set usr = `eval $passwd | awk -F: '$1==USR {print $1}' USR=$unix`
- if ($#usr != 1) then
- echo "ERROR: $unix Not in passwd database SKIPPING..."
- continue
- endif
- set tmp = `cat $smbpasswd | awk -F: '$1==USR {print $1}' USR=$unix`
- if ($#tmp != 0) then
- echo "ERROR: $unix is already in $smbpasswd SKIPPING..."
- continue
- endif
-
- echo "Adding: $unix to $smbpasswd"
- eval $passwd | \
- awk -F: '$1==USR { \
- printf( "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:%s:%s:%s\n",
-$1, $3, $5, $6, $7) }' USR=$unix >> $smbpasswd
- if ($unix != $ntid) then
- echo "Adding: {$unix = $ntid} to $user_map"
- echo "$unix = $ntid" >> $user_map
- endif
- set new = ($new $unix)
-end
-
-#
-# Enter password for new users
-#
-foreach one ($new)
- echo $line
- echo "ENTER password for $one"
- smbpasswd $one
-end \ No newline at end of file
diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c
deleted file mode 100644
index bed81138b24..00000000000
--- a/source/smbd/chgpasswd.c
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Samba utility functions
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-
-/* fork a child process to exec passwd and write to its
-* tty to change a users password. This is running as the
-* user who is attempting to change the password.
-*/
-
-/*
- * This code was copied/borrowed and stolen from various sources.
- * The primary source was the poppasswd.c from the authors of POPMail. This software
- * was included as a client to change passwords using the 'passwd' program
- * on the remote machine.
- *
- * This routine is called by set_user_password() in password.c only if ALLOW_PASSWORD_CHANGE
- * is defined in the compiler directives located in the Makefile.
- *
- * This code has been hacked by Bob Nance (nance@niehs.nih.gov) and Evan Patterson
- * (patters2@niehs.nih.gov) at the National Institute of Environmental Health Sciences
- * and rights to modify, distribute or incorporate this change to the CAP suite or
- * using it for any other reason are granted, so long as this disclaimer is left intact.
- */
-
-/*
- This code was hacked considerably for inclusion in Samba, primarily
- by Andrew.Tridgell@anu.edu.au. The biggest change was the addition
- of the "password chat" option, which allows the easy runtime
- specification of the expected sequence of events to change a
- password.
- */
-
-#include "includes.h"
-
-extern int DEBUGLEVEL;
-
-#ifdef ALLOW_CHANGE_PASSWORD
-
-#define MINPASSWDLENGTH 5
-#define BUFSIZE 512
-
-static int findpty(char **slave)
-{
- int master;
-#if defined(SVR4) || defined(SUNOS5)
- extern char *ptsname();
-#else /* defined(SVR4) || defined(SUNOS5) */
- static char line[12];
- void *dirp;
- char *dpname;
-#endif /* defined(SVR4) || defined(SUNOS5) */
-
-#if defined(SVR4) || defined(SUNOS5)
- if ((master = open("/dev/ptmx", O_RDWR)) >= 1) {
- grantpt(master);
- unlockpt(master);
- *slave = ptsname(master);
- return (master);
- }
-#else /* defined(SVR4) || defined(SUNOS5) */
- strcpy( line, "/dev/ptyXX" );
-
- dirp = OpenDir(-1, "/dev", True);
- if (!dirp) return(-1);
- while ((dpname = ReadDirName(dirp)) != NULL) {
- if (strncmp(dpname, "pty", 3) == 0 && strlen(dpname) == 5) {
- DEBUG(3,("pty: try to open %s, line was %s\n", dpname, line ) );
- line[8] = dpname[3];
- line[9] = dpname[4];
- if ((master = open(line, O_RDWR)) >= 0) {
- DEBUG(3,("pty: opened %s\n", line ) );
- line[5] = 't';
- *slave = line;
- CloseDir(dirp);
- return (master);
- }
- }
- }
- CloseDir(dirp);
-#endif /* defined(SVR4) || defined(SUNOS5) */
- return (-1);
-}
-
-static int dochild(int master,char *slavedev, char *name, char *passwordprogram)
-{
- int slave;
- struct termios stermios;
- struct passwd *pass = Get_Pwnam(name,True);
- int gid = pass->pw_gid;
- int uid = pass->pw_uid;
-
-#ifdef USE_SETRES
- setresuid(0,0,0);
-#else /* USE_SETRES */
- setuid(0);
-#endif /* USE_SETRES */
-
- /* Start new session - gets rid of controlling terminal. */
- if (setsid() < 0) {
- DEBUG(3,("Weirdness, couldn't let go of controlling terminal\n"));
- return(False);
- }
-
- /* Open slave pty and acquire as new controlling terminal. */
- if ((slave = open(slavedev, O_RDWR)) < 0) {
- DEBUG(3,("More weirdness, could not open %s\n",
- slavedev));
- return(False);
- }
-#if defined(SVR4) || defined(SUNOS5)
- ioctl(slave, I_PUSH, "ptem");
- ioctl(slave, I_PUSH, "ldterm");
-#else /* defined(SVR4) || defined(SUNOS5) */
- if (ioctl(slave,TIOCSCTTY,0) <0) {
- DEBUG(3,("Error in ioctl call for slave pty\n"));
- /* return(False); */
- }
-#endif /* defined(SVR4) || defined(SUNOS5) */
-
- /* Close master. */
- close(master);
-
- /* Make slave stdin/out/err of child. */
-
- if (dup2(slave, STDIN_FILENO) != STDIN_FILENO) {
- DEBUG(3,("Could not re-direct stdin\n"));
- return(False);
- }
- if (dup2(slave, STDOUT_FILENO) != STDOUT_FILENO) {
- DEBUG(3,("Could not re-direct stdout\n"));
- return(False);
- }
- if (dup2(slave, STDERR_FILENO) != STDERR_FILENO) {
- DEBUG(3,("Could not re-direct stderr\n"));
- return(False);
- }
- if (slave > 2) close(slave);
-
- /* Set proper terminal attributes - no echo, canonical input processing,
- no map NL to CR/NL on output. */
-
- if (tcgetattr(0, &stermios) < 0) {
- DEBUG(3,("could not read default terminal attributes on pty\n"));
- return(False);
- }
- stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
- stermios.c_lflag |= ICANON;
- stermios.c_oflag &= ~(ONLCR);
- if (tcsetattr(0, TCSANOW, &stermios) < 0) {
- DEBUG(3,("could not set attributes of pty\n"));
- return(False);
- }
-
- /* make us completely into the right uid */
-#ifdef USE_SETRES
- setresgid(0,0,0);
- setresuid(0,0,0);
- setresgid(gid,gid,gid);
- setresuid(uid,uid,uid);
-#else
- setuid(0);
- seteuid(0);
- setgid(gid);
- setegid(gid);
- setuid(uid);
- seteuid(uid);
-#endif
-
- /* execl() password-change application */
- if (execl("/bin/sh","sh","-c",passwordprogram,NULL) < 0) {
- DEBUG(3,("Bad status returned from %s\n",passwordprogram));
- return(False);
- }
- return(True);
-}
-
-static int expect(int master,char *expected,char *buf)
-{
- int n, m;
-
- n = 0;
- buf[0] = 0;
- while (1) {
- if (n >= BUFSIZE-1) {
- return False;
- }
-
- /* allow 4 seconds for some output to appear */
- m = read_with_timeout(master, buf+n, 1, BUFSIZE-1-n, 4000);
- if (m < 0)
- return False;
-
- n += m;
- buf[n] = 0;
-
- {
- pstring s1,s2;
- pstrcpy(s1,buf);
- pstrcpy(s2,expected);
- if (do_match(s1, s2, False))
- return(True);
- }
- }
-}
-
-static void pwd_sub(char *buf)
-{
- string_sub(buf,"\\n","\n");
- string_sub(buf,"\\r","\r");
- string_sub(buf,"\\s"," ");
- string_sub(buf,"\\t","\t");
-}
-
-static void writestring(int fd,char *s)
-{
- int l;
-
- l = strlen (s);
- write (fd, s, l);
-}
-
-
-static int talktochild(int master, char *chatsequence)
-{
- char buf[BUFSIZE];
- int count=0;
- char *ptr=chatsequence;
- fstring chatbuf;
-
- *buf = 0;
- sleep(1);
-
- while (next_token(&ptr,chatbuf,NULL)) {
- BOOL ok=True;
- count++;
- pwd_sub(chatbuf);
- if (!strequal(chatbuf,"."))
- ok = expect(master,chatbuf,buf);
-
-#if DEBUG_PASSWORD
- DEBUG(100,("chatbuf=[%s] responsebuf=[%s]\n",chatbuf,buf));
-#endif
-
- if (!ok) {
- DEBUG(3,("response %d incorrect\n",count));
- return(False);
- }
-
- if (!next_token(&ptr,chatbuf,NULL)) break;
- pwd_sub(chatbuf);
- if (!strequal(chatbuf,"."))
- writestring(master,chatbuf);
-
-#if DEBUG_PASSWORD
- DEBUG(100,("sendbuf=[%s]\n",chatbuf));
-#endif
- }
-
- if (count<1) return(False);
-
- return (True);
-}
-
-
-BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequence)
-{
- char *slavedev;
- int master;
- pid_t pid, wpid;
- int wstat;
- BOOL chstat;
-
- /* allocate a pseudo-terminal device */
- if ((master = findpty (&slavedev)) < 0) {
- DEBUG(3,("Cannot Allocate pty for password change: %s",name));
- return(False);
- }
-
- if ((pid = fork()) < 0) {
- DEBUG(3,("Cannot fork() child for password change: %s",name));
- return(False);
- }
-
- /* we now have a pty */
- if (pid > 0){ /* This is the parent process */
- if ((chstat = talktochild(master, chatsequence)) == False) {
- DEBUG(3,("Child failed to change password: %s\n",name));
- kill(pid, SIGKILL); /* be sure to end this process */
- return(False);
- }
- if ((wpid = sys_waitpid(pid, &wstat, 0)) < 0) {
- DEBUG(3,("The process is no longer waiting!\n\n"));
- return(False);
- }
- if (pid != wpid) {
- DEBUG(3,("We were waiting for the wrong process ID\n"));
- return(False);
- }
- if (WIFEXITED(wstat) == 0) {
- DEBUG(3,("The process exited while we were waiting\n"));
- return(False);
- }
- if (WEXITSTATUS(wstat) != 0) {
- DEBUG(3,("The status of the process exiting was %d\n", wstat));
- return(False);
- }
-
- } else {
- /* CHILD */
-
- /* make sure it doesn't freeze */
- alarm(20);
-
- DEBUG(3,("Dochild for user %s (uid=%d,gid=%d)\n",name,getuid(),getgid()));
- chstat = dochild(master, slavedev, name, passwordprogram);
- }
- DEBUG(3,("Password change %ssuccessful for user %s\n", (chstat?"":"un"), name));
- return (chstat);
-}
-
-
-BOOL chgpasswd(char *name,char *oldpass,char *newpass)
-{
- pstring passwordprogram;
- pstring chatsequence;
-
- strlower(name);
- DEBUG(3,("Password change for user: %s\n",name));
-
-#if DEBUG_PASSWORD
- DEBUG(100,("Passwords: old=%s new=%s\n",oldpass,newpass));
-#endif
-
- /* Take the passed information and test it for minimum criteria */
- /* Minimum password length */
- if (strlen(newpass) < MINPASSWDLENGTH) /* too short, must be at least MINPASSWDLENGTH */
- {
- DEBUG(2,("Password Change: %s, New password is shorter than MINPASSWDLENGTH\n",name));
- return (False); /* inform the user */
- }
-
- /* Password is same as old password */
- if (strcmp(oldpass,newpass) == 0) /* don't allow same password */
- {
- DEBUG(2,("Password Change: %s, New password is same as old\n",name)); /* log the attempt */
- return (False); /* inform the user */
- }
-
-#if (defined(PASSWD_PROGRAM) && defined(PASSWD_CHAT))
- pstrcpy(passwordprogram,PASSWD_PROGRAM);
- pstrcpy(chatsequence,PASSWD_CHAT);
-#else
- pstrcpy(passwordprogram,lp_passwd_program());
- pstrcpy(chatsequence,lp_passwd_chat());
-#endif
-
- if (!*chatsequence) {
- DEBUG(2,("Null chat sequence - no password changing\n"));
- return(False);
- }
-
- if (!*passwordprogram) {
- DEBUG(2,("Null password program - no password changing\n"));
- return(False);
- }
-
- string_sub(passwordprogram,"%u",name);
- string_sub(passwordprogram,"%o",oldpass);
- string_sub(passwordprogram,"%n",newpass);
-
- string_sub(chatsequence,"%u",name);
- string_sub(chatsequence,"%o",oldpass);
- string_sub(chatsequence,"%n",newpass);
- return(chat_with_program(passwordprogram,name,chatsequence));
-}
-
-#else
-BOOL chgpasswd(char *name,char *oldpass,char *newpass)
-{
- DEBUG(0,("Password changing not compiled in (user=%s)\n",name));
- return(False);
-}
-#endif
diff --git a/source/smbd/dir.c b/source/smbd/dir.c
deleted file mode 100644
index 316b58818fd..00000000000
--- a/source/smbd/dir.c
+++ /dev/null
@@ -1,996 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Directory handling routines
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-
-#include "includes.h"
-
-extern int DEBUGLEVEL;
-extern connection_struct Connections[];
-
-/*
- This module implements directory related functions for Samba.
-*/
-
-
-
-uint32 dircounter = 0;
-
-
-#define NUMDIRPTRS 256
-
-
-static struct dptr_struct
-{
- int pid;
- int cnum;
- uint32 lastused;
- void *ptr;
- BOOL valid;
- BOOL finished;
- BOOL expect_close;
- char *wcard; /* Field only used for lanman2 trans2_findfirst/next searches */
- uint16 attr; /* Field only used for lanman2 trans2_findfirst/next searches */
- char *path;
-}
-dirptrs[NUMDIRPTRS];
-
-
-static int dptrs_open = 0;
-
-/****************************************************************************
-initialise the dir array
-****************************************************************************/
-void init_dptrs(void)
-{
- static BOOL dptrs_init=False;
- int i;
-
- if (dptrs_init) return;
- for (i=0;i<NUMDIRPTRS;i++)
- {
- dirptrs[i].valid = False;
- dirptrs[i].wcard = NULL;
- dirptrs[i].ptr = NULL;
- string_init(&dirptrs[i].path,"");
- }
- dptrs_init = True;
-}
-
-/****************************************************************************
-idle a dptr - the directory is closed but the control info is kept
-****************************************************************************/
-static void dptr_idle(int key)
-{
- if (dirptrs[key].valid && dirptrs[key].ptr) {
- DEBUG(4,("Idling dptr key %d\n",key));
- dptrs_open--;
- CloseDir(dirptrs[key].ptr);
- dirptrs[key].ptr = NULL;
- }
-}
-
-/****************************************************************************
-idle the oldest dptr
-****************************************************************************/
-static void dptr_idleoldest(void)
-{
- int i;
- uint32 old=dircounter+1;
- int oldi= -1;
- for (i=0;i<NUMDIRPTRS;i++)
- if (dirptrs[i].valid && dirptrs[i].ptr && dirptrs[i].lastused < old) {
- old = dirptrs[i].lastused;
- oldi = i;
- }
- if (oldi != -1)
- dptr_idle(oldi);
- else
- DEBUG(0,("No dptrs available to idle??\n"));
-}
-
-/****************************************************************************
-get the dir ptr for a dir index
-****************************************************************************/
-static void *dptr_get(int key,uint32 lastused)
-{
- struct dptr_struct *dp = &dirptrs[key];
-
- if (dp->valid) {
- if (lastused) dp->lastused = lastused;
- if (!dp->ptr) {
- if (dptrs_open >= MAXDIR)
- dptr_idleoldest();
- DEBUG(4,("Reopening dptr key %d\n",key));
- if ((dp->ptr = OpenDir(dp->cnum, dp->path, True)))
- dptrs_open++;
- }
- return(dp->ptr);
- }
- return(NULL);
-}
-
-/****************************************************************************
-get the dir path for a dir index
-****************************************************************************/
-char *dptr_path(int key)
-{
- if (dirptrs[key].valid)
- return(dirptrs[key].path);
- return(NULL);
-}
-
-/****************************************************************************
-get the dir wcard for a dir index (lanman2 specific)
-****************************************************************************/
-char *dptr_wcard(int key)
-{
- if (dirptrs[key].valid)
- return(dirptrs[key].wcard);
- return(NULL);
-}
-
-/****************************************************************************
-set the dir wcard for a dir index (lanman2 specific)
-Returns 0 on ok, 1 on fail.
-****************************************************************************/
-BOOL dptr_set_wcard(int key, char *wcard)
-{
- if (dirptrs[key].valid) {
- dirptrs[key].wcard = wcard;
- return True;
- }
- return False;
-}
-
-/****************************************************************************
-set the dir attrib for a dir index (lanman2 specific)
-Returns 0 on ok, 1 on fail.
-****************************************************************************/
-BOOL dptr_set_attr(int key, uint16 attr)
-{
- if (dirptrs[key].valid) {
- dirptrs[key].attr = attr;
- return True;
- }
- return False;
-}
-
-/****************************************************************************
-get the dir attrib for a dir index (lanman2 specific)
-****************************************************************************/
-uint16 dptr_attr(int key)
-{
- if (dirptrs[key].valid)
- return(dirptrs[key].attr);
- return(0);
-}
-
-/****************************************************************************
-close a dptr
-****************************************************************************/
-void dptr_close(int key)
-{
- /* OS/2 seems to use -1 to indicate "close all directories" */
- if (key == -1) {
- int i;
- for (i=0;i<NUMDIRPTRS;i++)
- dptr_close(i);
- return;
- }
-
- if (key < 0 || key >= NUMDIRPTRS) {
- DEBUG(3,("Invalid key %d given to dptr_close\n",key));
- return;
- }
-
- if (dirptrs[key].valid) {
- DEBUG(4,("closing dptr key %d\n",key));
- if (dirptrs[key].ptr) {
- CloseDir(dirptrs[key].ptr);
- dptrs_open--;
- }
- /* Lanman 2 specific code */
- if (dirptrs[key].wcard)
- free(dirptrs[key].wcard);
- dirptrs[key].valid = False;
- string_set(&dirptrs[key].path,"");
- }
-}
-
-/****************************************************************************
-close all dptrs for a cnum
-****************************************************************************/
-void dptr_closecnum(int cnum)
-{
- int i;
- for (i=0;i<NUMDIRPTRS;i++)
- if (dirptrs[i].valid && dirptrs[i].cnum == cnum)
- dptr_close(i);
-}
-
-/****************************************************************************
-idle all dptrs for a cnum
-****************************************************************************/
-void dptr_idlecnum(int cnum)
-{
- int i;
- for (i=0;i<NUMDIRPTRS;i++)
- if (dirptrs[i].valid && dirptrs[i].cnum == cnum && dirptrs[i].ptr)
- dptr_idle(i);
-}
-
-/****************************************************************************
-close a dptr that matches a given path, only if it matches the pid also
-****************************************************************************/
-void dptr_closepath(char *path,int pid)
-{
- int i;
- for (i=0;i<NUMDIRPTRS;i++)
- if (dirptrs[i].valid && pid == dirptrs[i].pid &&
- strequal(dirptrs[i].path,path))
- dptr_close(i);
-}
-
-/****************************************************************************
- start a directory listing
-****************************************************************************/
-static BOOL start_dir(int cnum,char *directory)
-{
- DEBUG(5,("start_dir cnum=%d dir=%s\n",cnum,directory));
-
- if (!check_name(directory,cnum))
- return(False);
-
- if (! *directory)
- directory = ".";
-
- Connections[cnum].dirptr = OpenDir(cnum, directory, True);
- if (Connections[cnum].dirptr) {
- dptrs_open++;
- string_set(&Connections[cnum].dirpath,directory);
- return(True);
- }
-
- return(False);
-}
-
-
-/****************************************************************************
-create a new dir ptr
-****************************************************************************/
-int dptr_create(int cnum,char *path, BOOL expect_close,int pid)
-{
- int i;
- uint32 old;
- int oldi;
-
- if (!start_dir(cnum,path))
- return(-2); /* Code to say use a unix error return code. */
-
- if (dptrs_open >= MAXDIR)
- dptr_idleoldest();
-
- for (i=0;i<NUMDIRPTRS;i++)
- if (!dirptrs[i].valid)
- break;
- if (i == NUMDIRPTRS) i = -1;
-
-
- /* as a 2nd option, grab the oldest not marked for expect_close */
- if (i == -1) {
- old=dircounter+1;
- oldi= -1;
- for (i=0;i<NUMDIRPTRS;i++)
- if (!dirptrs[i].expect_close && dirptrs[i].lastused < old) {
- old = dirptrs[i].lastused;
- oldi = i;
- }
- i = oldi;
- }
-
- /* a 3rd option - grab the oldest one */
- if (i == -1) {
- old=dircounter+1;
- oldi= -1;
- for (i=0;i<NUMDIRPTRS;i++)
- if (dirptrs[i].lastused < old) {
- old = dirptrs[i].lastused;
- oldi = i;
- }
- i = oldi;
- }
-
- if (i == -1) {
- DEBUG(0,("Error - all dirptrs in use??\n"));
- return(-1);
- }
-
- if (dirptrs[i].valid)
- dptr_close(i);
-
- dirptrs[i].ptr = Connections[cnum].dirptr;
- string_set(&dirptrs[i].path,path);
- dirptrs[i].lastused = dircounter++;
- dirptrs[i].finished = False;
- dirptrs[i].cnum = cnum;
- dirptrs[i].pid = pid;
- dirptrs[i].expect_close = expect_close;
- dirptrs[i].wcard = NULL; /* Only used in lanman2 searches */
- dirptrs[i].attr = 0; /* Only used in lanman2 searches */
- dirptrs[i].valid = True;
-
- DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n",
- i,path,expect_close));
-
- return(i);
-}
-
-#define DPTR_MASK ((uint32)(((uint32)1)<<31))
-
-/****************************************************************************
-fill the 5 byte server reserved dptr field
-****************************************************************************/
-BOOL dptr_fill(char *buf1,unsigned int key)
-{
- unsigned char *buf = (unsigned char *)buf1;
- void *p = dptr_get(key,0);
- uint32 offset;
- if (!p) {
- DEBUG(1,("filling null dirptr %d\n",key));
- return(False);
- }
- offset = TellDir(p);
- DEBUG(6,("fill on key %d dirptr 0x%x now at %d\n",key,p,offset));
- buf[0] = key;
- SIVAL(buf,1,offset | DPTR_MASK);
- return(True);
-}
-
-
-/****************************************************************************
-return True is the offset is at zero
-****************************************************************************/
-BOOL dptr_zero(char *buf)
-{
- return((IVAL(buf,1)&~DPTR_MASK) == 0);
-}
-
-/****************************************************************************
-fetch the dir ptr and seek it given the 5 byte server field
-****************************************************************************/
-void *dptr_fetch(char *buf,int *num)
-{
- unsigned int key = *(unsigned char *)buf;
- void *p = dptr_get(key,dircounter++);
- uint32 offset;
- if (!p) {
- DEBUG(3,("fetched null dirptr %d\n",key));
- return(NULL);
- }
- *num = key;
- offset = IVAL(buf,1)&~DPTR_MASK;
- SeekDir(p,offset);
- DEBUG(3,("fetching dirptr %d for path %s at offset %d\n",
- key,dptr_path(key),offset));
- return(p);
-}
-
-/****************************************************************************
-fetch the dir ptr and seek it given the lanman2 parameter block
-****************************************************************************/
-void *dptr_fetch_lanman2(char *params,int dptr_num)
-{
- void *p = dptr_get(dptr_num,dircounter++);
- uint32 resume_key = SVAL(params,6);
- BOOL uses_resume_key = BITSETW(params+10,2);
- BOOL continue_bit = BITSETW(params+10,3);
-
- if (!p) {
- DEBUG(3,("fetched null dirptr %d\n",dptr_num));
- return(NULL);
- }
- if(uses_resume_key && !continue_bit)
- SeekDir(p,resume_key);
- DEBUG(3,("fetching dirptr %d for path %s\n",dptr_num,dptr_path(dptr_num)));
- return(p);
-}
-
-/****************************************************************************
-check a filetype for being valid
-****************************************************************************/
-BOOL dir_check_ftype(int cnum,int mode,struct stat *st,int dirtype)
-{
- if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0)
- return False;
- return True;
-}
-
-/****************************************************************************
- get a directory entry
-****************************************************************************/
-BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mode,time_t *date,BOOL check_descend)
-{
- char *dname;
- BOOL found = False;
- struct stat sbuf;
- pstring path;
- pstring pathreal;
- BOOL isrootdir;
- pstring filename;
- BOOL matched;
- BOOL needslash;
-
- *path = *pathreal = *filename = 0;
-
- isrootdir = (strequal(Connections[cnum].dirpath,"./") ||
- strequal(Connections[cnum].dirpath,".") ||
- strequal(Connections[cnum].dirpath,"/"));
-
- needslash =
- ( Connections[cnum].dirpath[strlen(Connections[cnum].dirpath) -1] != '/');
-
- if (!Connections[cnum].dirptr)
- return(False);
-
- while (!found)
- {
- dname = ReadDirName(Connections[cnum].dirptr);
-
- DEBUG(6,("readdir on dirptr 0x%x now at offset %d\n",
- Connections[cnum].dirptr,TellDir(Connections[cnum].dirptr)));
-
- if (dname == NULL)
- return(False);
-
- matched = False;
-
- pstrcpy(filename,dname);
-
- if ((strcmp(filename,mask) == 0) ||
- (name_map_mangle(filename,True,SNUM(cnum)) &&
- mask_match(filename,mask,False,False)))
- {
- if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
- continue;
-
- pstrcpy(fname,filename);
- *path = 0;
- pstrcpy(path,Connections[cnum].dirpath);
- if(needslash)
- strcat(path,"/");
- pstrcpy(pathreal,path);
- strcat(path,fname);
- strcat(pathreal,dname);
- if (sys_stat(pathreal,&sbuf) != 0)
- {
- DEBUG(5,("Couldn't stat 1 [%s]\n",path));
- continue;
- }
-
- if (check_descend &&
- !strequal(fname,".") && !strequal(fname,".."))
- continue;
-
- *mode = dos_mode(cnum,pathreal,&sbuf);
-
- if (!dir_check_ftype(cnum,*mode,&sbuf,dirtype)) {
- DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype));
- continue;
- }
-
- *size = sbuf.st_size;
- *date = sbuf.st_mtime;
-
- DEBUG(5,("get_dir_entry found %s fname=%s\n",pathreal,fname));
-
- found = True;
- }
- }
-
- return(found);
-}
-
-
-
-typedef struct
-{
- int pos;
- int numentries;
- int mallocsize;
- char *data;
- char *current;
-} Dir;
-
-
-/*******************************************************************
-open a directory
-********************************************************************/
-void *OpenDir(int cnum, char *name, BOOL use_veto)
-{
- Dir *dirp;
- char *n;
- void *p = sys_opendir(name);
- int used=0;
-
- if (!p) return(NULL);
- dirp = (Dir *)malloc(sizeof(Dir));
- if (!dirp) {
- closedir(p);
- return(NULL);
- }
- dirp->pos = dirp->numentries = dirp->mallocsize = 0;
- dirp->data = dirp->current = NULL;
-
- while ((n = readdirname(p)))
- {
- int l = strlen(n)+1;
-
- /* If it's a vetoed file, pretend it doesn't even exist */
- if (use_veto && IS_VETO_PATH(cnum, n)) continue;
-
- if (used + l > dirp->mallocsize) {
- int s = MAX(used+l,used+2000);
- char *r;
- r = (char *)Realloc(dirp->data,s);
- if (!r) {
- DEBUG(0,("Out of memory in OpenDir\n"));
- break;
- }
- dirp->data = r;
- dirp->mallocsize = s;
- dirp->current = dirp->data;
- }
- strcpy(dirp->data+used,n);
- used += l;
- dirp->numentries++;
- }
-
- closedir(p);
- return((void *)dirp);
-}
-
-
-/*******************************************************************
-close a directory
-********************************************************************/
-void CloseDir(void *p)
-{
- Dir *dirp = (Dir *)p;
- if (!dirp) return;
- if (dirp->data) free(dirp->data);
- free(dirp);
-}
-
-/*******************************************************************
-read from a directory
-********************************************************************/
-char *ReadDirName(void *p)
-{
- char *ret;
- Dir *dirp = (Dir *)p;
-
- if (!dirp || !dirp->current || dirp->pos >= dirp->numentries) return(NULL);
-
- ret = dirp->current;
- dirp->current = skip_string(dirp->current,1);
- dirp->pos++;
-
- return(ret);
-}
-
-
-/*******************************************************************
-seek a dir
-********************************************************************/
-BOOL SeekDir(void *p,int pos)
-{
- Dir *dirp = (Dir *)p;
-
- if (!dirp) return(False);
-
- if (pos < dirp->pos) {
- dirp->current = dirp->data;
- dirp->pos = 0;
- }
-
- while (dirp->pos < pos && ReadDirName(p)) ;
-
- return(dirp->pos == pos);
-}
-
-/*******************************************************************
-tell a dir position
-********************************************************************/
-int TellDir(void *p)
-{
- Dir *dirp = (Dir *)p;
-
- if (!dirp) return(-1);
-
- return(dirp->pos);
-}
-
-
-static int dir_cache_size = 0;
-static struct dir_cache {
- struct dir_cache *next;
- struct dir_cache *prev;
- char *path;
- char *name;
- char *dname;
- int snum;
-} *dir_cache = NULL;
-
-/*******************************************************************
-add an entry to the directory cache
-********************************************************************/
-void DirCacheAdd(char *path,char *name,char *dname,int snum)
-{
- int count;
- struct dir_cache *entry = (struct dir_cache *)malloc(sizeof(*entry));
- if (!entry) return;
- entry->path = strdup(path);
- entry->name = strdup(name);
- entry->dname = strdup(dname);
- entry->snum = snum;
- if (!entry->path || !entry->name || !entry->dname) return;
-
- entry->next = dir_cache;
- entry->prev = NULL;
- if (entry->next) entry->next->prev = entry;
- dir_cache = entry;
-
- DEBUG(4,("Added dir cache entry %s %s -> %s\n",path,name,dname));
-
- if (dir_cache_size == DIRCACHESIZE) {
- for (entry=dir_cache, count=1;
- entry->next && count < dir_cache_size + 1;
- entry=entry->next, count++) ;
- if (entry->next || count != dir_cache_size + 1) {
- DEBUG(0,("DirCache bug - please report %d %d\n",dir_cache_size,count));
- }
- free(entry->path);
- free(entry->name);
- free(entry->dname);
- if (entry->prev) entry->prev->next = entry->next;
- free(entry);
- } else {
- dir_cache_size++;
- }
-}
-
-
-/*******************************************************************
-check for an entry in the directory cache
-********************************************************************/
-char *DirCacheCheck(char *path,char *name,int snum)
-{
- struct dir_cache *entry;
-
- for (entry=dir_cache; entry; entry=entry->next) {
- if (entry->snum == snum &&
- strcmp(path,entry->path) == 0 &&
- strcmp(name,entry->name) == 0) {
- DEBUG(4,("Got dir cache hit on %s %s -> %s\n",path,name,entry->dname));
- return(entry->dname);
- }
- }
-
- return(NULL);
-}
-
-/*******************************************************************
-flush entries in the dir_cache
-********************************************************************/
-void DirCacheFlush(int snum)
-{
- struct dir_cache *entry,*next;
-
- for (entry=dir_cache; entry; entry=next) {
- if (entry->snum == snum) {
- free(entry->path);
- free(entry->dname);
- free(entry->name);
- next = entry->next;
- if (entry->prev) entry->prev->next = entry->next;
- if (entry->next) entry->next->prev = entry->prev;
- if (dir_cache == entry) dir_cache = entry->next;
- free(entry);
- dir_cache_size--;
- } else {
- next = entry->next;
- }
- }
-}
-
-
-#ifdef REPLACE_GETWD
-/* This is getcwd.c from bash. It is needed in Interactive UNIX. To
- * add support for another OS you need to determine which of the
- * conditional compilation macros you need to define. All the options
- * are defined for Interactive UNIX.
- */
-#ifdef ISC
-#define HAVE_UNISTD_H
-#define USGr3
-#define USG
-#endif
-
-#if defined (HAVE_UNISTD_H)
-# include <unistd.h>
-#endif
-
-#if defined (__STDC__)
-# define CONST const
-# define PTR void *
-#else /* !__STDC__ */
-# define CONST
-# define PTR char *
-#endif /* !__STDC__ */
-
-#if !defined (PATH_MAX)
-# if defined (MAXPATHLEN)
-# define PATH_MAX MAXPATHLEN
-# else /* !MAXPATHLEN */
-# define PATH_MAX 1024
-# endif /* !MAXPATHLEN */
-#endif /* !PATH_MAX */
-
-#if defined (_POSIX_VERSION) || defined (USGr3) || defined (HAVE_DIRENT_H)
-# if !defined (HAVE_DIRENT)
-# define HAVE_DIRENT
-# endif /* !HAVE_DIRENT */
-#endif /* _POSIX_VERSION || USGr3 || HAVE_DIRENT_H */
-
-#if defined (HAVE_DIRENT)
-# define D_NAMLEN(d) (strlen ((d)->d_name))
-#else
-# define D_NAMLEN(d) ((d)->d_namlen)
-#endif /* ! (_POSIX_VERSION || USGr3) */
-
-#if defined (USG) || defined (USGr3)
-# define d_fileno d_ino
-#endif
-
-#if !defined (alloca)
-extern char *alloca ();
-#endif /* alloca */
-
-/* Get the pathname of the current working directory,
- and put it in SIZE bytes of BUF. Returns NULL if the
- directory couldn't be determined or SIZE was too small.
- If successful, returns BUF. In GNU, if BUF is NULL,
- an array is allocated with `malloc'; the array is SIZE
- bytes long, unless SIZE <= 0, in which case it is as
- big as necessary. */
-#if defined (__STDC__)
-char *
-getcwd (char *buf, size_t size)
-#else /* !__STDC__ */
-char *
-getcwd (buf, size)
- char *buf;
- int size;
-#endif /* !__STDC__ */
-{
- static CONST char dots[]
- = "../../../../../../../../../../../../../../../../../../../../../../../\
-../../../../../../../../../../../../../../../../../../../../../../../../../../\
-../../../../../../../../../../../../../../../../../../../../../../../../../..";
- CONST char *dotp, *dotlist;
- size_t dotsize;
- dev_t rootdev, thisdev;
- ino_t rootino, thisino;
- char path[PATH_MAX + 1];
- register char *pathp;
- char *pathbuf;
- size_t pathsize;
- struct stat st;
-
- if (buf != NULL && size == 0)
- {
- errno = EINVAL;
- return ((char *)NULL);
- }
-
- pathsize = sizeof (path);
- pathp = &path[pathsize];
- *--pathp = '\0';
- pathbuf = path;
-
- if (stat (".", &st) < 0)
- return ((char *)NULL);
- thisdev = st.st_dev;
- thisino = st.st_ino;
-
- if (stat ("/", &st) < 0)
- return ((char *)NULL);
- rootdev = st.st_dev;
- rootino = st.st_ino;
-
- dotsize = sizeof (dots) - 1;
- dotp = &dots[sizeof (dots)];
- dotlist = dots;
- while (!(thisdev == rootdev && thisino == rootino))
- {
- register DIR *dirstream;
- register struct dirent *d;
- dev_t dotdev;
- ino_t dotino;
- char mount_point;
- int namlen;
-
- /* Look at the parent directory. */
- if (dotp == dotlist)
- {
- /* My, what a deep directory tree you have, Grandma. */
- char *new;
- if (dotlist == dots)
- {
- new = malloc (dotsize * 2 + 1);
- if (new == NULL)
- goto lose;
- memcpy (new, dots, dotsize);
- }
- else
- {
- new = realloc ((PTR) dotlist, dotsize * 2 + 1);
- if (new == NULL)
- goto lose;
- }
- memcpy (&new[dotsize], new, dotsize);
- dotp = &new[dotsize];
- dotsize *= 2;
- new[dotsize] = '\0';
- dotlist = new;
- }
-
- dotp -= 3;
-
- /* Figure out if this directory is a mount point. */
- if (stat (dotp, &st) < 0)
- goto lose;
- dotdev = st.st_dev;
- dotino = st.st_ino;
- mount_point = dotdev != thisdev;
-
- /* Search for the last directory. */
- dirstream = opendir(dotp);
- if (dirstream == NULL)
- goto lose;
- while ((d = (struct dirent *)readdir(dirstream)) != NULL)
- {
- if (d->d_name[0] == '.' &&
- (d->d_name[1] == '\0' ||
- (d->d_name[1] == '.' && d->d_name[2] == '\0')))
- continue;
- if (mount_point || d->d_fileno == thisino)
- {
- char *name;
-
- namlen = D_NAMLEN(d);
- name = (char *)
- alloca (dotlist + dotsize - dotp + 1 + namlen + 1);
- memcpy (name, dotp, dotlist + dotsize - dotp);
- name[dotlist + dotsize - dotp] = '/';
- memcpy (&name[dotlist + dotsize - dotp + 1],
- d->d_name, namlen + 1);
- if (lstat (name, &st) < 0)
- {
- int save = errno;
- closedir(dirstream);
- errno = save;
- goto lose;
- }
- if (st.st_dev == thisdev && st.st_ino == thisino)
- break;
- }
- }
- if (d == NULL)
- {
- int save = errno;
- closedir(dirstream);
- errno = save;
- goto lose;
- }
- else
- {
- size_t space;
-
- while ((space = pathp - pathbuf) <= namlen)
- {
- char *new;
-
- if (pathbuf == path)
- {
- new = malloc (pathsize * 2);
- if (!new)
- goto lose;
- }
- else
- {
- new = realloc ((PTR) pathbuf, (pathsize * 2));
- if (!new)
- goto lose;
- pathp = new + space;
- }
- (void) memcpy (new + pathsize + space, pathp, pathsize - space);
- pathp = new + pathsize + space;
- pathbuf = new;
- pathsize *= 2;
- }
-
- pathp -= namlen;
- (void) memcpy (pathp, d->d_name, namlen);
- *--pathp = '/';
- closedir(dirstream);
- }
-
- thisdev = dotdev;
- thisino = dotino;
- }
-
- if (pathp == &path[sizeof(path) - 1])
- *--pathp = '/';
-
- if (dotlist != dots)
- free ((PTR) dotlist);
-
- {
- size_t len = pathbuf + pathsize - pathp;
- if (buf == NULL)
- {
- if (len < (size_t) size)
- len = size;
- buf = (char *) malloc (len);
- if (buf == NULL)
- goto lose2;
- }
- else if ((size_t) size < len)
- {
- errno = ERANGE;
- goto lose2;
- }
- (void) memcpy((PTR) buf, (PTR) pathp, len);
- }
-
- if (pathbuf != path)
- free (pathbuf);
-
- return (buf);
-
- lose:
- if ((dotlist != dots) && dotlist)
- {
- int e = errno;
- free ((PTR) dotlist);
- errno = e;
- }
-
- lose2:
- if ((pathbuf != path) && pathbuf)
- {
- int e = errno;
- free ((PTR) pathbuf);
- errno = e;
- }
- return ((char *)NULL);
-}
-#endif
diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c
deleted file mode 100644
index 28cdb22889a..00000000000
--- a/source/smbd/ipc.c
+++ /dev/null
@@ -1,3133 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Inter-process communication and named pipe handling
- Copyright (C) Andrew Tridgell 1992-1997
-
- SMB Version handling
- Copyright (C) John H Terpstra 1995-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.
- */
-/*
- This file handles the named pipe and mailslot calls
- in the SMBtrans protocol
- */
-
-#include "includes.h"
-
-#ifdef CHECK_TYPES
-#undef CHECK_TYPES
-#endif
-#define CHECK_TYPES 0
-
-extern int DEBUGLEVEL;
-extern int max_send;
-extern files_struct Files[];
-extern connection_struct Connections[];
-
-extern fstring local_machine;
-extern fstring myworkgroup;
-
-#define NERR_Success 0
-#define NERR_badpass 86
-#define NERR_notsupported 50
-
-#define NERR_BASE (2100)
-#define NERR_BufTooSmall (NERR_BASE+23)
-#define NERR_JobNotFound (NERR_BASE+51)
-#define NERR_DestNotFound (NERR_BASE+52)
-#define ERROR_INVALID_LEVEL 124
-#define ERROR_MORE_DATA 234
-
-#define REALLOC(ptr,size) Realloc(ptr,MAX((size),4*1024))
-
-#define ACCESS_READ 0x01
-#define ACCESS_WRITE 0x02
-#define ACCESS_CREATE 0x04
-
-#define SHPWLEN 8 /* share password length */
-#define NNLEN 12 /* 8.3 net name length */
-#define SNLEN 15 /* service name length */
-#define QNLEN 12 /* queue name maximum length */
-
-extern int Client;
-
-static BOOL api_Unsupported(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len);
-static BOOL api_TooSmall(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len);
-
-
-static int CopyExpanded(int cnum, int snum, char** dst, char* src, int* n)
-{
- pstring buf;
- int l;
-
- if (!src || !dst || !n || !(*dst)) return(0);
-
- StrnCpy(buf,src,sizeof(buf)/2);
- string_sub(buf,"%S",lp_servicename(snum));
- standard_sub(cnum,buf);
- StrnCpy(*dst,buf,*n);
- l = strlen(*dst) + 1;
- (*dst) += l;
- (*n) -= l;
- return l;
-}
-
-static int CopyAndAdvance(char** dst, char* src, int* n)
-{
- int l;
- if (!src || !dst || !n || !(*dst)) return(0);
- StrnCpy(*dst,src,*n);
- l = strlen(*dst) + 1;
- (*dst) += l;
- (*n) -= l;
- return l;
-}
-
-static int StrlenExpanded(int cnum, int snum, char* s)
-{
- pstring buf;
- if (!s) return(0);
- StrnCpy(buf,s,sizeof(buf)/2);
- string_sub(buf,"%S",lp_servicename(snum));
- standard_sub(cnum,buf);
- return strlen(buf) + 1;
-}
-
-static char* Expand(int cnum, int snum, char* s)
-{
- static pstring buf;
- if (!s) return(NULL);
- StrnCpy(buf,s,sizeof(buf)/2);
- string_sub(buf,"%S",lp_servicename(snum));
- standard_sub(cnum,buf);
- return &buf[0];
-}
-
-/*******************************************************************
- check a API string for validity when we only need to check the prefix
- ******************************************************************/
-static BOOL prefix_ok(char *str,char *prefix)
-{
- return(strncmp(str,prefix,strlen(prefix)) == 0);
-}
-
-
-/****************************************************************************
- send a trans reply
- ****************************************************************************/
-static void send_trans_reply(char *outbuf,char *data,char *param,uint16 *setup,
- int ldata,int lparam,int lsetup)
-{
- int i;
- int this_ldata,this_lparam;
- int tot_data=0,tot_param=0;
- int align;
-
- this_lparam = MIN(lparam,max_send - (500+lsetup*SIZEOFWORD)); /* hack */
- this_ldata = MIN(ldata,max_send - (500+lsetup*SIZEOFWORD+this_lparam));
-
- align = (this_lparam%4);
-
- set_message(outbuf,10+lsetup,align+this_ldata+this_lparam,True);
- if (this_lparam)
- memcpy(smb_buf(outbuf),param,this_lparam);
- if (this_ldata)
- memcpy(smb_buf(outbuf)+this_lparam+align,data,this_ldata);
-
- SSVAL(outbuf,smb_vwv0,lparam);
- SSVAL(outbuf,smb_vwv1,ldata);
- SSVAL(outbuf,smb_vwv3,this_lparam);
- SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf),outbuf));
- SSVAL(outbuf,smb_vwv5,0);
- SSVAL(outbuf,smb_vwv6,this_ldata);
- SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+this_lparam+align,outbuf));
- SSVAL(outbuf,smb_vwv8,0);
- SSVAL(outbuf,smb_vwv9,lsetup);
- for (i=0;i<lsetup;i++)
- SSVAL(outbuf,smb_vwv10+i*SIZEOFWORD,setup[i]);
-
- show_msg(outbuf);
- send_smb(Client,outbuf);
-
- tot_data = this_ldata;
- tot_param = this_lparam;
-
- while (tot_data < ldata || tot_param < lparam)
- {
- this_lparam = MIN(lparam-tot_param,max_send - 500); /* hack */
- this_ldata = MIN(ldata-tot_data,max_send - (500+this_lparam));
-
- align = (this_lparam%4);
-
- set_message(outbuf,10,this_ldata+this_lparam+align,False);
- if (this_lparam)
- memcpy(smb_buf(outbuf),param+tot_param,this_lparam);
- if (this_ldata)
- memcpy(smb_buf(outbuf)+this_lparam+align,data+tot_data,this_ldata);
-
- SSVAL(outbuf,smb_vwv3,this_lparam);
- SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf),outbuf));
- SSVAL(outbuf,smb_vwv5,tot_param);
- SSVAL(outbuf,smb_vwv6,this_ldata);
- SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+this_lparam+align,outbuf));
- SSVAL(outbuf,smb_vwv8,tot_data);
- SSVAL(outbuf,smb_vwv9,0);
-
- show_msg(outbuf);
- send_smb(Client,outbuf);
-
- tot_data += this_ldata;
- tot_param += this_lparam;
- }
-}
-
-struct pack_desc {
- char* format; /* formatstring for structure */
- char* subformat; /* subformat for structure */
- char* base; /* baseaddress of buffer */
- int buflen; /* remaining size for fixed part; on init: length of base */
- int subcount; /* count of substructures */
- char* structbuf; /* pointer into buffer for remaining fixed part */
- int stringlen; /* remaining size for variable part */
- char* stringbuf; /* pointer into buffer for remaining variable part */
- int neededlen; /* total needed size */
- int usedlen; /* total used size (usedlen <= neededlen and usedlen <= buflen) */
- char* curpos; /* current position; pointer into format or subformat */
- int errcode;
-};
-
-static int get_counter(char** p)
-{
- int i, n;
- if (!p || !(*p)) return(1);
- if (!isdigit(**p)) return 1;
- for (n = 0;;) {
- i = **p;
- if (isdigit(i))
- n = 10 * n + (i - '0');
- else
- return n;
- (*p)++;
- }
-}
-
-static int getlen(char* p)
-{
- int n = 0;
- if (!p) return(0);
- while (*p) {
- switch( *p++ ) {
- case 'W': /* word (2 byte) */
- n += 2;
- break;
- case 'N': /* count of substructures (word) at end */
- n += 2;
- break;
- case 'D': /* double word (4 byte) */
- case 'z': /* offset to zero terminated string (4 byte) */
- case 'l': /* offset to user data (4 byte) */
- n += 4;
- break;
- case 'b': /* offset to data (with counter) (4 byte) */
- n += 4;
- get_counter(&p);
- break;
- case 'B': /* byte (with optional counter) */
- n += get_counter(&p);
- break;
- }
- }
- return n;
-}
-
-static BOOL init_package(struct pack_desc* p, int count, int subcount)
-{
- int n = p->buflen;
- int i;
-
- if (!p->format || !p->base) return(False);
-
- i = count * getlen(p->format);
- if (p->subformat) i += subcount * getlen(p->subformat);
- p->structbuf = p->base;
- p->neededlen = 0;
- p->usedlen = 0;
- p->subcount = 0;
- p->curpos = p->format;
- if (i > n) {
- i = n = 0;
- p->errcode = NERR_BufTooSmall;
- }
-
- p->errcode = NERR_Success;
- p->buflen = i;
- n -= i;
- p->stringbuf = p->base + i;
- p->stringlen = n;
- return(p->errcode == NERR_Success);
-}
-
-#ifdef __STDC__
-static int package(struct pack_desc* p, ...)
-{
-#else
-static int package(va_alist)
-va_dcl
-{
- struct pack_desc* p;
-#endif
- va_list args;
- int needed=0, stringneeded;
- char* str=NULL;
- int is_string=0, stringused;
- int32 temp;
-
-#ifdef __STDC__
- va_start(args,p);
-#else
- va_start(args);
- p = va_arg(args,struct pack_desc *);
-#endif
-
- if (!*p->curpos) {
- if (!p->subcount)
- p->curpos = p->format;
- else {
- p->curpos = p->subformat;
- p->subcount--;
- }
- }
-#if CHECK_TYPES
- str = va_arg(args,char*);
- if (strncmp(str,p->curpos,strlen(str)) != 0) {
- DEBUG(2,("type error in package: %s instead of %*s\n",str,
- strlen(str),p->curpos));
- va_end(args);
-#if AJT
- ajt_panic();
-#endif
- return 0;
- }
-#endif
- stringneeded = -1;
-
- if (!p->curpos) return(0);
-
- switch( *p->curpos++ ) {
- case 'W': /* word (2 byte) */
- needed = 2;
- temp = va_arg(args,int);
- if (p->buflen >= needed) SSVAL(p->structbuf,0,temp);
- break;
- case 'N': /* count of substructures (word) at end */
- needed = 2;
- p->subcount = va_arg(args,int);
- if (p->buflen >= needed) SSVAL(p->structbuf,0,p->subcount);
- break;
- case 'D': /* double word (4 byte) */
- needed = 4;
- temp = va_arg(args,int);
- if (p->buflen >= needed) SIVAL(p->structbuf,0,temp);
- break;
- case 'B': /* byte (with optional counter) */
- needed = get_counter(&p->curpos);
- {
- char *s = va_arg(args,char*);
- if (p->buflen >= needed) StrnCpy(p->structbuf,s?s:"",needed);
- }
- break;
- case 'z': /* offset to zero terminated string (4 byte) */
- str = va_arg(args,char*);
- stringneeded = (str ? strlen(str)+1 : 0);
- is_string = 1;
- break;
- case 'l': /* offset to user data (4 byte) */
- str = va_arg(args,char*);
- stringneeded = va_arg(args,int);
- is_string = 0;
- break;
- case 'b': /* offset to data (with counter) (4 byte) */
- str = va_arg(args,char*);
- stringneeded = get_counter(&p->curpos);
- is_string = 0;
- break;
- }
- va_end(args);
- if (stringneeded >= 0) {
- needed = 4;
- if (p->buflen >= needed) {
- stringused = stringneeded;
- if (stringused > p->stringlen) {
- stringused = (is_string ? p->stringlen : 0);
- if (p->errcode == NERR_Success) p->errcode = ERROR_MORE_DATA;
- }
- if (!stringused)
- SIVAL(p->structbuf,0,0);
- else {
- SIVAL(p->structbuf,0,PTR_DIFF(p->stringbuf,p->base));
- memcpy(p->stringbuf,str?str:"",stringused);
- if (is_string) p->stringbuf[stringused-1] = '\0';
- p->stringbuf += stringused;
- p->stringlen -= stringused;
- p->usedlen += stringused;
- }
- }
- p->neededlen += stringneeded;
- }
- p->neededlen += needed;
- if (p->buflen >= needed) {
- p->structbuf += needed;
- p->buflen -= needed;
- p->usedlen += needed;
- }
- else {
- if (p->errcode == NERR_Success) p->errcode = NERR_BufTooSmall;
- }
- return 1;
-}
-
-#if CHECK_TYPES
-#define PACK(desc,t,v) package(desc,t,v,0,0,0,0)
-#define PACKl(desc,t,v,l) package(desc,t,v,l,0,0,0,0)
-#else
-#define PACK(desc,t,v) package(desc,v)
-#define PACKl(desc,t,v,l) package(desc,v,l)
-#endif
-
-static void PACKI(struct pack_desc* desc,char *t,int v)
-{
- PACK(desc,t,v);
-}
-
-static void PACKS(struct pack_desc* desc,char *t,char *v)
-{
- PACK(desc,t,v);
-}
-
-
-/****************************************************************************
- get a print queue
- ****************************************************************************/
-
-static void PackDriverData(struct pack_desc* desc)
-{
- char drivdata[4+4+32];
- SIVAL(drivdata,0,sizeof drivdata); /* cb */
- SIVAL(drivdata,4,1000); /* lVersion */
- memset(drivdata+8,0,32); /* szDeviceName */
- strcpy(drivdata+8,"NULL");
- PACKl(desc,"l",drivdata,sizeof drivdata); /* pDriverData */
-}
-
-static int check_printq_info(struct pack_desc* desc,
- int uLevel, char *id1, char *id2)
-{
- desc->subformat = NULL;
- switch( uLevel ) {
- case 0:
- desc->format = "B13";
- break;
- case 1:
- desc->format = "B13BWWWzzzzzWW";
- break;
- case 2:
- desc->format = "B13BWWWzzzzzWN";
- desc->subformat = "WB21BB16B10zWWzDDz";
- break;
- case 3:
- desc->format = "zWWWWzzzzWWzzl";
- break;
- case 4:
- desc->format = "zWWWWzzzzWNzzl";
- desc->subformat = "WWzWWDDzz";
- break;
- case 5:
- desc->format = "z";
- break;
- default: return False;
- }
- if (strcmp(desc->format,id1) != 0) return False;
- if (desc->subformat && strcmp(desc->subformat,id2) != 0) return False;
- return True;
-}
-
-static void fill_printjob_info(int cnum, int snum, int uLevel,
- struct pack_desc* desc,
- print_queue_struct* queue, int n)
-{
- time_t t = queue->time;
-
- /* the client expects localtime */
- t -= TimeDiff(t);
-
- PACKI(desc,"W",printjob_encode(snum, queue->job)); /* uJobId */
- if (uLevel == 1) {
- PACKS(desc,"B21",queue->user); /* szUserName */
- PACKS(desc,"B",""); /* pad */
- PACKS(desc,"B16",""); /* szNotifyName */
- PACKS(desc,"B10","PM_Q_RAW"); /* szDataType */
- PACKS(desc,"z",""); /* pszParms */
- PACKI(desc,"W",n+1); /* uPosition */
- PACKI(desc,"W",queue->status); /* fsStatus */
- PACKS(desc,"z",""); /* pszStatus */
- PACKI(desc,"D",t); /* ulSubmitted */
- PACKI(desc,"D",queue->size); /* ulSize */
- PACKS(desc,"z",queue->file); /* pszComment */
- }
- if (uLevel == 2 || uLevel == 3) {
- PACKI(desc,"W",queue->priority); /* uPriority */
- PACKS(desc,"z",queue->user); /* pszUserName */
- PACKI(desc,"W",n+1); /* uPosition */
- PACKI(desc,"W",queue->status); /* fsStatus */
- PACKI(desc,"D",t); /* ulSubmitted */
- PACKI(desc,"D",queue->size); /* ulSize */
- PACKS(desc,"z","Samba"); /* pszComment */
- PACKS(desc,"z",queue->file); /* pszDocument */
- if (uLevel == 3) {
- PACKS(desc,"z",""); /* pszNotifyName */
- PACKS(desc,"z","PM_Q_RAW"); /* pszDataType */
- PACKS(desc,"z",""); /* pszParms */
- PACKS(desc,"z",""); /* pszStatus */
- PACKS(desc,"z",SERVICE(snum)); /* pszQueue */
- PACKS(desc,"z","lpd"); /* pszQProcName */
- PACKS(desc,"z",""); /* pszQProcParms */
- PACKS(desc,"z","NULL"); /* pszDriverName */
- PackDriverData(desc); /* pDriverData */
- PACKS(desc,"z",""); /* pszPrinterName */
- }
- }
-}
-
-static void fill_printq_info(int cnum, int snum, int uLevel,
- struct pack_desc* desc,
- int count, print_queue_struct* queue,
- print_status_struct* status)
-{
- if (uLevel < 3) {
- PACKS(desc,"B13",SERVICE(snum));
- } else {
- PACKS(desc,"z",Expand(cnum,snum,SERVICE(snum)));
- }
- if (uLevel == 1 || uLevel == 2) {
- PACKS(desc,"B",""); /* alignment */
- PACKI(desc,"W",5); /* priority */
- PACKI(desc,"W",0); /* start time */
- PACKI(desc,"W",0); /* until time */
- PACKS(desc,"z",""); /* pSepFile */
- PACKS(desc,"z","lpd"); /* pPrProc */
- PACKS(desc,"z",SERVICE(snum)); /* pDestinations */
- PACKS(desc,"z",""); /* pParms */
- if (snum < 0) {
- PACKS(desc,"z","UNKNOWN PRINTER");
- PACKI(desc,"W",LPSTAT_ERROR);
- }
- else if (!status || !status->message[0]) {
- PACKS(desc,"z",Expand(cnum,snum,lp_comment(snum)));
- PACKI(desc,"W",LPSTAT_OK); /* status */
- } else {
- PACKS(desc,"z",status->message);
- PACKI(desc,"W",status->status); /* status */
- }
- PACKI(desc,(uLevel == 1 ? "W" : "N"),count);
- }
- if (uLevel == 3 || uLevel == 4) {
- PACKI(desc,"W",5); /* uPriority */
- PACKI(desc,"W",0); /* uStarttime */
- PACKI(desc,"W",0); /* uUntiltime */
- PACKI(desc,"W",5); /* pad1 */
- PACKS(desc,"z",""); /* pszSepFile */
- PACKS(desc,"z","WinPrint"); /* pszPrProc */
- PACKS(desc,"z",""); /* pszParms */
- if (!status || !status->message[0]) {
- PACKS(desc,"z",Expand(cnum,snum,lp_comment(snum))); /* pszComment */
- PACKI(desc,"W",LPSTAT_OK); /* fsStatus */
- } else {
- PACKS(desc,"z",status->message); /* pszComment */
- PACKI(desc,"W",status->status); /* fsStatus */
- }
- PACKI(desc,(uLevel == 3 ? "W" : "N"),count); /* cJobs */
- PACKS(desc,"z",SERVICE(snum)); /* pszPrinters */
- PACKS(desc,"z",lp_printerdriver(snum)); /* pszDriverName */
- PackDriverData(desc); /* pDriverData */
- }
- if (uLevel == 2 || uLevel == 4) {
- int i;
- for (i=0;i<count;i++)
- fill_printjob_info(cnum,snum,uLevel == 2 ? 1 : 2,desc,&queue[i],i);
- }
-
- DEBUG(3,("fill_printq_info on <%s> gave %d entries\n",SERVICE(snum),count));
-}
-
-static BOOL api_DosPrintQGetInfo(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- char *QueueName = p;
- int uLevel,cbBuf;
- int count=0;
- int snum;
- char* str3;
- struct pack_desc desc;
- print_queue_struct *queue=NULL;
- print_status_struct status;
-
- bzero(&status,sizeof(status));
- bzero(&desc,sizeof(desc));
-
- p = skip_string(p,1);
- uLevel = SVAL(p,0);
- cbBuf = SVAL(p,2);
- str3 = p + 4;
-
- /* remove any trailing username */
- if ((p = strchr(QueueName,'%'))) *p = 0;
-
- DEBUG(3,("PrintQueue uLevel=%d name=%s\n",uLevel,QueueName));
-
- /* check it's a supported varient */
- if (!prefix_ok(str1,"zWrLh")) return False;
- if (!check_printq_info(&desc,uLevel,str2,str3)) return False;
-
- snum = lp_servicenumber(QueueName);
- if (snum < 0 && pcap_printername_ok(QueueName,NULL)) {
- int pnum = lp_servicenumber(PRINTERS_NAME);
- if (pnum >= 0) {
- lp_add_printer(QueueName,pnum);
- snum = lp_servicenumber(QueueName);
- }
- }
-
- if (snum < 0 || !VALID_SNUM(snum)) return(False);
-
- count = get_printqueue(snum,cnum,&queue,&status);
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- if (init_package(&desc,1,count)) {
- desc.subcount = count;
- fill_printq_info(cnum,snum,uLevel,&desc,count,queue,&status);
- }
-
- *rdata_len = desc.usedlen;
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,desc.neededlen);
-
- DEBUG(4,("printqgetinfo: errorcode %d\n",desc.errcode));
-
- if (queue) free(queue);
-
- return(True);
-}
-
-
-/****************************************************************************
- view list of all print jobs on all queues
- ****************************************************************************/
-static BOOL api_DosPrintQEnum(int cnum, uint16 vuid, char* param, char* data,
- int mdrcnt, int mprcnt,
- char **rdata, char** rparam,
- int *rdata_len, int *rparam_len)
-{
- char *param_format = param+2;
- char *output_format1 = skip_string(param_format,1);
- char *p = skip_string(output_format1,1);
- int uLevel = SVAL(p,0);
- char *output_format2 = p + 4;
- int services = lp_numservices();
- int i, n;
- struct pack_desc desc;
- print_queue_struct **queue = NULL;
- print_status_struct *status = NULL;
- int* subcntarr = NULL;
- int queuecnt, subcnt=0, succnt=0;
-
- bzero(&desc,sizeof(desc));
-
- DEBUG(3,("DosPrintQEnum uLevel=%d\n",uLevel));
-
- if (!prefix_ok(param_format,"WrLeh")) return False;
- if (!check_printq_info(&desc,uLevel,output_format1,output_format2))
- return False;
- queuecnt = 0;
- for (i = 0; i < services; i++)
- if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i))
- queuecnt++;
- if (uLevel > 0) {
- queue = (print_queue_struct**)malloc(queuecnt*sizeof(print_queue_struct*));
- memset(queue,0,queuecnt*sizeof(print_queue_struct*));
- status = (print_status_struct*)malloc(queuecnt*sizeof(print_status_struct));
- memset(status,0,queuecnt*sizeof(print_status_struct));
- subcntarr = (int*)malloc(queuecnt*sizeof(int));
- subcnt = 0;
- n = 0;
- for (i = 0; i < services; i++)
- if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
- subcntarr[n] = get_printqueue(i,cnum,&queue[n],&status[n]);
- subcnt += subcntarr[n];
- n++;
- }
- }
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
-
- if (init_package(&desc,queuecnt,subcnt)) {
- n = 0;
- succnt = 0;
- for (i = 0; i < services; i++)
- if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
- fill_printq_info(cnum,i,uLevel,&desc,subcntarr[n],queue[n],&status[n]);
- n++;
- if (desc.errcode == NERR_Success) succnt = n;
- }
- }
-
- if (subcntarr) free(subcntarr);
-
- *rdata_len = desc.usedlen;
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,succnt);
- SSVAL(*rparam,6,queuecnt);
-
- for (i = 0; i < queuecnt; i++) {
- if (queue && queue[i]) free(queue[i]);
- }
-
- if (queue) free(queue);
- if (status) free(status);
-
- return True;
-}
-
-/****************************************************************************
- get info level for a server list query
- ****************************************************************************/
-static BOOL check_server_info(int uLevel, char* id)
-{
- switch( uLevel ) {
- case 0:
- if (strcmp(id,"B16") != 0) return False;
- break;
- case 1:
- if (strcmp(id,"B16BBDz") != 0) return False;
- break;
- default:
- return False;
- }
- return True;
-}
-
-struct srv_info_struct
-{
- fstring name;
- uint32 type;
- fstring comment;
- fstring domain;
- BOOL server_added;
-};
-
-
-/*******************************************************************
- get server info lists from the files saved by nmbd. Return the
- number of entries
- ******************************************************************/
-static int get_server_info(uint32 servertype,
- struct srv_info_struct **servers,
- char *domain)
-{
- FILE *f;
- pstring fname;
- int count=0;
- int alloced=0;
- pstring line;
- BOOL local_list_only;
-
- pstrcpy(fname,lp_lockdir());
- trim_string(fname,NULL,"/");
- strcat(fname,"/");
- strcat(fname,SERVER_LIST);
-
- f = fopen(fname,"r");
-
- if (!f) {
- DEBUG(4,("Can't open %s - %s\n",fname,strerror(errno)));
- return(0);
- }
-
- /* request for everything is code for request all servers */
- if (servertype == SV_TYPE_ALL)
- servertype &= ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY);
-
- local_list_only = (servertype & SV_TYPE_LOCAL_LIST_ONLY);
-
- DEBUG(4,("Servertype search: %8x\n",servertype));
-
- while (!feof(f))
- {
- fstring stype;
- struct srv_info_struct *s;
- char *ptr = line;
- BOOL ok = True;
- *ptr = 0;
-
- fgets(line,sizeof(line)-1,f);
- if (!*line) continue;
-
- if (count == alloced) {
- alloced += 10;
- (*servers) = (struct srv_info_struct *)
- Realloc(*servers,sizeof(**servers)*alloced);
- if (!(*servers)) return(0);
- bzero((char *)((*servers)+count),sizeof(**servers)*(alloced-count));
- }
- s = &(*servers)[count];
-
- if (!next_token(&ptr,s->name , NULL)) continue;
- if (!next_token(&ptr,stype , NULL)) continue;
- if (!next_token(&ptr,s->comment, NULL)) continue;
- if (!next_token(&ptr,s->domain , NULL)) {
- /* this allows us to cope with an old nmbd */
- strcpy(s->domain,myworkgroup);
- }
-
- if (sscanf(stype,"%X",&s->type) != 1) {
- DEBUG(4,("r:host file "));
- ok = False;
- }
-
- /* Filter the servers/domains we return based on what was asked for. */
-
- /* Check to see if we are being asked for a local list only. */
- if(local_list_only && ((s->type & SV_TYPE_LOCAL_LIST_ONLY) == 0)) {
- DEBUG(4,("r: local list only"));
- ok = False;
- }
-
- /* doesn't match up: don't want it */
- if (!(servertype & s->type)) {
- DEBUG(4,("r:serv type "));
- ok = False;
- }
-
- if ((servertype & SV_TYPE_DOMAIN_ENUM) !=
- (s->type & SV_TYPE_DOMAIN_ENUM))
- {
- DEBUG(4,("s: dom mismatch "));
- ok = False;
- }
-
- if (!strequal(domain, s->domain) && !(servertype & SV_TYPE_DOMAIN_ENUM))
- {
- ok = False;
- }
-
- /* We should never return a server type with a SV_TYPE_LOCAL_LIST_ONLY set. */
- s->type &= ~SV_TYPE_LOCAL_LIST_ONLY;
-
- if (ok)
- {
- DEBUG(4,("**SV** %20s %8x %25s %15s\n",
- s->name, s->type, s->comment, s->domain));
-
- s->server_added = True;
- count++;
- }
- else
- {
- DEBUG(4,("%20s %8x %25s %15s\n",
- s->name, s->type, s->comment, s->domain));
- }
- }
-
- fclose(f);
- return(count);
-}
-
-
-/*******************************************************************
- fill in a server info structure
- ******************************************************************/
-static int fill_srv_info(struct srv_info_struct *service,
- int uLevel, char **buf, int *buflen,
- char **stringbuf, int *stringspace, char *baseaddr)
-{
- int struct_len;
- char* p;
- char* p2;
- int l2;
- int len;
-
- switch (uLevel) {
- case 0: struct_len = 16; break;
- case 1: struct_len = 26; break;
- default: return -1;
- }
-
- if (!buf)
- {
- len = 0;
- switch (uLevel)
- {
- case 1:
- len = strlen(service->comment)+1;
- break;
- }
-
- if (buflen) *buflen = struct_len;
- if (stringspace) *stringspace = len;
- return struct_len + len;
- }
-
- len = struct_len;
- p = *buf;
- if (*buflen < struct_len) return -1;
- if (stringbuf)
- {
- p2 = *stringbuf;
- l2 = *stringspace;
- }
- else
- {
- p2 = p + struct_len;
- l2 = *buflen - struct_len;
- }
- if (!baseaddr) baseaddr = p;
-
- switch (uLevel)
- {
- case 0:
- StrnCpy(p,service->name,15);
- break;
-
- case 1:
- StrnCpy(p,service->name,15);
- SIVAL(p,18,service->type);
- SIVAL(p,22,PTR_DIFF(p2,baseaddr));
- len += CopyAndAdvance(&p2,service->comment,&l2);
- break;
- }
-
- if (stringbuf)
- {
- *buf = p + struct_len;
- *buflen -= struct_len;
- *stringbuf = p2;
- *stringspace = l2;
- }
- else
- {
- *buf = p2;
- *buflen -= len;
- }
- return len;
-}
-
-
-static BOOL srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2)
-{
- return(strcmp(s1->name,s2->name));
-}
-
-/****************************************************************************
- view list of servers available (or possibly domains). The info is
- extracted from lists saved by nmbd on the local host
- ****************************************************************************/
-static BOOL api_RNetServerEnum(int cnum, uint16 vuid, char *param, char *data,
- int mdrcnt, int mprcnt, char **rdata,
- char **rparam, int *rdata_len, int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel = SVAL(p,0);
- int buf_len = SVAL(p,2);
- uint32 servertype = IVAL(p,4);
- char *p2;
- int data_len, fixed_len, string_len;
- int f_len, s_len;
- struct srv_info_struct *servers=NULL;
- int counted=0,total=0;
- int i,missed;
- fstring domain;
- BOOL domain_request;
- BOOL local_request;
-
- /* If someone sets all the bits they don't really mean to set
- DOMAIN_ENUM and LOCAL_LIST_ONLY, they just want all the
- known servers. */
-
- if (servertype == SV_TYPE_ALL)
- servertype &= ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY);
-
- /* If someone sets SV_TYPE_LOCAL_LIST_ONLY but hasn't set
- any other bit (they may just set this bit on it's own) they
- want all the locally seen servers. However this bit can be
- set on its own so set the requested servers to be
- ALL - DOMAIN_ENUM. */
-
- if ((servertype & SV_TYPE_LOCAL_LIST_ONLY) && !(servertype & SV_TYPE_DOMAIN_ENUM))
- servertype = SV_TYPE_ALL & ~(SV_TYPE_DOMAIN_ENUM);
-
- domain_request = ((servertype & SV_TYPE_DOMAIN_ENUM) != 0);
- local_request = ((servertype & SV_TYPE_LOCAL_LIST_ONLY) != 0);
-
- p += 8;
-
- if (!prefix_ok(str1,"WrLehD")) return False;
- if (!check_server_info(uLevel,str2)) return False;
-
- DEBUG(4, ("server request level: %s %8x ", str2, servertype));
- DEBUG(4, ("domains_req:%s ", BOOLSTR(domain_request)));
- DEBUG(4, ("local_only:%s\n", BOOLSTR(local_request)));
-
- if (strcmp(str1, "WrLehDz") == 0) {
- StrnCpy(domain, p, sizeof(fstring)-1);
- } else {
- StrnCpy(domain, myworkgroup, sizeof(fstring)-1);
- }
-
- if (lp_browse_list())
- total = get_server_info(servertype,&servers,domain);
-
- data_len = fixed_len = string_len = 0;
- missed = 0;
-
- qsort(servers,total,sizeof(servers[0]),QSORT_CAST srv_comp);
-
- {
- char *lastname=NULL;
-
- for (i=0;i<total;i++)
- {
- struct srv_info_struct *s = &servers[i];
- if (lastname && strequal(lastname,s->name)) continue;
- lastname = s->name;
- data_len += fill_srv_info(s,uLevel,0,&f_len,0,&s_len,0);
- DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
- s->name, s->type, s->comment, s->domain));
-
- if (data_len <= buf_len) {
- counted++;
- fixed_len += f_len;
- string_len += s_len;
- } else {
- missed++;
- }
- }
- }
-
- *rdata_len = fixed_len + string_len;
- *rdata = REALLOC(*rdata,*rdata_len);
- bzero(*rdata,*rdata_len);
-
- p2 = (*rdata) + fixed_len; /* auxilliary data (strings) will go here */
- p = *rdata;
- f_len = fixed_len;
- s_len = string_len;
-
- {
- char *lastname=NULL;
- int count2 = counted;
- for (i = 0; i < total && count2;i++)
- {
- struct srv_info_struct *s = &servers[i];
- if (lastname && strequal(lastname,s->name)) continue;
- lastname = s->name;
- fill_srv_info(s,uLevel,&p,&f_len,&p2,&s_len,*rdata);
- DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
- s->name, s->type, s->comment, s->domain));
- count2--;
- }
- }
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVAL(*rparam,0,(missed == 0 ? NERR_Success : ERROR_MORE_DATA));
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,counted);
- SSVAL(*rparam,6,counted+missed);
-
- if (servers) free(servers);
-
- DEBUG(3,("NetServerEnum domain = %s uLevel=%d counted=%d total=%d\n",
- domain,uLevel,counted,counted+missed));
-
- return(True);
-}
-
-
-/****************************************************************************
- get info about a share
- ****************************************************************************/
-static BOOL check_share_info(int uLevel, char* id)
-{
- switch( uLevel ) {
- case 0:
- if (strcmp(id,"B13") != 0) return False;
- break;
- case 1:
- if (strcmp(id,"B13BWz") != 0) return False;
- break;
- case 2:
- if (strcmp(id,"B13BWzWWWzB9B") != 0) return False;
- break;
- case 91:
- if (strcmp(id,"B13BWzWWWzB9BB9BWzWWzWW") != 0) return False;
- break;
- default: return False;
- }
- return True;
-}
-
-static int fill_share_info(int cnum, int snum, int uLevel,
- char** buf, int* buflen,
- char** stringbuf, int* stringspace, char* baseaddr)
-{
- int struct_len;
- char* p;
- char* p2;
- int l2;
- int len;
-
- switch( uLevel ) {
- case 0: struct_len = 13; break;
- case 1: struct_len = 20; break;
- case 2: struct_len = 40; break;
- case 91: struct_len = 68; break;
- default: return -1;
- }
-
-
- if (!buf)
- {
- len = 0;
- if (uLevel > 0) len += StrlenExpanded(cnum,snum,lp_comment(snum));
- if (uLevel > 1) len += strlen(lp_pathname(snum)) + 1;
- if (buflen) *buflen = struct_len;
- if (stringspace) *stringspace = len;
- return struct_len + len;
- }
-
- len = struct_len;
- p = *buf;
- if ((*buflen) < struct_len) return -1;
- if (stringbuf)
- {
- p2 = *stringbuf;
- l2 = *stringspace;
- }
- else
- {
- p2 = p + struct_len;
- l2 = (*buflen) - struct_len;
- }
- if (!baseaddr) baseaddr = p;
-
- StrnCpy(p,lp_servicename(snum),13);
-
- if (uLevel > 0)
- {
- int type;
- CVAL(p,13) = 0;
- type = STYPE_DISKTREE;
- if (lp_print_ok(snum)) type = STYPE_PRINTQ;
- if (strequal("IPC$",lp_servicename(snum))) type = STYPE_IPC;
- SSVAL(p,14,type); /* device type */
- SIVAL(p,16,PTR_DIFF(p2,baseaddr));
- len += CopyExpanded(cnum,snum,&p2,lp_comment(snum),&l2);
- }
-
- if (uLevel > 1)
- {
- SSVAL(p,20,ACCESS_READ|ACCESS_WRITE|ACCESS_CREATE); /* permissions */
- SSVALS(p,22,-1); /* max uses */
- SSVAL(p,24,1); /* current uses */
- SIVAL(p,26,PTR_DIFF(p2,baseaddr)); /* local pathname */
- len += CopyAndAdvance(&p2,lp_pathname(snum),&l2);
- memset(p+30,0,SHPWLEN+2); /* passwd (reserved), pad field */
- }
-
- if (uLevel > 2)
- {
- memset(p+40,0,SHPWLEN+2);
- SSVAL(p,50,0);
- SIVAL(p,52,0);
- SSVAL(p,56,0);
- SSVAL(p,58,0);
- SIVAL(p,60,0);
- SSVAL(p,64,0);
- SSVAL(p,66,0);
- }
-
- if (stringbuf)
- {
- (*buf) = p + struct_len;
- (*buflen) -= struct_len;
- (*stringbuf) = p2;
- (*stringspace) = l2;
- }
- else
- {
- (*buf) = p2;
- (*buflen) -= len;
- }
- return len;
-}
-
-static BOOL api_RNetShareGetInfo(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *netname = skip_string(str2,1);
- char *p = skip_string(netname,1);
- int uLevel = SVAL(p,0);
- int snum = find_service(netname);
-
- if (snum < 0) return False;
-
- /* check it's a supported varient */
- if (!prefix_ok(str1,"zWrLh")) return False;
- if (!check_share_info(uLevel,str2)) return False;
-
- *rdata = REALLOC(*rdata,mdrcnt);
- p = *rdata;
- *rdata_len = fill_share_info(cnum,snum,uLevel,&p,&mdrcnt,0,0,0);
- if (*rdata_len < 0) return False;
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
- SSVAL(*rparam,4,*rdata_len);
-
- return(True);
-}
-
-/****************************************************************************
- view list of shares available
- ****************************************************************************/
-static BOOL api_RNetShareEnum(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel = SVAL(p,0);
- int buf_len = SVAL(p,2);
- char *p2;
- int count=lp_numservices();
- int total=0,counted=0;
- int i;
- int data_len, fixed_len, string_len;
- int f_len, s_len;
-
- if (!prefix_ok(str1,"WrLeh")) return False;
- if (!check_share_info(uLevel,str2)) return False;
-
- data_len = fixed_len = string_len = 0;
- for (i=0;i<count;i++)
- if (lp_browseable(i) && lp_snum_ok(i))
- {
- total++;
- data_len += fill_share_info(cnum,i,uLevel,0,&f_len,0,&s_len,0);
- if (data_len <= buf_len)
- {
- counted++;
- fixed_len += f_len;
- string_len += s_len;
- }
- }
- *rdata_len = fixed_len + string_len;
- *rdata = REALLOC(*rdata,*rdata_len);
- memset(*rdata,0,*rdata_len);
-
- p2 = (*rdata) + fixed_len; /* auxillery data (strings) will go here */
- p = *rdata;
- f_len = fixed_len;
- s_len = string_len;
- for (i = 0; i < count;i++)
- if (lp_browseable(i) && lp_snum_ok(i))
- if (fill_share_info(cnum,i,uLevel,&p,&f_len,&p2,&s_len,*rdata) < 0)
- break;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,counted);
- SSVAL(*rparam,6,total);
-
- DEBUG(3,("RNetShareEnum gave %d entries of %d (%d %d %d %d)\n",
- counted,total,uLevel,
- buf_len,*rdata_len,mdrcnt));
- return(True);
-}
-
-
-
-/****************************************************************************
- get the time of day info
- ****************************************************************************/
-static BOOL api_NetRemoteTOD(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *p;
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- *rdata_len = 21;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
-
- p = *rdata;
-
- {
- struct tm *t;
- time_t unixdate = time(NULL);
-
- put_dos_date3(p,0,unixdate); /* this is the time that is looked at
- by NT in a "net time" operation,
- it seems to ignore the one below */
-
- /* the client expects to get localtime, not GMT, in this bit
- (I think, this needs testing) */
- t = LocalTime(&unixdate);
-
- SIVAL(p,4,0); /* msecs ? */
- CVAL(p,8) = t->tm_hour;
- CVAL(p,9) = t->tm_min;
- CVAL(p,10) = t->tm_sec;
- CVAL(p,11) = 0; /* hundredths of seconds */
- SSVALS(p,12,TimeDiff(unixdate)/60); /* timezone in minutes from GMT */
- SSVAL(p,14,10000); /* timer interval in 0.0001 of sec */
- CVAL(p,16) = t->tm_mday;
- CVAL(p,17) = t->tm_mon + 1;
- SSVAL(p,18,1900+t->tm_year);
- CVAL(p,20) = t->tm_wday;
- }
-
-
- return(True);
-}
-
-/****************************************************************************
- set the user password
- ****************************************************************************/
-static BOOL api_SetUserPassword(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *p = skip_string(param+2,2);
- fstring user;
- fstring pass1,pass2;
-
- fstrcpy(user,p);
-
- p = skip_string(p,1);
-
- StrnCpy(pass1,p,16);
- StrnCpy(pass2,p+16,16);
-
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- *rdata_len = 0;
-
- SSVAL(*rparam,0,NERR_badpass);
- SSVAL(*rparam,2,0); /* converter word */
-
- DEBUG(3,("Set password for <%s>\n",user));
-
- if (password_ok(user,pass1,strlen(pass1),NULL) &&
- chgpasswd(user,pass1,pass2))
- {
- SSVAL(*rparam,0,NERR_Success);
- }
-
- bzero(pass1,sizeof(fstring));
- bzero(pass2,sizeof(fstring));
-
- return(True);
-}
-
-/****************************************************************************
- delete a print job
- Form: <W> <>
- ****************************************************************************/
-static BOOL api_RDosPrintJobDel(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- int function = SVAL(param,0);
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int jobid, snum;
- int i, count;
-
- printjob_decode(SVAL(p,0), &snum, &jobid);
-
- /* check it's a supported varient */
- if (!(strcsequal(str1,"W") && strcsequal(str2,"")))
- return(False);
-
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- *rdata_len = 0;
-
- SSVAL(*rparam,0,NERR_Success);
-
- if (snum >= 0 && VALID_SNUM(snum))
- {
- print_queue_struct *queue=NULL;
- lpq_reset(snum);
- count = get_printqueue(snum,cnum,&queue,NULL);
-
- for (i=0;i<count;i++)
- if ((queue[i].job&0xFF) == jobid)
- {
- switch (function) {
- case 81: /* delete */
- DEBUG(3,("Deleting queue entry %d\n",queue[i].job));
- del_printqueue(cnum,snum,queue[i].job);
- break;
- case 82: /* pause */
- case 83: /* resume */
- DEBUG(3,("%s queue entry %d\n",
- (function==82?"pausing":"resuming"),queue[i].job));
- status_printjob(cnum,snum,queue[i].job,
- (function==82?LPQ_PAUSED:LPQ_QUEUED));
- break;
- }
- break;
- }
-
- if (i==count)
- SSVAL(*rparam,0,NERR_JobNotFound);
-
- if (queue) free(queue);
- }
-
- SSVAL(*rparam,2,0); /* converter word */
-
- return(True);
-}
-
-static BOOL api_WPrintQueuePurge(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *QueueName = skip_string(str2,1);
- int snum;
-
- /* check it's a supported varient */
- if (!(strcsequal(str1,"z") && strcsequal(str2,"")))
- return(False);
-
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- *rdata_len = 0;
-
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
-
- snum = lp_servicenumber(QueueName);
- if (snum < 0 && pcap_printername_ok(QueueName,NULL)) {
- int pnum = lp_servicenumber(PRINTERS_NAME);
- if (pnum >= 0) {
- lp_add_printer(QueueName,pnum);
- snum = lp_servicenumber(QueueName);
- }
- }
-
- if (snum >= 0 && VALID_SNUM(snum)) {
- print_queue_struct *queue=NULL;
- int i, count;
- lpq_reset(snum);
-
- count = get_printqueue(snum,cnum,&queue,NULL);
- for (i = 0; i < count; i++)
- del_printqueue(cnum,snum,queue[i].job);
-
- if (queue) free(queue);
- }
-
- DEBUG(3,("Print queue purge, queue=%s\n",QueueName));
-
- return(True);
-}
-
-
-/****************************************************************************
- set the property of a print job (undocumented?)
- ? function = 0xb -> set name of print job
- ? function = 0x6 -> move print job up/down
- Form: <WWsTP> <WWzWWDDzzzzzzzzzzlz>
- or <WWsTP> <WB21BB16B10zWWzDDz>
-****************************************************************************/
-static int check_printjob_info(struct pack_desc* desc,
- int uLevel, char* id)
-{
- desc->subformat = NULL;
- switch( uLevel ) {
- case 0: desc->format = "W"; break;
- case 1: desc->format = "WB21BB16B10zWWzDDz"; break;
- case 2: desc->format = "WWzWWDDzz"; break;
- case 3: desc->format = "WWzWWDDzzzzzzzzzzlz"; break;
- default: return False;
- }
- if (strcmp(desc->format,id) != 0) return False;
- return True;
-}
-
-static BOOL api_PrintJobInfo(int cnum,uint16 vuid,char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- struct pack_desc desc;
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int jobid, snum;
- int uLevel = SVAL(p,2);
- int function = SVAL(p,4); /* what is this ?? */
- int i;
- char *s = data;
-
- printjob_decode(SVAL(p,0), &snum, &jobid);
-
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- *rdata_len = 0;
-
- /* check it's a supported varient */
- if ((strcmp(str1,"WWsTP")) || (!check_printjob_info(&desc,uLevel,str2)))
- return(False);
-
- switch (function) {
- case 0x6: /* change job place in the queue, data gives the new place */
- if (snum >= 0 && VALID_SNUM(snum))
- {
- print_queue_struct *queue=NULL;
- int count;
-
- lpq_reset(snum);
- count = get_printqueue(snum,cnum,&queue,NULL);
- for (i=0;i<count;i++) /* find job */
- if ((queue[i].job&0xFF) == jobid) break;
-
- if (i==count) {
- desc.errcode=NERR_JobNotFound;
- if (queue) free(queue);
- }
- else {
- desc.errcode=NERR_Success;
- i++;
-#if 0
- {
- int place= SVAL(data,0);
- /* we currently have no way of doing this. Can any unix do it? */
- if (i < place) /* move down */;
- else if (i > place ) /* move up */;
- }
-#endif
- desc.errcode=NERR_notsupported; /* not yet supported */
- if (queue) free(queue);
- }
- }
- else desc.errcode=NERR_JobNotFound;
- break;
- case 0xb: /* change print job name, data gives the name */
- /* jobid, snum should be zero */
- if (isalpha(*s))
- {
- pstring name;
- int l = 0;
- while (l<64 && *s)
- {
- if (issafe(*s)) name[l++] = *s;
- s++;
- }
- name[l] = 0;
-
- DEBUG(3,("Setting print name to %s\n",name));
-
- for (i=0;i<MAX_OPEN_FILES;i++)
- if (Files[i].open && Files[i].print_file)
- {
- pstring wd;
- GetWd(wd);
- unbecome_user();
-
- if (!become_user(Files[i].cnum,vuid) ||
- !become_service(Files[i].cnum,True))
- break;
-
- if (sys_rename(Files[i].name,name) == 0)
- string_set(&Files[i].name,name);
- break;
- }
- }
- desc.errcode=NERR_Success;
-
- break;
- default: /* not implemented */
- return False;
- }
-
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0); /* converter word */
-
- return(True);
-}
-
-
-/****************************************************************************
- get info about the server
- ****************************************************************************/
-static BOOL api_RNetServerGetInfo(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel = SVAL(p,0);
- char *p2;
- int struct_len;
-
- DEBUG(4,("NetServerGetInfo level %d\n",uLevel));
-
- /* check it's a supported varient */
- if (!prefix_ok(str1,"WrLh")) return False;
- switch( uLevel ) {
- case 0:
- if (strcmp(str2,"B16") != 0) return False;
- struct_len = 16;
- break;
- case 1:
- if (strcmp(str2,"B16BBDz") != 0) return False;
- struct_len = 26;
- break;
- case 2:
- if (strcmp(str2,"B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWz")
- != 0) return False;
- struct_len = 134;
- break;
- case 3:
- if (strcmp(str2,"B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWzDWz")
- != 0) return False;
- struct_len = 144;
- break;
- case 20:
- if (strcmp(str2,"DN") != 0) return False;
- struct_len = 6;
- break;
- case 50:
- if (strcmp(str2,"B16BBDzWWzzz") != 0) return False;
- struct_len = 42;
- break;
- default: return False;
- }
-
- *rdata_len = mdrcnt;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- p = *rdata;
- p2 = p + struct_len;
- if (uLevel != 20) {
- StrnCpy(p,local_machine,16);
- strupper(p);
- }
- p += 16;
- if (uLevel > 0)
- {
- struct srv_info_struct *servers=NULL;
- int i,count;
- pstring comment;
- uint32 servertype= lp_default_server_announce();
-
- pstrcpy(comment,lp_serverstring());
-
- if ((count=get_server_info(SV_TYPE_ALL,&servers,myworkgroup))>0) {
- for (i=0;i<count;i++)
- if (strequal(servers[i].name,local_machine))
- {
- servertype = servers[i].type;
- pstrcpy(comment,servers[i].comment);
- }
- }
- if (servers) free(servers);
-
- SCVAL(p,0,lp_major_announce_version());
- SCVAL(p,1,lp_minor_announce_version());
- SIVAL(p,2,servertype);
-
- if (mdrcnt == struct_len) {
- SIVAL(p,6,0);
- } else {
- SIVAL(p,6,PTR_DIFF(p2,*rdata));
- standard_sub(cnum,comment);
- StrnCpy(p2,comment,MAX(mdrcnt - struct_len,0));
- p2 = skip_string(p2,1);
- }
- }
- if (uLevel > 1)
- {
- return False; /* not yet implemented */
- }
-
- *rdata_len = PTR_DIFF(p2,*rdata);
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
- SSVAL(*rparam,4,*rdata_len);
-
- return(True);
-}
-
-
-/****************************************************************************
- get info about the server
- ****************************************************************************/
-static BOOL api_NetWkstaGetInfo(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- char *p2;
- extern pstring sesssetup_user;
- int level = SVAL(p,0);
-
- DEBUG(4,("NetWkstaGetInfo level %d\n",level));
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- /* check it's a supported varient */
- if (!(level==10 && strcsequal(str1,"WrLh") && strcsequal(str2,"zzzBBzz")))
- return(False);
-
- *rdata_len = mdrcnt + 1024;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
-
- p = *rdata;
- p2 = p + 22;
-
-
- SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* host name */
- strcpy(p2,local_machine);
- strupper(p2);
- p2 = skip_string(p2,1);
- p += 4;
-
- SIVAL(p,0,PTR_DIFF(p2,*rdata));
- strcpy(p2,sesssetup_user);
- p2 = skip_string(p2,1);
- p += 4;
-
- SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* login domain */
- strcpy(p2,myworkgroup);
- strupper(p2);
- p2 = skip_string(p2,1);
- p += 4;
-
- SCVAL(p,0,lp_major_announce_version()); /* system version - e.g 4 in 4.1 */
- SCVAL(p,1,lp_minor_announce_version()); /* system version - e.g .1 in 4.1 */
- p += 2;
-
- SIVAL(p,0,PTR_DIFF(p2,*rdata));
- strcpy(p2,myworkgroup); /* don't know. login domain?? */
- p2 = skip_string(p2,1);
- p += 4;
-
- SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* don't know */
- strcpy(p2,"");
- p2 = skip_string(p2,1);
- p += 4;
-
- *rdata_len = PTR_DIFF(p2,*rdata);
-
- SSVAL(*rparam,4,*rdata_len);
-
- return(True);
-}
-
-/****************************************************************************
- get info about a user
-
- struct user_info_11 {
- char usri11_name[21]; 0-20
- char usri11_pad; 21
- char *usri11_comment; 22-25
- char *usri11_usr_comment; 26-29
- unsigned short usri11_priv; 30-31
- unsigned long usri11_auth_flags; 32-35
- long usri11_password_age; 36-39
- char *usri11_homedir; 40-43
- char *usri11_parms; 44-47
- long usri11_last_logon; 48-51
- long usri11_last_logoff; 52-55
- unsigned short usri11_bad_pw_count; 56-57
- unsigned short usri11_num_logons; 58-59
- char *usri11_logon_server; 60-63
- unsigned short usri11_country_code; 64-65
- char *usri11_workstations; 66-69
- unsigned long usri11_max_storage; 70-73
- unsigned short usri11_units_per_week; 74-75
- unsigned char *usri11_logon_hours; 76-79
- unsigned short usri11_code_page; 80-81
- };
-
-where:
-
- usri11_name specifies the user name for which information is retireved
-
- usri11_pad aligns the next data structure element to a word boundary
-
- usri11_comment is a null terminated ASCII comment
-
- usri11_user_comment is a null terminated ASCII comment about the user
-
- usri11_priv specifies the level of the privilege assigned to the user.
- The possible values are:
-
-Name Value Description
-USER_PRIV_GUEST 0 Guest privilege
-USER_PRIV_USER 1 User privilege
-USER_PRV_ADMIN 2 Administrator privilege
-
- usri11_auth_flags specifies the account operator privileges. The
- possible values are:
-
-Name Value Description
-AF_OP_PRINT 0 Print operator
-
-
-Leach, Naik [Page 28]
-
-
-INTERNET-DRAFT CIFS Remote Admin Protocol January 10, 1997
-
-
-AF_OP_COMM 1 Communications operator
-AF_OP_SERVER 2 Server operator
-AF_OP_ACCOUNTS 3 Accounts operator
-
-
- usri11_password_age specifies how many seconds have elapsed since the
- password was last changed.
-
- usri11_home_dir points to a null terminated ASCII string that contains
- the path name of the user's home directory.
-
- usri11_parms points to a null terminated ASCII string that is set
- aside for use by applications.
-
- usri11_last_logon specifies the time when the user last logged on.
- This value is stored as the number of seconds elapsed since
- 00:00:00, January 1, 1970.
-
- usri11_last_logoff specifies the time when the user last logged off.
- This value is stored as the number of seconds elapsed since
- 00:00:00, January 1, 1970. A value of 0 means the last logoff
- time is unknown.
-
- usri11_bad_pw_count specifies the number of incorrect passwords
- entered since the last successful logon.
-
- usri11_log1_num_logons specifies the number of times this user has
- logged on. A value of -1 means the number of logons is unknown.
-
- usri11_logon_server points to a null terminated ASCII string that
- contains the name of the server to which logon requests are sent.
- A null string indicates logon requests should be sent to the
- domain controller.
-
- usri11_country_code specifies the country code for the user's language
- of choice.
-
- usri11_workstations points to a null terminated ASCII string that
- contains the names of workstations the user may log on from.
- There may be up to 8 workstations, with the names separated by
- commas. A null strings indicates there are no restrictions.
-
- usri11_max_storage specifies the maximum amount of disk space the user
- can occupy. A value of 0xffffffff indicates there are no
- restrictions.
-
- usri11_units_per_week specifies the equal number of time units into
- which a week is divided. This value must be equal to 168.
-
- usri11_logon_hours points to a 21 byte (168 bits) string that
- specifies the time during which the user can log on. Each bit
- represents one unique hour in a week. The first bit (bit 0, word
- 0) is Sunday, 0:00 to 0:59, the second bit (bit 1, word 0) is
-
-
-
-Leach, Naik [Page 29]
-
-
-INTERNET-DRAFT CIFS Remote Admin Protocol January 10, 1997
-
-
- Sunday, 1:00 to 1:59 and so on. A null pointer indicates there
- are no restrictions.
-
- usri11_code_page specifies the code page for the user's language of
- choice
-
-All of the pointers in this data structure need to be treated
-specially. The pointer is a 32 bit pointer. The higher 16 bits need
-to be ignored. The converter word returned in the parameters section
-needs to be subtracted from the lower 16 bits to calculate an offset
-into the return buffer where this ASCII string resides.
-
-There is no auxiliary data in the response.
-
- ****************************************************************************/
-
-#define usri11_name 0
-#define usri11_pad 21
-#define usri11_comment 22
-#define usri11_usr_comment 26
-#define usri11_full_name 30
-#define usri11_priv 34
-#define usri11_auth_flags 36
-#define usri11_password_age 40
-#define usri11_homedir 44
-#define usri11_parms 48
-#define usri11_last_logon 52
-#define usri11_last_logoff 56
-#define usri11_bad_pw_count 60
-#define usri11_num_logons 62
-#define usri11_logon_server 64
-#define usri11_country_code 68
-#define usri11_workstations 70
-#define usri11_max_storage 74
-#define usri11_units_per_week 78
-#define usri11_logon_hours 80
-#define usri11_code_page 84
-#define usri11_end 86
-
-#define USER_PRIV_GUEST 0
-#define USER_PRIV_USER 1
-#define USER_PRIV_ADMIN 2
-
-#define AF_OP_PRINT 0
-#define AF_OP_COMM 1
-#define AF_OP_SERVER 2
-#define AF_OP_ACCOUNTS 3
-
-
-static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *UserName = skip_string(str2,1);
- char *p = skip_string(UserName,1);
- int uLevel = SVAL(p,0);
- char *p2;
-
- /* get NIS home of a previously validated user - simeon */
- user_struct *vuser = get_valid_user_struct(vuid);
- DEBUG(3,(" Username of UID %d is %s\n", vuser->uid, vuser->name));
-#if (defined(NETGROUP) && defined(AUTOMOUNT))
- DEBUG(3,(" HOMESHR for %s is %s\n", vuser->name, vuser->home_share));
-#endif
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- /* check it's a supported variant */
- if (strcmp(str1,"zWrLh") != 0) return False;
- switch( uLevel )
- {
- case 0: p2 = "B21"; break;
- case 1: p2 = "B21BB16DWzzWz"; break;
- case 2: p2 = "B21BB16DWzzWzDzzzzDDDDWb21WWzWW"; break;
- case 10: p2 = "B21Bzzz"; break;
- case 11: p2 = "B21BzzzWDDzzDDWWzWzDWb21W"; break;
- default: return False;
- }
-
- if (strcmp(p2,str2) != 0) return False;
-
- *rdata_len = mdrcnt + 1024;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
-
- p = *rdata;
- p2 = p + usri11_end;
-
- memset(p,0,21);
- fstrcpy(p+usri11_name,UserName); /* 21 bytes - user name */
-
- if (uLevel > 0)
- {
- SCVAL(p,usri11_pad,0); /* padding - 1 byte */
- *p2 = 0;
- }
- if (uLevel >= 10)
- {
- SIVAL(p,usri11_comment,PTR_DIFF(p2,p)); /* comment */
- strcpy(p2,"Comment");
- p2 = skip_string(p2,1);
-
- SIVAL(p,usri11_usr_comment,PTR_DIFF(p2,p)); /* user_comment */
- strcpy(p2,"UserComment");
- p2 = skip_string(p2,1);
-
- /* EEK! the cifsrap.txt doesn't have this in!!!! */
- SIVAL(p,usri11_full_name,PTR_DIFF(p2,p)); /* full name */
- strcpy(p2,vuser->real_name); /* simeon */
- p2 = skip_string(p2,1);
- }
-
- if (uLevel == 11) /* modelled after NTAS 3.51 reply */
- {
- SSVAL(p,usri11_priv,Connections[cnum].admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
- SIVAL(p,usri11_auth_flags,AF_OP_PRINT); /* auth flags */
- SIVALS(p,usri11_password_age,0xffffffff); /* password age */
- SIVAL(p,usri11_homedir,PTR_DIFF(p2,p)); /* home dir */
- if (*lp_logon_path())
- {
- strcpy(p2,lp_logon_path());
- }
- else
- {
-#if (defined(NETGROUP) && defined(AUTOMOUNT))
- strcpy(p2, vuser->home_share);
-#else
- strcpy(p2,"\\\\%L\\%U");
-#endif
- }
- standard_sub_basic(p2);
- p2 = skip_string(p2,1);
- SIVAL(p,usri11_parms,PTR_DIFF(p2,p)); /* parms */
- strcpy(p2,"");
- p2 = skip_string(p2,1);
- SIVAL(p,usri11_last_logon,0); /* last logon */
- SIVAL(p,usri11_last_logoff,0); /* last logoff */
- SSVALS(p,usri11_bad_pw_count,0xffffffff); /* bad pw counts */
- SSVALS(p,usri11_num_logons,0xffffffff); /* num logons */
- SIVAL(p,usri11_logon_server,PTR_DIFF(p2,p)); /* logon server */
- strcpy(p2,"\\\\*");
- p2 = skip_string(p2,1);
- SSVAL(p,usri11_country_code,0); /* country code */
-
- SIVAL(p,usri11_workstations,PTR_DIFF(p2,p)); /* workstations */
- strcpy(p2,"");
- p2 = skip_string(p2,1);
-
- SIVALS(p,usri11_max_storage,0xffffffff); /* max storage */
- SSVAL(p,usri11_units_per_week,168); /* units per week */
- SIVAL(p,usri11_logon_hours,PTR_DIFF(p2,p)); /* logon hours */
-
- /* a simple way to get logon hours at all times. */
- memset(p2,0xff,21);
- SCVAL(p2,21,0); /* fix zero termination */
- p2 = skip_string(p2,1);
-
- SSVAL(p,usri11_code_page,0); /* code page */
- }
- if (uLevel == 1 || uLevel == 2)
- {
- memset(p+22,' ',16); /* password */
- SIVALS(p,38,-1); /* password age */
- SSVAL(p,42,
- Connections[cnum].admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
- SIVAL(p,44,PTR_DIFF(p2,*rdata)); /* home dir */
- if (*lp_logon_path())
- {
- strcpy(p2,lp_logon_path());
- }
- else
- {
-#if (defined(NETGROUP) && defined(AUTOMOUNT))
- strcpy(p2, vuser->home_share);
-#else
- strcpy(p2,"\\\\%L\\%U");
-#endif
- }
- standard_sub_basic(p2);
- p2 = skip_string(p2,1);
- SIVAL(p,48,PTR_DIFF(p2,*rdata)); /* comment */
- *p2++ = 0;
- SSVAL(p,52,0); /* flags */
- SIVAL(p,54,0); /* script_path */
- if (uLevel == 2)
- {
- SIVAL(p,60,0); /* auth_flags */
- SIVAL(p,64,PTR_DIFF(p2,*rdata)); /* full_name */
- strcpy(p2,vuser->real_name); /* simeon */
- p2 = skip_string(p2,1);
- SIVAL(p,68,0); /* urs_comment */
- SIVAL(p,72,PTR_DIFF(p2,*rdata)); /* parms */
- strcpy(p2,"");
- p2 = skip_string(p2,1);
- SIVAL(p,76,0); /* workstations */
- SIVAL(p,80,0); /* last_logon */
- SIVAL(p,84,0); /* last_logoff */
- SIVALS(p,88,-1); /* acct_expires */
- SIVALS(p,92,-1); /* max_storage */
- SSVAL(p,96,168); /* units_per_week */
- SIVAL(p,98,PTR_DIFF(p2,*rdata)); /* logon_hours */
- memset(p2,-1,21);
- p2 += 21;
- SSVALS(p,102,-1); /* bad_pw_count */
- SSVALS(p,104,-1); /* num_logons */
- SIVAL(p,106,PTR_DIFF(p2,*rdata)); /* logon_server */
- strcpy(p2,"\\\\%L");
- standard_sub_basic(p2);
- p2 = skip_string(p2,1);
- SSVAL(p,110,49); /* country_code */
- SSVAL(p,112,860); /* code page */
- }
- }
-
- *rdata_len = PTR_DIFF(p2,*rdata);
-
- SSVAL(*rparam,4,*rdata_len); /* is this right?? */
-
- return(True);
-}
-
-/*******************************************************************
- get groups that a user is a member of
- ******************************************************************/
-static BOOL api_NetUserGetGroups(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *UserName = skip_string(str2,1);
- char *p = skip_string(UserName,1);
- int uLevel = SVAL(p,0);
- char *p2;
- int count=0;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- /* check it's a supported varient */
- if (strcmp(str1,"zWrLeh") != 0) return False;
- switch( uLevel ) {
- case 0: p2 = "B21"; break;
- default: return False;
- }
- if (strcmp(p2,str2) != 0) return False;
-
- *rdata_len = mdrcnt + 1024;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
-
- p = *rdata;
-
- /* XXXX we need a real SAM database some day */
- strcpy(p,"Users"); p += 21; count++;
- strcpy(p,"Domain Users"); p += 21; count++;
- strcpy(p,"Guests"); p += 21; count++;
- strcpy(p,"Domain Guests"); p += 21; count++;
-
- *rdata_len = PTR_DIFF(p,*rdata);
-
- SSVAL(*rparam,4,count); /* is this right?? */
- SSVAL(*rparam,6,count); /* is this right?? */
-
- return(True);
-}
-
-
-static BOOL api_WWkstaUserLogon(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel;
- struct pack_desc desc;
- char* name;
- char* logon_script;
-
- uLevel = SVAL(p,0);
- name = p + 2;
-
- bzero(&desc,sizeof(desc));
-
- DEBUG(3,("WWkstaUserLogon uLevel=%d name=%s\n",uLevel,name));
-
- /* check it's a supported varient */
- if (strcmp(str1,"OOWb54WrLh") != 0) return False;
- if (uLevel != 1 || strcmp(str2,"WB21BWDWWDDDDDDDzzzD") != 0) return False;
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- desc.subformat = NULL;
- desc.format = str2;
-
- if (init_package(&desc,1,0))
- {
- PACKI(&desc,"W",0); /* code */
- PACKS(&desc,"B21",name); /* eff. name */
- PACKS(&desc,"B",""); /* pad */
- PACKI(&desc,"W",
- Connections[cnum].admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
- PACKI(&desc,"D",0); /* auth flags XXX */
- PACKI(&desc,"W",0); /* num logons */
- PACKI(&desc,"W",0); /* bad pw count */
- PACKI(&desc,"D",0); /* last logon */
- PACKI(&desc,"D",-1); /* last logoff */
- PACKI(&desc,"D",-1); /* logoff time */
- PACKI(&desc,"D",-1); /* kickoff time */
- PACKI(&desc,"D",0); /* password age */
- PACKI(&desc,"D",0); /* password can change */
- PACKI(&desc,"D",-1); /* password must change */
- {
- fstring mypath;
- strcpy(mypath,"\\\\");
- strcat(mypath,local_machine);
- strupper(mypath);
- PACKS(&desc,"z",mypath); /* computer */
- }
- PACKS(&desc,"z",myworkgroup);/* domain */
-
-/* JHT - By calling lp_logon_script() and standard_sub() we have */
-/* made sure all macros are fully substituted and available */
- logon_script = lp_logon_script();
- standard_sub( cnum, logon_script );
- PACKS(&desc,"z", logon_script); /* script path */
-/* End of JHT mods */
-
- PACKI(&desc,"D",0x00000000); /* reserved */
- }
-
- *rdata_len = desc.usedlen;
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,desc.neededlen);
-
- DEBUG(4,("WWkstaUserLogon: errorcode %d\n",desc.errcode));
- return(True);
-}
-
-
-/****************************************************************************
- api_WAccessGetUserPerms
- ****************************************************************************/
-static BOOL api_WAccessGetUserPerms(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *user = skip_string(str2,1);
- char *resource = skip_string(user,1);
-
- DEBUG(3,("WAccessGetUserPerms user=%s resource=%s\n",user,resource));
-
- /* check it's a supported varient */
- if (strcmp(str1,"zzh") != 0) return False;
- if (strcmp(str2,"") != 0) return False;
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,0); /* errorcode */
- SSVAL(*rparam,2,0); /* converter word */
- SSVAL(*rparam,4,0x7f); /* permission flags */
-
- return(True);
-}
-
-/****************************************************************************
- api_WPrintJobEnumerate
- ****************************************************************************/
-static BOOL api_WPrintJobGetInfo(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel,cbBuf;
- int count;
- int i;
- int snum;
- int job;
- struct pack_desc desc;
- print_queue_struct *queue=NULL;
- print_status_struct status;
-
- uLevel = SVAL(p,2);
- cbBuf = SVAL(p,4);
-
- bzero(&desc,sizeof(desc));
- bzero(&status,sizeof(status));
-
- DEBUG(3,("WPrintJobGetInfo uLevel=%d uJobId=0x%X\n",uLevel,SVAL(p,0)));
-
- /* check it's a supported varient */
- if (strcmp(str1,"WWrLh") != 0) return False;
- if (!check_printjob_info(&desc,uLevel,str2)) return False;
-
- printjob_decode(SVAL(p,0), &snum, &job);
-
- if (snum < 0 || !VALID_SNUM(snum)) return(False);
-
- count = get_printqueue(snum,cnum,&queue,&status);
- for (i = 0; i < count; i++) {
- if ((queue[i].job & 0xFF) == job) break;
- }
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
-
- if (init_package(&desc,1,0)) {
- if (i < count) {
- fill_printjob_info(cnum,snum,uLevel,&desc,&queue[i],i);
- *rdata_len = desc.usedlen;
- }
- else {
- desc.errcode = NERR_JobNotFound;
- *rdata_len = 0;
- }
- }
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,desc.neededlen);
-
- if (queue) free(queue);
-
- DEBUG(4,("WPrintJobGetInfo: errorcode %d\n",desc.errcode));
- return(True);
-}
-
-static BOOL api_WPrintJobEnumerate(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- char* name = p;
- int uLevel,cbBuf;
- int count;
- int i, succnt=0;
- int snum;
- struct pack_desc desc;
- print_queue_struct *queue=NULL;
- print_status_struct status;
-
- bzero(&desc,sizeof(desc));
- bzero(&status,sizeof(status));
-
- p = skip_string(p,1);
- uLevel = SVAL(p,0);
- cbBuf = SVAL(p,2);
-
- DEBUG(3,("WPrintJobEnumerate uLevel=%d name=%s\n",uLevel,name));
-
- /* check it's a supported varient */
- if (strcmp(str1,"zWrLeh") != 0) return False;
- if (uLevel > 2) return False; /* defined only for uLevel 0,1,2 */
- if (!check_printjob_info(&desc,uLevel,str2)) return False;
-
- snum = lp_servicenumber(name);
- if (snum < 0 && pcap_printername_ok(name,NULL)) {
- int pnum = lp_servicenumber(PRINTERS_NAME);
- if (pnum >= 0) {
- lp_add_printer(name,pnum);
- snum = lp_servicenumber(name);
- }
- }
-
- if (snum < 0 || !VALID_SNUM(snum)) return(False);
-
- count = get_printqueue(snum,cnum,&queue,&status);
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
-
- if (init_package(&desc,count,0)) {
- succnt = 0;
- for (i = 0; i < count; i++) {
- fill_printjob_info(cnum,snum,uLevel,&desc,&queue[i],i);
- if (desc.errcode == NERR_Success) succnt = i+1;
- }
- }
-
- *rdata_len = desc.usedlen;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,succnt);
- SSVAL(*rparam,6,count);
-
- if (queue) free(queue);
-
- DEBUG(4,("WPrintJobEnumerate: errorcode %d\n",desc.errcode));
- return(True);
-}
-
-static int check_printdest_info(struct pack_desc* desc,
- int uLevel, char* id)
-{
- desc->subformat = NULL;
- switch( uLevel ) {
- case 0: desc->format = "B9"; break;
- case 1: desc->format = "B9B21WWzW"; break;
- case 2: desc->format = "z"; break;
- case 3: desc->format = "zzzWWzzzWW"; break;
- default: return False;
- }
- if (strcmp(desc->format,id) != 0) return False;
- return True;
-}
-
-static void fill_printdest_info(int cnum, int snum, int uLevel,
- struct pack_desc* desc)
-{
- char buf[100];
- strncpy(buf,SERVICE(snum),sizeof(buf)-1);
- buf[sizeof(buf)-1] = 0;
- strupper(buf);
- if (uLevel <= 1) {
- PACKS(desc,"B9",buf); /* szName */
- if (uLevel == 1) {
- PACKS(desc,"B21",""); /* szUserName */
- PACKI(desc,"W",0); /* uJobId */
- PACKI(desc,"W",0); /* fsStatus */
- PACKS(desc,"z",""); /* pszStatus */
- PACKI(desc,"W",0); /* time */
- }
- }
- if (uLevel == 2 || uLevel == 3) {
- PACKS(desc,"z",buf); /* pszPrinterName */
- if (uLevel == 3) {
- PACKS(desc,"z",""); /* pszUserName */
- PACKS(desc,"z",""); /* pszLogAddr */
- PACKI(desc,"W",0); /* uJobId */
- PACKI(desc,"W",0); /* fsStatus */
- PACKS(desc,"z",""); /* pszStatus */
- PACKS(desc,"z",""); /* pszComment */
- PACKS(desc,"z","NULL"); /* pszDrivers */
- PACKI(desc,"W",0); /* time */
- PACKI(desc,"W",0); /* pad1 */
- }
- }
-}
-
-static BOOL api_WPrintDestGetInfo(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- char* PrinterName = p;
- int uLevel,cbBuf;
- struct pack_desc desc;
- int snum;
-
- bzero(&desc,sizeof(desc));
-
- p = skip_string(p,1);
- uLevel = SVAL(p,0);
- cbBuf = SVAL(p,2);
-
- DEBUG(3,("WPrintDestGetInfo uLevel=%d PrinterName=%s\n",uLevel,PrinterName));
-
- /* check it's a supported varient */
- if (strcmp(str1,"zWrLh") != 0) return False;
- if (!check_printdest_info(&desc,uLevel,str2)) return False;
-
- snum = lp_servicenumber(PrinterName);
- if (snum < 0 && pcap_printername_ok(PrinterName,NULL)) {
- int pnum = lp_servicenumber(PRINTERS_NAME);
- if (pnum >= 0) {
- lp_add_printer(PrinterName,pnum);
- snum = lp_servicenumber(PrinterName);
- }
- }
-
- if (snum < 0) {
- *rdata_len = 0;
- desc.errcode = NERR_DestNotFound;
- desc.neededlen = 0;
- }
- else {
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- if (init_package(&desc,1,0)) {
- fill_printdest_info(cnum,snum,uLevel,&desc);
- }
- *rdata_len = desc.usedlen;
- }
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,desc.neededlen);
-
- DEBUG(4,("WPrintDestGetInfo: errorcode %d\n",desc.errcode));
- return(True);
-}
-
-static BOOL api_WPrintDestEnum(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel,cbBuf;
- int queuecnt;
- int i, n, succnt=0;
- struct pack_desc desc;
- int services = lp_numservices();
-
- bzero(&desc,sizeof(desc));
-
- uLevel = SVAL(p,0);
- cbBuf = SVAL(p,2);
-
- DEBUG(3,("WPrintDestEnum uLevel=%d\n",uLevel));
-
- /* check it's a supported varient */
- if (strcmp(str1,"WrLeh") != 0) return False;
- if (!check_printdest_info(&desc,uLevel,str2)) return False;
-
- queuecnt = 0;
- for (i = 0; i < services; i++)
- if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i))
- queuecnt++;
-
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- if (init_package(&desc,queuecnt,0)) {
- succnt = 0;
- n = 0;
- for (i = 0; i < services; i++) {
- if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
- fill_printdest_info(cnum,i,uLevel,&desc);
- n++;
- if (desc.errcode == NERR_Success) succnt = n;
- }
- }
- }
-
- *rdata_len = desc.usedlen;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,succnt);
- SSVAL(*rparam,6,queuecnt);
-
- DEBUG(4,("WPrintDestEnumerate: errorcode %d\n",desc.errcode));
- return(True);
-}
-
-static BOOL api_WPrintDriverEnum(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel,cbBuf;
- int succnt;
- struct pack_desc desc;
-
- bzero(&desc,sizeof(desc));
-
- uLevel = SVAL(p,0);
- cbBuf = SVAL(p,2);
-
- DEBUG(3,("WPrintDriverEnum uLevel=%d\n",uLevel));
-
- /* check it's a supported varient */
- if (strcmp(str1,"WrLeh") != 0) return False;
- if (uLevel != 0 || strcmp(str2,"B41") != 0) return False;
-
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- if (init_package(&desc,1,0)) {
- PACKS(&desc,"B41","NULL");
- }
-
- succnt = (desc.errcode == NERR_Success ? 1 : 0);
-
- *rdata_len = desc.usedlen;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,succnt);
- SSVAL(*rparam,6,1);
-
- DEBUG(4,("WPrintDriverEnum: errorcode %d\n",desc.errcode));
- return(True);
-}
-
-static BOOL api_WPrintQProcEnum(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel,cbBuf;
- int succnt;
- struct pack_desc desc;
-
- bzero(&desc,sizeof(desc));
-
- uLevel = SVAL(p,0);
- cbBuf = SVAL(p,2);
-
- DEBUG(3,("WPrintQProcEnum uLevel=%d\n",uLevel));
-
- /* check it's a supported varient */
- if (strcmp(str1,"WrLeh") != 0) return False;
- if (uLevel != 0 || strcmp(str2,"B13") != 0) return False;
-
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- desc.format = str2;
- if (init_package(&desc,1,0)) {
- PACKS(&desc,"B13","lpd");
- }
-
- succnt = (desc.errcode == NERR_Success ? 1 : 0);
-
- *rdata_len = desc.usedlen;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,succnt);
- SSVAL(*rparam,6,1);
-
- DEBUG(4,("WPrintQProcEnum: errorcode %d\n",desc.errcode));
- return(True);
-}
-
-static BOOL api_WPrintPortEnum(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel,cbBuf;
- int succnt;
- struct pack_desc desc;
-
- bzero(&desc,sizeof(desc));
-
- uLevel = SVAL(p,0);
- cbBuf = SVAL(p,2);
-
- DEBUG(3,("WPrintPortEnum uLevel=%d\n",uLevel));
-
- /* check it's a supported varient */
- if (strcmp(str1,"WrLeh") != 0) return False;
- if (uLevel != 0 || strcmp(str2,"B9") != 0) return False;
-
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- bzero(&desc,sizeof(desc));
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- desc.format = str2;
- if (init_package(&desc,1,0)) {
- PACKS(&desc,"B13","lp0");
- }
-
- succnt = (desc.errcode == NERR_Success ? 1 : 0);
-
- *rdata_len = desc.usedlen;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,succnt);
- SSVAL(*rparam,6,1);
-
- DEBUG(4,("WPrintPortEnum: errorcode %d\n",desc.errcode));
- return(True);
-}
-
-
-struct
-{
- char * name;
- char * pipename;
- int subcommand;
- BOOL (*fn) ();
-} api_fd_commands [] =
- {
- { "SetNmdPpHndState", "lsarpc", 1, api_LsarpcSNPHS },
-#ifdef NTDOMAIN
- { "TransactNmPipe", "lsarpc", 0x26, api_ntLsarpcTNP },
-#else
- { "TransactNmPipe", "lsarpc", 0x26, api_LsarpcTNP },
-#endif
- { NULL, NULL, -1, (BOOL (*)())api_Unsupported }
- };
-
-/****************************************************************************
- handle remote api calls delivered to a named pipe already opened.
- ****************************************************************************/
-static int api_fd_reply(int cnum,uint16 vuid,char *outbuf,
- uint16 *setup,char *data,char *params,
- int suwcnt,int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
-{
- char *rdata = NULL;
- char *rparam = NULL;
- int rdata_len = 0;
- int rparam_len = 0;
- BOOL reply=False;
- int i;
- int fd;
- int subcommand;
-
- /* First find out the name of this file. */
- if (suwcnt != 2)
- {
- DEBUG(0,("Unexpected named pipe transaction.\n"));
- return(-1);
- }
-
- /* Get the file handle and hence the file name. */
- fd = setup[1];
- subcommand = setup[0];
-
- DEBUG(3,("Got API command %d on pipe %s ",subcommand,Files[fd].name));
- DEBUG(3,("(tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d)\n",
- tdscnt,tpscnt,mdrcnt,mprcnt));
-
- for (i=0;api_fd_commands[i].name;i++)
- if (strequal(api_fd_commands[i].pipename, Files[fd].name) &&
- api_fd_commands[i].subcommand == subcommand &&
- api_fd_commands[i].fn)
- {
- DEBUG(3,("Doing %s\n",api_fd_commands[i].name));
- break;
- }
-
- rdata = (char *)malloc(1024); if (rdata) bzero(rdata,1024);
- rparam = (char *)malloc(1024); if (rparam) bzero(rparam,1024);
-
- reply = api_fd_commands[i].fn(cnum,vuid,params,data,mdrcnt,mprcnt,
- &rdata,&rparam,&rdata_len,&rparam_len);
-
- if (rdata_len > mdrcnt ||
- rparam_len > mprcnt)
- {
- reply = api_TooSmall(cnum,vuid,params,data,mdrcnt,mprcnt,
- &rdata,&rparam,&rdata_len,&rparam_len);
- }
-
-
- /* if we get False back then it's actually unsupported */
- if (!reply)
- api_Unsupported(cnum,vuid,params,data,mdrcnt,mprcnt,
- &rdata,&rparam,&rdata_len,&rparam_len);
-
- /* now send the reply */
- send_trans_reply(outbuf,rdata,rparam,NULL,rdata_len,rparam_len,0);
-
- if (rdata)
- free(rdata);
- if (rparam)
- free(rparam);
-
- return(-1);
-}
-
-
-
-/****************************************************************************
- the buffer was too small
- ****************************************************************************/
-static BOOL api_TooSmall(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- *rparam_len = MIN(*rparam_len,mprcnt);
- *rparam = REALLOC(*rparam,*rparam_len);
-
- *rdata_len = 0;
-
- SSVAL(*rparam,0,NERR_BufTooSmall);
-
- DEBUG(3,("Supplied buffer too small in API command\n"));
-
- return(True);
-}
-
-
-/****************************************************************************
- the request is not supported
- ****************************************************************************/
-static BOOL api_Unsupported(int cnum,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- *rdata_len = 0;
-
- SSVAL(*rparam,0,NERR_notsupported);
- SSVAL(*rparam,2,0); /* converter word */
-
- DEBUG(3,("Unsupported API command\n"));
-
- return(True);
-}
-
-
-
-
-struct
-{
- char *name;
- int id;
- BOOL (*fn)();
- int flags;
-} api_commands[] = {
- {"RNetShareEnum", 0, (BOOL (*)())api_RNetShareEnum,0},
- {"RNetShareGetInfo", 1, (BOOL (*)())api_RNetShareGetInfo,0},
- {"RNetServerGetInfo", 13, (BOOL (*)())api_RNetServerGetInfo,0},
- {"RNetUserGetInfo", 56, (BOOL (*)())api_RNetUserGetInfo,0},
- {"NetUserGetGroups", 59, (BOOL (*)())api_NetUserGetGroups,0},
- {"NetWkstaGetInfo", 63, (BOOL (*)())api_NetWkstaGetInfo,0},
- {"DosPrintQEnum", 69, (BOOL (*)())api_DosPrintQEnum,0},
- {"DosPrintQGetInfo", 70, (BOOL (*)())api_DosPrintQGetInfo,0},
- {"WPrintJobEnumerate",76, (BOOL (*)())api_WPrintJobEnumerate,0},
- {"WPrintJobGetInfo", 77, (BOOL (*)())api_WPrintJobGetInfo,0},
- {"RDosPrintJobDel", 81, (BOOL (*)())api_RDosPrintJobDel,0},
- {"RDosPrintJobPause", 82, (BOOL (*)())api_RDosPrintJobDel,0},
- {"RDosPrintJobResume",83, (BOOL (*)())api_RDosPrintJobDel,0},
- {"WPrintDestEnum", 84, (BOOL (*)())api_WPrintDestEnum,0},
- {"WPrintDestGetInfo", 85, (BOOL (*)())api_WPrintDestGetInfo,0},
- {"NetRemoteTOD", 91, (BOOL (*)())api_NetRemoteTOD,0},
- {"WPrintQueuePurge", 103, (BOOL (*)())api_WPrintQueuePurge,0},
- {"NetServerEnum", 104, (BOOL (*)())api_RNetServerEnum,0},
- {"WAccessGetUserPerms",105, (BOOL (*)())api_WAccessGetUserPerms,0},
- {"SetUserPassword", 115, (BOOL (*)())api_SetUserPassword,0},
- {"WWkstaUserLogon", 132, (BOOL (*)())api_WWkstaUserLogon,0},
- {"PrintJobInfo", 147, (BOOL (*)())api_PrintJobInfo,0},
- {"WPrintDriverEnum", 205, (BOOL (*)())api_WPrintDriverEnum,0},
- {"WPrintQProcEnum", 206, (BOOL (*)())api_WPrintQProcEnum,0},
- {"WPrintPortEnum", 207, (BOOL (*)())api_WPrintPortEnum,0},
- {NULL, -1, (BOOL (*)())api_Unsupported,0}};
-
-
-/****************************************************************************
- handle remote api calls
- ****************************************************************************/
-static int api_reply(int cnum,uint16 vuid,char *outbuf,char *data,char *params,
- int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
-{
- int api_command = SVAL(params,0);
- char *rdata = NULL;
- char *rparam = NULL;
- int rdata_len = 0;
- int rparam_len = 0;
- BOOL reply=False;
- int i;
-
- DEBUG(3,("Got API command %d of form <%s> <%s> (tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d)\n",
- api_command,params+2,skip_string(params+2,1),
- tdscnt,tpscnt,mdrcnt,mprcnt));
-
- for (i=0;api_commands[i].name;i++)
- if (api_commands[i].id == api_command && api_commands[i].fn)
- {
- DEBUG(3,("Doing %s\n",api_commands[i].name));
- break;
- }
-
- rdata = (char *)malloc(1024); if (rdata) bzero(rdata,1024);
- rparam = (char *)malloc(1024); if (rparam) bzero(rparam,1024);
-
- reply = api_commands[i].fn(cnum,vuid,params,data,mdrcnt,mprcnt,
- &rdata,&rparam,&rdata_len,&rparam_len);
-
-
- if (rdata_len > mdrcnt ||
- rparam_len > mprcnt)
- {
- reply = api_TooSmall(cnum,vuid,params,data,mdrcnt,mprcnt,
- &rdata,&rparam,&rdata_len,&rparam_len);
- }
-
-
- /* if we get False back then it's actually unsupported */
- if (!reply)
- api_Unsupported(cnum,vuid,params,data,mdrcnt,mprcnt,
- &rdata,&rparam,&rdata_len,&rparam_len);
-
-
-
- /* now send the reply */
- send_trans_reply(outbuf,rdata,rparam,NULL,rdata_len,rparam_len,0);
-
- if (rdata)
- free(rdata);
- if (rparam)
- free(rparam);
-
- return(-1);
-}
-
-/****************************************************************************
- handle named pipe commands
- ****************************************************************************/
-static int named_pipe(int cnum,uint16 vuid, char *outbuf,char *name,
- uint16 *setup,char *data,char *params,
- int suwcnt,int tdscnt,int tpscnt,
- int msrcnt,int mdrcnt,int mprcnt)
-{
-
- if (strequal(name,"LANMAN"))
- return(api_reply(cnum,vuid,outbuf,data,params,tdscnt,tpscnt,mdrcnt,mprcnt));
-
-if (strlen(name) < 1)
- return(api_fd_reply(cnum,vuid,outbuf,setup,data,params,suwcnt,tdscnt,tpscnt,mdrcnt,mprcnt));
-
-
- DEBUG(3,("named pipe command on <%s> 0x%X setup1=%d\n",
- name,(int)setup[0],(int)setup[1]));
-
- return(0);
-}
-
-
-/****************************************************************************
- reply to a SMBtrans
- ****************************************************************************/
-int reply_trans(char *inbuf,char *outbuf)
-{
- fstring name;
-
- char *data=NULL,*params=NULL;
- uint16 *setup=NULL;
-
- int outsize = 0;
- int cnum = SVAL(inbuf,smb_tid);
- uint16 vuid = SVAL(inbuf,smb_uid);
-
- int tpscnt = SVAL(inbuf,smb_vwv0);
- int tdscnt = SVAL(inbuf,smb_vwv1);
- int mprcnt = SVAL(inbuf,smb_vwv2);
- int mdrcnt = SVAL(inbuf,smb_vwv3);
- int msrcnt = CVAL(inbuf,smb_vwv4);
- BOOL close_on_completion = BITSETW(inbuf+smb_vwv5,0);
- BOOL one_way = BITSETW(inbuf+smb_vwv5,1);
- int pscnt = SVAL(inbuf,smb_vwv9);
- int psoff = SVAL(inbuf,smb_vwv10);
- int dscnt = SVAL(inbuf,smb_vwv11);
- int dsoff = SVAL(inbuf,smb_vwv12);
- int suwcnt = CVAL(inbuf,smb_vwv13);
-
- fstrcpy(name,smb_buf(inbuf));
-
- if (dscnt > tdscnt || pscnt > tpscnt) {
- exit_server("invalid trans parameters\n");
- }
-
- if (tdscnt)
- {
- data = (char *)malloc(tdscnt);
- memcpy(data,smb_base(inbuf)+dsoff,dscnt);
- }
- if (tpscnt)
- {
- params = (char *)malloc(tpscnt);
- memcpy(params,smb_base(inbuf)+psoff,pscnt);
- }
-
- if (suwcnt)
- {
- int i;
- setup = (uint16 *)malloc(suwcnt*sizeof(setup[0]));
- for (i=0;i<suwcnt;i++)
- setup[i] = SVAL(inbuf,smb_vwv14+i*SIZEOFWORD);
- }
-
-
- if (pscnt < tpscnt || dscnt < tdscnt)
- {
- /* We need to send an interim response then receive the rest
- of the parameter/data bytes */
- outsize = set_message(outbuf,0,0,True);
- show_msg(outbuf);
- send_smb(Client,outbuf);
- }
-
- /* receive the rest of the trans packet */
- while (pscnt < tpscnt || dscnt < tdscnt)
- {
- int pcnt,poff,dcnt,doff,pdisp,ddisp;
-
- if (!receive_smb(Client,inbuf, SMB_SECONDARY_WAIT) ||
- CVAL(inbuf, smb_com) != SMBtrans)
- {
- DEBUG(2,("Invalid secondary trans2 packet\n"));
- if (params) free(params);
- if (data) free(data);
- if (setup) free(setup);
- return(ERROR(ERRSRV,ERRerror));
- }
-
- show_msg(inbuf);
-
- tpscnt = SVAL(inbuf,smb_vwv0);
- tdscnt = SVAL(inbuf,smb_vwv1);
-
- pcnt = SVAL(inbuf,smb_vwv2);
- poff = SVAL(inbuf,smb_vwv3);
- pdisp = SVAL(inbuf,smb_vwv4);
-
- dcnt = SVAL(inbuf,smb_vwv5);
- doff = SVAL(inbuf,smb_vwv6);
- ddisp = SVAL(inbuf,smb_vwv7);
-
- pscnt += pcnt;
- dscnt += dcnt;
-
- if (dscnt > tdscnt || pscnt > tpscnt) {
- exit_server("invalid trans parameters\n");
- }
-
- if (pcnt)
- memcpy(params+pdisp,smb_base(inbuf)+poff,pcnt);
- if (dcnt)
- memcpy(data+ddisp,smb_base(inbuf)+doff,dcnt);
- }
-
-
- DEBUG(3,("trans <%s> data=%d params=%d setup=%d\n",name,tdscnt,tpscnt,suwcnt));
-
-
- if (strncmp(name,"\\PIPE\\",strlen("\\PIPE\\")) == 0)
- outsize = named_pipe(cnum,vuid,outbuf,name+strlen("\\PIPE\\"),setup,data,params,
- suwcnt,tdscnt,tpscnt,msrcnt,mdrcnt,mprcnt);
-
-
- if (data) free(data);
- if (params) free(params);
- if (setup) free(setup);
-
- if (close_on_completion)
- close_cnum(cnum,vuid);
-
- if (one_way)
- return(-1);
-
- if (outsize == 0)
- return(ERROR(ERRSRV,ERRnosupport));
-
- return(outsize);
-}
diff --git a/source/smbd/mangle.c b/source/smbd/mangle.c
deleted file mode 100644
index b0a45ffb47c..00000000000
--- a/source/smbd/mangle.c
+++ /dev/null
@@ -1,673 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Name mangling
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-
-#include "includes.h"
-
-extern int DEBUGLEVEL;
-extern int case_default;
-extern BOOL case_mangle;
-
-/****************************************************************************
-provide a checksum on a string
-****************************************************************************/
-int str_checksum(char *s)
-{
- int res = 0;
- int c;
- int i=0;
- while (*s)
- {
- c = *s;
- res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
- s++; i++;
- }
- return(res);
-}
-
-/****************************************************************************
-return True if a name is a special msdos reserved name
-****************************************************************************/
-static BOOL is_reserved_msdos(char *fname)
-{
- char upperFname[13];
- char *p;
-
- StrnCpy (upperFname, fname, 12);
-
- /* lpt1.txt and con.txt etc are also illegal */
- p=strchr(upperFname,'.');
- if (p)
- *p='\0';
- strupper (upperFname);
- if ((strcmp(upperFname,"CLOCK$") == 0) ||
- (strcmp(upperFname,"CON") == 0) ||
- (strcmp(upperFname,"AUX") == 0) ||
- (strcmp(upperFname,"COM1") == 0) ||
- (strcmp(upperFname,"COM2") == 0) ||
- (strcmp(upperFname,"COM3") == 0) ||
- (strcmp(upperFname,"COM4") == 0) ||
- (strcmp(upperFname,"LPT1") == 0) ||
- (strcmp(upperFname,"LPT2") == 0) ||
- (strcmp(upperFname,"LPT3") == 0) ||
- (strcmp(upperFname,"NUL") == 0) ||
- (strcmp(upperFname,"PRN") == 0))
- return (True) ;
-
- return (False);
-}
-
-
-
-/****************************************************************************
-return True if a name is in 8.3 dos format
-****************************************************************************/
-BOOL is_8_3(char *fname, BOOL check_case)
-{
- int len;
- char *dot_pos;
- char *slash_pos = strrchr(fname,'/');
- int l;
-
- if (slash_pos) fname = slash_pos+1;
- len = strlen(fname);
-
- DEBUG(5,("checking %s for 8.3\n",fname));
-
- if (check_case && case_mangle)
- switch (case_default)
- {
- case CASE_LOWER:
- if (strhasupper(fname)) return(False);
- break;
- case CASE_UPPER:
- if (strhaslower(fname)) return(False);
- break;
- }
-
- /* can't be longer than 12 chars */
- if (len == 0 || len > 12)
- return(False);
-
- /* can't be an MS-DOS Special file such as lpt1 or even lpt1.txt */
- if (is_reserved_msdos(fname))
- return(False);
-
- /* can't contain invalid dos chars */
- /* Windows use the ANSI charset.
- But filenames are translated in the PC charset.
- This Translation may be more or less relaxed depending
- the Windows application. */
-
- /* %%% A nice improvment to name mangling would be to translate
- filename to ANSI charset on the smb server host */
-
- dot_pos = strchr(fname,'.');
-
- {
- char *p = fname;
- if(lp_client_code_page() == KANJI_CODEPAGE)
- {
- dot_pos = 0;
- while (*p)
- {
- if (is_shift_jis (*p))
- p += 2;
- else if (is_kana (*p))
- p ++;
- else
- {
- if (*p == '.' && !dot_pos)
- dot_pos = (char *) p;
- if (!isdoschar(*p))
- return(False);
- p++;
- }
- }
- }
- else
- {
- while (*p)
- {
- if (!isdoschar(*p))
- return(False);
- p++;
- }
- }
- }
-
- /* no dot and less than 9 means OK */
- if (!dot_pos)
- return(len <= 8);
-
- l = PTR_DIFF(dot_pos,fname);
-
- /* base must be at least 1 char except special cases . and .. */
- if (l == 0)
- return(strcmp(fname,".") == 0 || strcmp(fname,"..") == 0);
-
- /* base can't be greater than 8 */
- if (l > 8)
- return(False);
-
- if (lp_strip_dot() &&
- len - l == 1 &&
- !strchr(dot_pos+1,'.'))
- {
- *dot_pos = 0;
- return(True);
- }
-
- /* extension must be between 1 and 3 */
- if ( (len - l < 2 ) || (len - l > 4) )
- return(False);
-
- /* extension can't have a dot */
- if (strchr(dot_pos+1,'.'))
- return(False);
-
- /* must be in 8.3 format */
- return(True);
-}
-
-
-
-/*
-keep a stack of name mangling results - just
-so file moves and copies have a chance of working
-*/
-fstring *mangled_stack = NULL;
-int mangled_stack_size = 0;
-int mangled_stack_len = 0;
-
-/****************************************************************************
-create the mangled stack
-****************************************************************************/
-void create_mangled_stack(int size)
-{
- if (mangled_stack)
- {
- free(mangled_stack);
- mangled_stack_size = 0;
- mangled_stack_len = 0;
- }
- if (size > 0)
- mangled_stack = (fstring *)malloc(sizeof(fstring)*size);
- if (mangled_stack) mangled_stack_size = size;
-}
-
-/****************************************************************************
-push a mangled name onto the stack
-****************************************************************************/
-static void push_mangled_name(char *s)
-{
- int i;
- char *p;
-
- if (!mangled_stack)
- return;
-
- for (i=0;i<mangled_stack_len;i++)
- if (strcmp(s,mangled_stack[i]) == 0)
- {
- array_promote(mangled_stack[0],sizeof(fstring),i);
- return;
- }
-
- memmove(mangled_stack[1],mangled_stack[0],
- sizeof(fstring)*MIN(mangled_stack_len,mangled_stack_size-1));
- strcpy(mangled_stack[0],s);
- p = strrchr(mangled_stack[0],'.');
- if (p && (!strhasupper(p+1)) && (strlen(p+1) < 4))
- *p = 0;
- mangled_stack_len = MIN(mangled_stack_size,mangled_stack_len+1);
-}
-
-/****************************************************************************
-check for a name on the mangled name stack
-****************************************************************************/
-BOOL check_mangled_stack(char *s)
-{
- int i;
- pstring tmpname;
- char extension[5];
- char *p = strrchr(s,'.');
- BOOL check_extension = False;
-
- extension[0] = 0;
-
- if (!mangled_stack) return(False);
-
- if (p)
- {
- check_extension = True;
- StrnCpy(extension,p,4);
- strlower(extension); /* XXXXXXX */
- }
-
- for (i=0;i<mangled_stack_len;i++)
- {
- strcpy(tmpname,mangled_stack[i]);
- mangle_name_83(tmpname);
- if (strequal(tmpname,s))
- {
- strcpy(s,mangled_stack[i]);
- break;
- }
- if (check_extension && !strchr(mangled_stack[i],'.'))
- {
- pstrcpy(tmpname,mangled_stack[i]);
- strcat(tmpname,extension);
- mangle_name_83(tmpname);
- if (strequal(tmpname,s))
- {
- strcpy(s,mangled_stack[i]);
- strcat(s,extension);
- break;
- }
- }
- }
-
- if (i < mangled_stack_len)
- {
- DEBUG(3,("Found %s on mangled stack as %s\n",s,mangled_stack[i]));
- array_promote(mangled_stack[0],sizeof(fstring),i);
- return(True);
- }
-
- return(False);
-}
-
-static char *map_filename(char *s, /* This is null terminated */
- char *pattern, /* This isn't. */
- int len) /* This is the length of pattern. */
-{
- static pstring matching_bit; /* The bit of the string which matches */
- /* a * in pattern if indeed there is a * */
- char *sp; /* Pointer into s. */
- char *pp; /* Pointer into p. */
- char *match_start; /* Where the matching bit starts. */
- pstring pat;
-
- StrnCpy(pat, pattern, len); /* Get pattern into a proper string! */
- pstrcpy(matching_bit,""); /* Match but no star gets this. */
- pp = pat; /* Initialise the pointers. */
- sp = s;
- if ((len == 1) && (*pattern == '*')) {
- return NULL; /* Impossible, too ambiguous for */
- /* words! */
- }
-
- while ((*sp) /* Not the end of the string. */
- && (*pp) /* Not the end of the pattern. */
- && (*sp == *pp) /* The two match. */
- && (*pp != '*')) { /* No wildcard. */
- sp++; /* Keep looking. */
- pp++;
- }
- if (!*sp && !*pp) /* End of pattern. */
- return matching_bit; /* Simple match. Return empty string. */
- if (*pp == '*') {
- pp++; /* Always interrested in the chacter */
- /* after the '*' */
- if (!*pp) { /* It is at the end of the pattern. */
- StrnCpy(matching_bit, s, sp-s);
- return matching_bit;
- } else {
- /* The next character in pattern must match a character further */
- /* along s than sp so look for that character. */
- match_start = sp;
- while ((*sp) /* Not the end of s. */
- && (*sp != *pp)) /* Not the same */
- sp++; /* Keep looking. */
- if (!*sp) { /* Got to the end without a match. */
- return NULL;
- } else { /* Still hope for a match. */
- /* Now sp should point to a matching character. */
- StrnCpy(matching_bit, match_start, sp-match_start);
- /* Back to needing a stright match again. */
- while ((*sp) /* Not the end of the string. */
- && (*pp) /* Not the end of the pattern. */
- && (*sp == *pp)) { /* The two match. */
- sp++; /* Keep looking. */
- pp++;
- }
- if (!*sp && !*pp) /* Both at end so it matched */
- return matching_bit;
- else
- return NULL;
- }
- }
- }
- return NULL; /* No match. */
-}
-
-
-/* this is the magic char used for mangling */
-char magic_char = '~';
-
-
-/****************************************************************************
-determine whther is name could be a mangled name
-****************************************************************************/
-BOOL is_mangled(char *s)
-{
- char *m = strchr(s,magic_char);
- if (!m) return(False);
-
- /* we use two base 36 chars efore the extension */
- if (m[1] == '.' || m[1] == 0 ||
- m[2] == '.' || m[2] == 0 ||
- (m[3] != '.' && m[3] != 0))
- return(is_mangled(m+1));
-
- /* it could be */
- return(True);
-}
-
-
-
-/****************************************************************************
-return a base 36 character. v must be from 0 to 35.
-****************************************************************************/
-static char base36(unsigned int v)
-{
- static char basechars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- return basechars[v % 36];
-}
-
-
-static void do_fwd_mangled_map(char *s, char *MangledMap)
-{
- /* MangledMap is a series of name pairs in () separated by spaces.
- * If s matches the first of the pair then the name given is the
- * second of the pair. A * means any number of any character and if
- * present in the second of the pair as well as the first the
- * matching part of the first string takes the place of the * in the
- * second.
- *
- * I wanted this so that we could have RCS files which can be used
- * by UNIX and DOS programs. My mapping string is (RCS rcs) which
- * converts the UNIX RCS file subdirectory to lowercase thus
- * preventing mangling.
- */
- char *start=MangledMap; /* Use this to search for mappings. */
- char *end; /* Used to find the end of strings. */
- char *match_string;
- pstring new_string; /* Make up the result here. */
- char *np; /* Points into new_string. */
-
- DEBUG(5,("Mangled Mapping '%s' map '%s'\n", s, MangledMap));
- while (*start) {
- while ((*start) && (*start != '('))
- start++;
- if (!*start)
- continue; /* Always check for the end. */
- start++; /* Skip the ( */
- end = start; /* Search for the ' ' or a ')' */
- DEBUG(5,("Start of first in pair '%s'\n", start));
- while ((*end) && !((*end == ' ') || (*end == ')')))
- end++;
- if (!*end) {
- start = end;
- continue; /* Always check for the end. */
- }
- DEBUG(5,("End of first in pair '%s'\n", end));
- if ((match_string = map_filename(s, start, end-start))) {
- DEBUG(5,("Found a match\n"));
- /* Found a match. */
- start = end+1; /* Point to start of what it is to become. */
- DEBUG(5,("Start of second in pair '%s'\n", start));
- end = start;
- np = new_string;
- while ((*end) /* Not the end of string. */
- && (*end != ')') /* Not the end of the pattern. */
- && (*end != '*')) /* Not a wildcard. */
- *np++ = *end++;
- if (!*end) {
- start = end;
- continue; /* Always check for the end. */
- }
- if (*end == '*') {
- pstrcpy(np, match_string);
- np += strlen(match_string);
- end++; /* Skip the '*' */
- while ((*end) /* Not the end of string. */
- && (*end != ')') /* Not the end of the pattern. */
- && (*end != '*')) /* Not a wildcard. */
- *np++ = *end++;
- }
- if (!*end) {
- start = end;
- continue; /* Always check for the end. */
- }
- *np++ = '\0'; /* NULL terminate it. */
- DEBUG(5,("End of second in pair '%s'\n", end));
- pstrcpy(s, new_string); /* Substitute with the new name. */
- DEBUG(5,("s is now '%s'\n", s));
- }
- start = end; /* Skip a bit which cannot be wanted */
- /* anymore. */
- start++;
- }
-}
-
-/****************************************************************************
-do the actual mangling to 8.3 format
-****************************************************************************/
-void mangle_name_83(char *s)
-{
- int csum = str_checksum(s);
- char *p;
- char extension[4];
- char base[9];
- int baselen = 0;
- int extlen = 0;
-
- extension[0]=0;
- base[0]=0;
-
- p = strrchr(s,'.');
- if (p && (strlen(p+1)<4) )
- {
- BOOL all_normal = (strisnormal(p+1)); /* XXXXXXXXX */
- if (all_normal && p[1] != 0)
- {
- *p = 0;
- csum = str_checksum(s);
- *p = '.';
- }
- }
-
-
- strupper(s);
-
- DEBUG(5,("Mangling name %s to ",s));
-
- if (p)
- {
- if (p == s)
- strcpy(extension,"___");
- else
- {
- *p++ = 0;
- while (*p && extlen < 3)
- {
- if(lp_client_code_page() == KANJI_CODEPAGE)
- {
- if (is_shift_jis (*p))
- {
- if (extlen < 2)
- {
- extension[extlen++] = p[0];
- extension[extlen++] = p[1];
- }
- else
- {
- extension[extlen++] = base36 (((unsigned char) *p) % 36);
- }
- p += 2;
- }
- else if (is_kana (*p))
- {
- extension[extlen++] = p[0];
- p++;
- }
- else
- {
- if (isdoschar (*p) && *p != '.')
- extension[extlen++] = p[0];
- p++;
- }
- }
- else
- {
- if (isdoschar(*p) && *p != '.')
- extension[extlen++] = *p;
- p++;
- }
- }
- extension[extlen] = 0;
- }
- }
-
- p = s;
-
- while (*p && baselen < 5)
- {
- if(lp_client_code_page() == KANJI_CODEPAGE)
- {
- if (is_shift_jis (*p))
- {
- if (baselen < 4)
- {
- base[baselen++] = p[0];
- base[baselen++] = p[1];
- }
- else
- {
- base[baselen++] = base36 (((unsigned char) *p) % 36);
- }
- p += 2;
- }
- else if (is_kana (*p))
- {
- base[baselen++] = p[0];
- p++;
- }
- else
- {
- if (isdoschar (*p) && *p != '.')
- base[baselen++] = p[0];
- p++;
- }
- }
- else
- {
- if (isdoschar(*p) && *p != '.')
- base[baselen++] = *p;
- p++;
- }
- }
- base[baselen] = 0;
-
- csum = csum % (36*36);
-
- sprintf(s,"%s%c%c%c",base,magic_char,base36(csum/36),base36(csum%36));
-
- if (*extension)
- {
- strcat(s,".");
- strcat(s,extension);
- }
- DEBUG(5,("%s\n",s));
-}
-
-
-
-/*******************************************************************
- work out if a name is illegal, even for long names
- ******************************************************************/
-static BOOL illegal_name(char *name)
-{
- static unsigned char illegal[256];
- static BOOL initialised=False;
- unsigned char *s;
-
- if (!initialised)
- {
- char *ill = "*\\/?<>|\":{}";
- initialised = True;
-
- bzero((char *)illegal,256);
- for (s = (unsigned char *)ill; *s; s++)
- illegal[*s] = True;
- }
-
- if(lp_client_code_page() == KANJI_CODEPAGE)
- {
- for (s = (unsigned char *)name; *s;) {
- if (is_shift_jis (*s)) {
- s += 2;
- } else if (illegal[*s]) {
- return(True);
- } else {
- s++;
- }
- }
- }
- else
- {
- for (s = (unsigned char *)name;*s;s++)
- if (illegal[*s]) return(True);
- }
-
- return(False);
-}
-
-
-/****************************************************************************
-convert a filename to DOS format. return True if successful.
-****************************************************************************/
-BOOL name_map_mangle(char *OutName,BOOL need83,int snum)
-{
-#ifdef MANGLE_LONG_FILENAMES
- if (!need83 && illegal_name(OutName)) need83 = True;
-#endif
-
- /* apply any name mappings */
- {
- char *map = lp_mangled_map(snum);
- if (map && *map)
- do_fwd_mangled_map(OutName,map);
- }
-
- /* check if it's already in 8.3 format */
- if (need83 && !is_8_3(OutName, True)) {
- if (!lp_manglednames(snum)) return(False);
-
- /* mangle it into 8.3 */
- push_mangled_name(OutName);
- mangle_name_83(OutName);
- }
-
- return(True);
-}
-
diff --git a/source/smbd/message.c b/source/smbd/message.c
deleted file mode 100644
index 64253932abb..00000000000
--- a/source/smbd/message.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- SMB messaging
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-/*
- This file handles the messaging system calls for winpopup style
- messages
-*/
-
-
-#include "includes.h"
-
-/* look in server.c for some explanation of these variables */
-extern int DEBUGLEVEL;
-
-
-static char msgbuf[1600];
-static int msgpos=0;
-static fstring msgfrom="";
-static fstring msgto="";
-
-/****************************************************************************
-deliver the message
-****************************************************************************/
-static void msg_deliver(void)
-{
- pstring s;
- fstring name;
- int i;
- int fd;
-
- if (! (*lp_msg_command()))
- {
- DEBUG(1,("no messaging command specified\n"));
- msgpos = 0;
- return;
- }
-
- /* put it in a temporary file */
- sprintf(s,"%s/msg.XXXXXX",tmpdir());
- fstrcpy(name,(char *)mktemp(s));
-
- fd = open(name,O_WRONLY|O_CREAT|O_TRUNC|O_EXCL,0600);
- if (fd == -1) {
- DEBUG(1,("can't open message file %s\n",name));
- return;
- }
-
- for (i=0;i<msgpos;) {
- if (msgbuf[i]=='\r' && i<(msgpos-1) && msgbuf[i+1]=='\n') {
- i++; continue;
- }
- write(fd,&msgbuf[i++],1);
- }
- close(fd);
-
-
- /* run the command */
- if (*lp_msg_command())
- {
- pstrcpy(s,lp_msg_command());
- string_sub(s,"%s",name);
- string_sub(s,"%f",msgfrom);
- string_sub(s,"%t",msgto);
- standard_sub(-1,s);
- smbrun(s,NULL,False);
- }
-
- msgpos = 0;
-}
-
-
-
-/****************************************************************************
- reply to a sends
-****************************************************************************/
-int reply_sends(char *inbuf,char *outbuf)
-{
- int len;
- char *orig,*dest,*msg;
- int outsize = 0;
-
- msgpos = 0;
-
-
- if (! (*lp_msg_command()))
- return(ERROR(ERRSRV,ERRmsgoff));
-
- outsize = set_message(outbuf,0,0,True);
-
- orig = smb_buf(inbuf)+1;
- dest = skip_string(orig,1)+1;
- msg = skip_string(dest,1)+1;
-
- fstrcpy(msgfrom,orig);
- fstrcpy(msgto,dest);
-
- len = SVAL(msg,0);
- len = MIN(len,1600-msgpos);
-
- memcpy(&msgbuf[msgpos],msg+2,len);
- msgpos += len;
-
- DEBUG(3,("%s SMBsends (from %s to %s)\n",timestring(),orig,dest));
-
- msg_deliver();
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a sendstrt
-****************************************************************************/
-int reply_sendstrt(char *inbuf,char *outbuf)
-{
- char *orig,*dest;
- int outsize = 0;
-
- if (! (*lp_msg_command()))
- return(ERROR(ERRSRV,ERRmsgoff));
-
- outsize = set_message(outbuf,1,0,True);
-
- msgpos = 0;
-
- orig = smb_buf(inbuf)+1;
- dest = skip_string(orig,1)+1;
-
- fstrcpy(msgfrom,orig);
- fstrcpy(msgto,dest);
-
- DEBUG(3,("%s SMBsendstrt (from %s to %s)\n",timestring(),msgfrom,msgto));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a sendtxt
-****************************************************************************/
-int reply_sendtxt(char *inbuf,char *outbuf)
-{
- int len;
- int outsize = 0;
- char *msg;
-
- if (! (*lp_msg_command()))
- return(ERROR(ERRSRV,ERRmsgoff));
-
- outsize = set_message(outbuf,0,0,True);
-
- msg = smb_buf(inbuf) + 1;
-
- len = SVAL(msg,0);
- len = MIN(len,1600-msgpos);
-
- memcpy(&msgbuf[msgpos],msg+2,len);
- msgpos += len;
-
- DEBUG(3,("%s SMBsendtxt\n",timestring()));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a sendend
-****************************************************************************/
-int reply_sendend(char *inbuf,char *outbuf)
-{
- int outsize = 0;
-
- if (! (*lp_msg_command()))
- return(ERROR(ERRSRV,ERRmsgoff));
-
- outsize = set_message(outbuf,0,0,True);
-
- DEBUG(3,("%s SMBsendend\n",timestring()));
-
- msg_deliver();
-
- return(outsize);
-}
-
diff --git a/source/smbd/password.c b/source/smbd/password.c
deleted file mode 100644
index f4d94791cf3..00000000000
--- a/source/smbd/password.c
+++ /dev/null
@@ -1,1707 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Password and authentication handling
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-
-#include "includes.h"
-
-#if (defined(NETGROUP) && defined (AUTOMOUNT))
-#include "rpcsvc/ypclnt.h"
-#endif
-
-extern int DEBUGLEVEL;
-extern int Protocol;
-
-/* users from session setup */
-static pstring session_users="";
-
-/* these are kept here to keep the string_combinations function simple */
-static char this_user[100]="";
-static char this_salt[100]="";
-static char this_crypted[100]="";
-
-/* Data to do lanman1/2 password challenge. */
-static unsigned char saved_challenge[8];
-static BOOL challenge_sent=False;
-
-/*******************************************************************
-Get the next challenge value - no repeats.
-********************************************************************/
-void generate_next_challenge(char *challenge)
-{
- unsigned char buf[16];
- static int counter = 0;
- struct timeval tval;
- int v1,v2;
-
- /* get a sort-of random number */
- GetTimeOfDay(&tval);
- v1 = (counter++) + getpid() + tval.tv_sec;
- v2 = (counter++) * getpid() + tval.tv_usec;
- SIVAL(challenge,0,v1);
- SIVAL(challenge,4,v2);
-
- /* mash it up with md4 */
- mdfour(buf, (unsigned char *)challenge, 8);
-
- memcpy(saved_challenge, buf, 8);
- memcpy(challenge,buf,8);
- challenge_sent = True;
-}
-
-/*******************************************************************
-set the last challenge sent, usually from a password server
-********************************************************************/
-BOOL set_challenge(char *challenge)
-{
- memcpy(saved_challenge,challenge,8);
- challenge_sent = True;
- return(True);
-}
-
-/*******************************************************************
-get the last challenge sent
-********************************************************************/
-BOOL last_challenge(char *challenge)
-{
- if (!challenge_sent) return(False);
- memcpy(challenge,saved_challenge,8);
- return(True);
-}
-
-/* this holds info on user ids that are already validated for this VC */
-static user_struct *validated_users = NULL;
-static int num_validated_users = 0;
-
-/****************************************************************************
-check if a uid has been validated, and return an pointer to the user_struct
-if it has. NULL if not. vuid is biased by an offset. This allows us to
-tell random client vuid's (normally zero) from valid vuids.
-****************************************************************************/
-user_struct *get_valid_user_struct(uint16 vuid)
-{
- if(vuid == UID_FIELD_INVALID)
- return NULL;
- vuid -= VUID_OFFSET;
- if((vuid >= (uint16)num_validated_users) ||
- (validated_users[vuid].uid == -1) || (validated_users[vuid].gid == -1))
- return NULL;
- return &validated_users[vuid];
-}
-
-/****************************************************************************
-invalidate a uid
-****************************************************************************/
-void invalidate_vuid(uint16 vuid)
-{
- user_struct *vuser = get_valid_user_struct(vuid);
- if(vuser == 0)
- return;
-
- vuser->uid = -1;
- vuser->gid = -1;
- vuser->user_ngroups = 0;
- if(vuser->user_groups &&
- (vuser->user_groups != (gid_t *)vuser->user_igroups))
- free(vuser->user_groups);
- vuser->user_groups = NULL;
- if(vuser->user_igroups)
- free(vuser->user_igroups);
- vuser->user_igroups = NULL;
-}
-
-
-/****************************************************************************
-return a validated username
-****************************************************************************/
-char *validated_username(uint16 vuid)
-{
- user_struct *vuser = get_valid_user_struct(vuid);
- if(vuser == 0)
- return 0;
- return(vuser->name);
-}
-
-/****************************************************************************
-register a uid/name pair as being valid and that a valid password
-has been given. vuid is biased by an offset. This allows us to
-tell random client vuid's (normally zero) from valid vuids.
-****************************************************************************/
-uint16 register_vuid(int uid,int gid, char *name,BOOL guest)
-{
- user_struct *vuser;
-
-#if (defined(NETGROUP) && defined (AUTOMOUNT))
- int nis_error; /* returned by yp all functions */
- char *nis_result; /* yp_match inits this */
- int nis_result_len; /* and set this */
- char *nis_domain; /* yp_get_default_domain inits this */
- char *nis_map = (char *)lp_nis_home_map_name();
- int home_server_len;
-#endif
- struct passwd *pwfile; /* for getting real name from passwd file */
- int real_name_len;
-
-#if 0
- /*
- * After observing MS-Exchange services writing to a Samba share
- * I belive this code is incorrect. Each service does it's own
- * sessionsetup_and_X for the same user, and as each service shuts
- * down, it does a user_logoff_and_X. As we are consolidating multiple
- * sessionsetup_and_X's onto the same vuid here, when the first service
- * shuts down, it invalidates all the open files for the other services.
- * Hence I am removing this code and forcing each sessionsetup_and_X
- * to get a new vuid.
- * Jeremy Allison. (jallison@whistle.com).
- */
-
- int i;
- for(i = 0; i < num_validated_users; i++) {
- vuser = &validated_users[i];
- if( vuser->uid == uid )
- return (uint16)(i + VUID_OFFSET); /* User already validated */
- }
-#endif
-
- validated_users = (user_struct *)Realloc(validated_users,
- sizeof(user_struct)*
- (num_validated_users+1));
-
- if (!validated_users)
- {
- DEBUG(0,("Failed to realloc users struct!\n"));
- num_validated_users = 0;
- return UID_FIELD_INVALID;
- }
-
- vuser = &validated_users[num_validated_users];
- num_validated_users++;
-
- vuser->uid = uid;
- vuser->gid = gid;
- vuser->guest = guest;
- strcpy(vuser->name,name);
-
- vuser->user_ngroups = 0;
- vuser->user_groups = NULL;
- vuser->user_igroups = NULL;
-
- /* Find all the groups this uid is in and store them.
- Used by become_user() */
- setup_groups(name,uid,gid,
- &vuser->user_ngroups,
- &vuser->user_igroups,
- &vuser->user_groups);
-
- DEBUG(3,("uid %d registered to name %s\n",uid,name));
-
-#if (defined(NETGROUP) && defined (AUTOMOUNT))
- vuser->home_share = NULL;
- DEBUG(3, ("Setting default HOMESHR to: \\\\logon server\\HOMES\n"));
- vuser->home_share = Realloc(vuser->home_share, 32);
- strcpy(vuser->home_share,"\\\\%L\\HOMES");
-
- if (nis_error = yp_get_default_domain(&nis_domain))
- DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
- DEBUG(3, ("NIS Domain: %s\n", nis_domain));
-
- if (nis_error = yp_match(nis_domain, nis_map, vuser->name, strlen(vuser->name),
- &nis_result, &nis_result_len))
- DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
- if (!nis_error && lp_nis_home_map()) {
- home_server_len = strcspn(nis_result,":");
- DEBUG(3, ("NIS lookup succeeded\n\tHome server length: %d\n",home_server_len));
- vuser->home_share = (char *)Realloc(vuser->home_share, home_server_len+12);
- DEBUG(3, ("\tAllocated %d bytes for HOMESHR\n",home_server_len+12 ));
- strcpy(vuser->home_share,"\\\\");
- strncat(vuser->home_share, nis_result, home_server_len);
- strcat(vuser->home_share,"\\homes");
- DEBUG(2,("\tUser = %s\n\tUID = %d\n\tNIS result = %s\n\tHOMESHR = %s\n",
- vuser->name, vuser->uid, nis_result, vuser->home_share));
- }
-#endif
-
- vuser->real_name = NULL;
- DEBUG(3, ("Clearing default real name\n"));
- vuser->real_name = Realloc(vuser->real_name, 15);
- strcpy(vuser->real_name, "<Full Name>\0");
- if (lp_unix_realname()) {
- if((pwfile=getpwnam(vuser->name))!= NULL)
- {
- DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->name,pwfile->pw_gecos));
- real_name_len = strcspn(pwfile->pw_gecos, ",");
- DEBUG(3, ("Real name length: %d\n", real_name_len));
- vuser->real_name = (char *)Realloc(vuser->real_name, real_name_len+1);
- strncpy(vuser->real_name, pwfile->pw_gecos, real_name_len);
- vuser->real_name[real_name_len]='\0';
- }
- }
-
- return (uint16)((num_validated_users - 1) + VUID_OFFSET);
-}
-
-
-/****************************************************************************
-add a name to the session users list
-****************************************************************************/
-void add_session_user(char *user)
-{
- fstring suser;
- StrnCpy(suser,user,sizeof(suser)-1);
-
- if (!Get_Pwnam(suser,True)) return;
-
- if (suser && *suser && !in_list(suser,session_users,False))
- {
- if (strlen(suser) + strlen(session_users) + 2 >= sizeof(pstring))
- DEBUG(1,("Too many session users??\n"));
- else
- {
- strcat(session_users," ");
- strcat(session_users,suser);
- }
- }
-}
-
-
-#ifdef NO_GETSPNAM
-/* a fake shadow password routine which just fills a fake spwd struct
- * with the sp_pwdp field. (sreiz@aie.nl)
- */
-static struct spwd *getspnam(char *username) /* fake shadow password routine */
-{
- FILE *f;
- char line[1024];
- static char pw[20];
- static struct spwd static_spwd;
-
- static_spwd.sp_pwdp=0;
- if (!(f=fopen("/etc/master.passwd", "r")))
- return 0;
- while (fgets(line, 1024, f)) {
- if (!strncmp(line, username, strlen(username)) &&
- line[strlen(username)]==':') { /* found entry */
- char *p, *q;
-
- p=line+strlen(username)+1;
- if ((q=strchr(p, ':'))) {
- *q=0;
- if (q-p+1>20)
- break;
- strcpy(pw, p);
- static_spwd.sp_pwdp=pw;
- }
- break;
- }
- }
- fclose(f);
- if (static_spwd.sp_pwdp)
- return &static_spwd;
- return 0;
-}
-#endif
-
-
-#ifdef OSF1_ENH_SEC
-/****************************************************************************
-an enhanced crypt for OSF1
-****************************************************************************/
-static char *osf1_bigcrypt(char *password,char *salt1)
-{
- static char result[AUTH_MAX_PASSWD_LENGTH] = "";
- char *p1;
- char *p2=password;
- char salt[3];
- int i;
- int parts = strlen(password) / AUTH_CLEARTEXT_SEG_CHARS;
- if (strlen(password)%AUTH_CLEARTEXT_SEG_CHARS)
- parts++;
-
- StrnCpy(salt,salt1,2);
- StrnCpy(result,salt1,2);
-
- for (i=0; i<parts;i++)
- {
- p1 = crypt(p2,salt);
- strcat(result,p1+2);
- StrnCpy(salt,&result[2+i*AUTH_CIPHERTEXT_SEG_CHARS],2);
- p2 += AUTH_CLEARTEXT_SEG_CHARS;
- }
-
- return(result);
-}
-#endif
-
-
-/****************************************************************************
-update the enhanced security database. Only relevant for OSF1 at the moment.
-****************************************************************************/
-static void update_protected_database( char *user, BOOL result)
-{
-#ifdef OSF1_ENH_SEC
- struct pr_passwd *mypasswd;
- time_t starttime;
-
- mypasswd = getprpwnam (user);
- starttime = time (NULL);
-
- if (result)
- {
- mypasswd->ufld.fd_slogin = starttime;
- mypasswd->ufld.fd_nlogins = 0;
-
- putprpwnam(user,mypasswd);
-
- DEBUG(3,("Update protected database for Account %s after succesful connection\n",user));
- }
- else
- {
- mypasswd->ufld.fd_ulogin = starttime;
- mypasswd->ufld.fd_nlogins = mypasswd->ufld.fd_nlogins + 1;
- if ( mypasswd->ufld.fd_max_tries != 0 && mypasswd->ufld.fd_nlogins > mypasswd->ufld.fd_max_tries )
- {
- mypasswd->uflg.fg_lock = 0;
- DEBUG(3,("Account is disabled -- see Account Administrator.\n"));
- }
- putprpwnam ( user , mypasswd );
- DEBUG(3,("Update protected database for Account %s after refusing connection\n",user));
- }
-#else
- DEBUG(6,("Updated database with %s %s\n",user,BOOLSTR(result)));
-#endif
-}
-
-
-#ifdef USE_PAM
-/*******************************************************************
-check on PAM authentication
-********************************************************************/
-
-/* We first need some helper functions */
-#include <security/pam_appl.h>
-/* Static variables used to communicate between the conversation function
- * and the server_login function
- */
-static char *PAM_username;
-static char *PAM_password;
-
-/* PAM conversation function
- * Here we assume (for now, at least) that echo on means login name, and
- * echo off means password.
- */
-static int PAM_conv (int num_msg,
- struct pam_message **msg,
- struct pam_response **resp,
- void *appdata_ptr) {
- int count = 0, replies = 0;
- struct pam_response *reply = NULL;
- int size = sizeof(struct pam_response);
-
- #define GET_MEM if (reply) realloc(reply, size); else reply = malloc(size); \
- if (!reply) return PAM_CONV_ERR; \
- size += sizeof(struct pam_response)
- #define COPY_STRING(s) (s) ? strdup(s) : NULL
-
- for (count = 0; count < num_msg; count++) {
- switch (msg[count]->msg_style) {
- case PAM_PROMPT_ECHO_ON:
- GET_MEM;
- reply[replies].resp_retcode = PAM_SUCCESS;
- reply[replies++].resp = COPY_STRING(PAM_username);
- /* PAM frees resp */
- break;
- case PAM_PROMPT_ECHO_OFF:
- GET_MEM;
- reply[replies].resp_retcode = PAM_SUCCESS;
- reply[replies++].resp = COPY_STRING(PAM_password);
- /* PAM frees resp */
- break;
- case PAM_TEXT_INFO:
- /* ignore it... */
- break;
- case PAM_ERROR_MSG:
- default:
- /* Must be an error of some sort... */
- free (reply);
- return PAM_CONV_ERR;
- }
- }
- if (reply) *resp = reply;
- return PAM_SUCCESS;
-}
-static struct pam_conv PAM_conversation = {
- &PAM_conv,
- NULL
-};
-
-
-static BOOL pam_auth(char *this_user,char *password)
-{
- pam_handle_t *pamh;
- int pam_error;
-
- /* Now use PAM to do authentication. For now, we won't worry about
- * session logging, only authentication. Bail out if there are any
- * errors. Since this is a limited protocol, and an even more limited
- * function within a server speaking this protocol, we can't be as
- * verbose as would otherwise make sense.
- * Query: should we be using PAM_SILENT to shut PAM up?
- */
- #define PAM_BAIL if (pam_error != PAM_SUCCESS) { \
- pam_end(pamh, 0); return False; \
- }
- PAM_password = password;
- PAM_username = this_user;
- pam_error = pam_start("samba", this_user, &PAM_conversation, &pamh);
- PAM_BAIL;
- pam_error = pam_authenticate(pamh, 0);
- PAM_BAIL;
- /* It is not clear to me that account management is the right thing
- * to do, but it is not clear that it isn't, either. This can be
- * removed if no account management should be done. Alternately,
- * put a pam_allow.so entry in /etc/pam.conf for account handling. */
- pam_error = pam_acct_mgmt(pamh, 0);
- PAM_BAIL;
- pam_end(pamh, PAM_SUCCESS);
- /* If this point is reached, the user has been authenticated. */
- return(True);
-}
-#endif
-
-
-#ifdef AFS_AUTH
-/*******************************************************************
-check on AFS authentication
-********************************************************************/
-static BOOL afs_auth(char *this_user,char *password)
-{
- long password_expires = 0;
- char *reason;
-
- /* For versions of AFS prior to 3.3, this routine has few arguments, */
- /* but since I can't find the old documentation... :-) */
- setpag();
- if (ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION+KA_USERAUTH_DOSETPAG,
- this_user,
- (char *) 0, /* instance */
- (char *) 0, /* cell */
- password,
- 0, /* lifetime, default */
- &password_expires, /*days 'til it expires */
- 0, /* spare 2 */
- &reason) == 0)
- return(True);
- return(False);
-}
-#endif
-
-
-#ifdef DFS_AUTH
-
-sec_login_handle_t my_dce_sec_context;
-int dcelogin_atmost_once = 0;
-
-/*******************************************************************
-check on a DCE/DFS authentication
-********************************************************************/
-static BOOL dfs_auth(char *this_user,char *password)
-{
- error_status_t err;
- int err2;
- int prterr;
- boolean32 password_reset;
- sec_passwd_rec_t my_dce_password;
- sec_login_auth_src_t auth_src = sec_login_auth_src_network;
- unsigned char dce_errstr[dce_c_error_string_len];
-
- /*
- * We only go for a DCE login context if the given password
- * matches that stored in the local password file..
- * Assumes local passwd file is kept in sync w/ DCE RGY!
- */
-
- if (!strcmp((char *)crypt(password,this_salt),this_crypted) ||
- dcelogin_atmost_once)
- return(False);
-
- if (sec_login_setup_identity(
- (unsigned char *)this_user,
- sec_login_no_flags,
- &my_dce_sec_context,
- &err) == 0)
- {
- dce_error_inq_text(err, dce_errstr, &err2);
- DEBUG(0,("DCE Setup Identity for %s failed: %s\n",
- this_user,dce_errstr));
- return(False);
- }
-
- my_dce_password.version_number = sec_passwd_c_version_none;
- my_dce_password.pepper = NULL;
- my_dce_password.key.key_type = sec_passwd_plain;
- my_dce_password.key.tagged_union.plain = (idl_char *)password;
-
- if (sec_login_valid_and_cert_ident(my_dce_sec_context,
- &my_dce_password,
- &password_reset,
- &auth_src,
- &err) == 0 )
- {
- dce_error_inq_text(err, dce_errstr, &err2);
- DEBUG(0,("DCE Identity Validation failed for principal %s: %s\n",
- this_user,dce_errstr));
-
- return(False);
- }
-
- sec_login_set_context(my_dce_sec_context, &err);
- if (err != error_status_ok )
- {
- dce_error_inq_text(err, dce_errstr, &err2);
- DEBUG(0,("DCE login failed for principal %s, cant set context: %s\n",
- this_user,dce_errstr));
- sec_login_purge_context(my_dce_sec_context, &err);
- return(False);
- }
- else
- {
- DEBUG(0,("DCE login succeeded for principal %s on pid %d\n",
- this_user, getpid()));
- }
-
- dcelogin_atmost_once = 1;
- return (True);
-}
-
-void dfs_unlogin(void)
-{
- error_status_t err;
- int err2;
- unsigned char dce_errstr[dce_c_error_string_len];
-
- sec_login_purge_context(my_dce_sec_context, &err);
- if (err != error_status_ok )
- {
- dce_error_inq_text(err, dce_errstr, &err2);
- DEBUG(0,("DCE purge login context failed for server instance %d: %s\n",
- getpid(), dce_errstr));
- }
-}
-
-#endif
-
-#ifdef KRB5_AUTH
-/*******************************************************************
-check on Kerberos authentication
-********************************************************************/
-static BOOL krb5_auth(char *this_user,char *password)
-{
- krb5_data tgtname = {
- 0,
- KRB5_TGS_NAME_SIZE,
- KRB5_TGS_NAME
- };
- krb5_context kcontext;
- krb5_principal kprinc;
- krb5_principal server;
- krb5_creds kcreds;
- int options = 0;
- krb5_address **addrs = (krb5_address **)0;
- krb5_preauthtype *preauth = NULL;
- krb5_keytab keytab = NULL;
- krb5_timestamp now;
- krb5_ccache ccache = NULL;
- int retval;
- char *name;
-
- if ( retval=krb5_init_context(&kcontext))
- {
- return(False);
- }
-
- if ( retval = krb5_timeofday(kcontext, &now) )
- {
- return(False);
- }
-
- if ( retval = krb5_cc_default(kcontext, &ccache) )
- {
- return(False);
- }
-
- if ( retval = krb5_parse_name(kcontext, this_user, &kprinc) )
- {
- return(False);
- }
-
- memset((char *)&kcreds, 0, sizeof(kcreds));
-
- kcreds.client = kprinc;
-
- if ((retval = krb5_build_principal_ext(kcontext, &server,
- krb5_princ_realm(kcontext, kprinc)->length,
- krb5_princ_realm(kcontext, kprinc)->data,
- tgtname.length,
- tgtname.data,
- krb5_princ_realm(kcontext, kprinc)->length,
- krb5_princ_realm(kcontext, kprinc)->data,
- 0)))
- {
- return(False);
- }
-
- kcreds.server = server;
-
- retval = krb5_get_in_tkt_with_password(kcontext,
- options,
- addrs,
- NULL,
- preauth,
- password,
- 0,
- &kcreds,
- 0);
-
- if ( retval )
- {
- return(False);
- }
-
- return(True);
-}
-#endif /* KRB5_AUTH */
-
-#ifdef LINUX_BIGCRYPT
-/****************************************************************************
-an enhanced crypt for Linux to handle password longer than 8 characters
-****************************************************************************/
-static int linux_bigcrypt(char *password,char *salt1, char *crypted)
-{
-#define LINUX_PASSWORD_SEG_CHARS 8
- char salt[3];
- int i;
-
- StrnCpy(salt,salt1,2);
- crypted +=2;
-
- for ( i=strlen(password); i > 0; i -= LINUX_PASSWORD_SEG_CHARS) {
- char * p = crypt(password,salt) + 2;
- if(strncmp(p, crypted, LINUX_PASSWORD_SEG_CHARS) != 0)
- return(0);
- password += LINUX_PASSWORD_SEG_CHARS;
- crypted += strlen(p);
- }
-
- return(1);
-}
-#endif
-
-
-/****************************************************************************
-apply a function to upper/lower case combinations
-of a string and return true if one of them returns true.
-try all combinations with N uppercase letters.
-offset is the first char to try and change (start with 0)
-it assumes the string starts lowercased
-****************************************************************************/
-static BOOL string_combinations2(char *s,int offset,BOOL (*fn)(),int N)
-{
- int len = strlen(s);
- int i;
-
-#ifdef PASSWORD_LENGTH
- len = MIN(len,PASSWORD_LENGTH);
-#endif
-
- if (N <= 0 || offset >= len)
- return(fn(s));
-
- for (i=offset;i<(len-(N-1));i++)
- {
- char c = s[i];
- if (!islower(c)) continue;
- s[i] = toupper(c);
- if (string_combinations2(s,i+1,fn,N-1))
- return(True);
- s[i] = c;
- }
- return(False);
-}
-
-/****************************************************************************
-apply a function to upper/lower case combinations
-of a string and return true if one of them returns true.
-try all combinations with up to N uppercase letters.
-offset is the first char to try and change (start with 0)
-it assumes the string starts lowercased
-****************************************************************************/
-static BOOL string_combinations(char *s,BOOL (*fn)(),int N)
-{
- int n;
- for (n=1;n<=N;n++)
- if (string_combinations2(s,0,fn,n)) return(True);
- return(False);
-}
-
-
-
-/****************************************************************************
-core of password checking routine
-****************************************************************************/
-BOOL password_check(char *password)
-{
-
-#ifdef USE_PAM
-/* This falls through if the password check fails
- - if NO_CRYPT is defined this causes an error msg
- saying Warning - no crypt available
- - if NO_CRYPT is NOT defined this is a potential security hole
- as it may authenticate via the crypt call when PAM
- settings say it should fail.
- if (pam_auth(this_user,password)) return(True);
-Hence we make a direct return to avoid a second chance!!!
-*/
- return (pam_auth(this_user,password));
-#endif
-
-#ifdef AFS_AUTH
- if (afs_auth(this_user,password)) return(True);
-#endif
-
-#ifdef DFS_AUTH
- if (dfs_auth(this_user,password)) return(True);
-#endif
-
-#ifdef KRB5_AUTH
- if (krb5_auth(this_user,password)) return(True);
-#endif
-
-#ifdef PWDAUTH
- if (pwdauth(this_user,password) == 0)
- return(True);
-#endif
-
-#ifdef OSF1_ENH_SEC
- return(strcmp(osf1_bigcrypt(password,this_salt),this_crypted) == 0);
-#endif
-
-#ifdef ULTRIX_AUTH
- return (strcmp((char *)crypt16(password, this_salt ),this_crypted) == 0);
-#endif
-
-#ifdef LINUX_BIGCRYPT
- return(linux_bigcrypt(password,this_salt,this_crypted));
-#endif
-
-#ifdef NO_CRYPT
- DEBUG(1,("Warning - no crypt available\n"));
- return(False);
-#else
- return(strcmp((char *)crypt(password,this_salt),this_crypted) == 0);
-#endif
-}
-
-/****************************************************************************
-core of smb password checking routine.
-****************************************************************************/
-BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8)
-{
- /* Finish the encryption of part_passwd. */
- unsigned char p21[21];
- unsigned char p24[24];
-
- if(part_passwd == NULL)
- DEBUG(10,("No password set - allowing access\n"));
- /* No password set - always true ! */
- if(part_passwd == NULL)
- return 1;
-
- memset(p21,'\0',21);
- memcpy(p21,part_passwd,16);
- E_P24(p21, c8, p24);
-#if DEBUG_PASSWORD
- {
- int i;
- DEBUG(100,("Part password (P16) was |"));
- for(i = 0; i < 16; i++)
- DEBUG(100,("%X ", (unsigned char)part_passwd[i]));
- DEBUG(100,("|\n"));
- DEBUG(100,("Password from client was |"));
- for(i = 0; i < 24; i++)
- DEBUG(100,("%X ", (unsigned char)password[i]));
- DEBUG(100,("|\n"));
- DEBUG(100,("Given challenge was |"));
- for(i = 0; i < 8; i++)
- DEBUG(100,("%X ", (unsigned char)c8[i]));
- DEBUG(100,("|\n"));
- DEBUG(100,("Value from encryption was |"));
- for(i = 0; i < 24; i++)
- DEBUG(100,("%X ", (unsigned char)p24[i]));
- DEBUG(100,("|\n"));
- }
-#endif
- return (memcmp(p24, password, 24) == 0);
-}
-
-/****************************************************************************
-check if a username/password is OK
-****************************************************************************/
-BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd)
-{
- pstring pass2;
- int level = lp_passwordlevel();
- struct passwd *pass;
- char challenge[8];
- struct smb_passwd *smb_pass;
- BOOL challenge_done = False;
-
- if (password) password[pwlen] = 0;
-
- if (pwlen == 24)
- challenge_done = last_challenge(challenge);
-
-#if DEBUG_PASSWORD
- if (challenge_done)
- {
- int i;
- DEBUG(100,("checking user=[%s] pass=[",user));
- for( i = 0; i < 24; i++)
- DEBUG(100,("%0x ", (unsigned char)password[i]));
- DEBUG(100,("]\n"));
- } else {
- DEBUG(100,("checking user=[%s] pass=[%s]\n",user,password));
- }
-#endif
-
- if (!password)
- return(False);
-
- if (((!*password) || (!pwlen)) && !lp_null_passwords())
- return(False);
-
- if (pwd && !user)
- {
- pass = (struct passwd *) pwd;
- user = pass->pw_name;
- }
- else
- pass = Get_Pwnam(user,True);
-
- DEBUG(4,("SMB Password - pwlen = %d, challenge_done = %d\n", pwlen, challenge_done));
-
- if((pwlen == 24) && challenge_done)
- {
- DEBUG(4,("Checking SMB password for user %s (l=24)\n",user));
-
- if (!pass)
- {
- DEBUG(3,("Couldn't find user %s\n",user));
- return(False);
- }
-
- smb_pass = get_smbpwnam(user);
- if(!smb_pass)
- {
- DEBUG(3,("Couldn't find user %s in smb_passwd file.\n", user));
- return(False);
- }
-
- /* Ensure the uid's match */
- if(smb_pass->smb_userid != pass->pw_uid)
- {
- DEBUG(3,("Error : UNIX and SMB uids in password files do not match !\n"));
- return(False);
- }
-
- if(Protocol >= PROTOCOL_NT1)
- {
- /* We have the NT MD4 hash challenge available - see if we can
- use it (ie. does it exist in the smbpasswd file).
- */
- if(smb_pass->smb_nt_passwd != NULL)
- {
- DEBUG(4,("Checking NT MD4 password\n"));
- if(smb_password_check(password,
- smb_pass->smb_nt_passwd,
- (unsigned char *)challenge))
- {
- update_protected_database(user,True);
- return(True);
- }
- DEBUG(4,("NT MD4 password check failed\n"));
- }
- }
-
- /* Try against the lanman password */
-
- if (smb_password_check(password,
- smb_pass->smb_passwd,
- (unsigned char *)challenge)) {
- update_protected_database(user,True);
- return(True);
- }
-
- DEBUG(3,("Error smb_password_check failed\n"));
- }
-
- DEBUG(4,("Checking password for user %s (l=%d)\n",user,pwlen));
-
- if (!pass)
- {
- DEBUG(3,("Couldn't find user %s\n",user));
- return(False);
- }
-
-#ifdef SHADOW_PWD
- {
- struct spwd *spass;
-
- /* many shadow systems require you to be root to get the password,
- in most cases this should already be the case when this
- function is called, except perhaps for IPC password changing
- requests */
-
- spass = getspnam(pass->pw_name);
- if (spass && spass->sp_pwdp)
- pass->pw_passwd = spass->sp_pwdp;
- }
-#elif defined(IA_UINFO)
- {
- /* Need to get password with SVR4.2's ia_ functions instead of
- get{sp,pw}ent functions. Required by UnixWare 2.x, tested on
- version 2.1. (tangent@cyberport.com) */
- uinfo_t uinfo;
- if (ia_openinfo(pass->pw_name, &uinfo) != -1)
- ia_get_logpwd(uinfo, &(pass->pw_passwd));
- }
-#endif
-
-#ifdef SecureWare
- {
- struct pr_passwd *pr_pw = getprpwnam(pass->pw_name);
- if (pr_pw && pr_pw->ufld.fd_encrypt)
- pass->pw_passwd = pr_pw->ufld.fd_encrypt;
- }
-#endif
-
-#ifdef HPUX_10_TRUSTED
- {
- struct pr_passwd *pr_pw = getprpwnam(pass->pw_name);
- if (pr_pw && pr_pw->ufld.fd_encrypt)
- pass->pw_passwd = pr_pw->ufld.fd_encrypt;
- }
-#endif
-
-#ifdef OSF1_ENH_SEC
- {
- struct pr_passwd *mypasswd;
- DEBUG(5,("Checking password for user %s in OSF1_ENH_SEC\n",user));
- mypasswd = getprpwnam (user);
- if ( mypasswd )
- {
- strcpy(pass->pw_name,mypasswd->ufld.fd_name);
- strcpy(pass->pw_passwd,mypasswd->ufld.fd_encrypt);
- }
- else
- {
- DEBUG(5,("No entry for user %s in protected database !\n",user));
- return(False);
- }
- }
-#endif
-
-#ifdef ULTRIX_AUTH
- {
- AUTHORIZATION *ap = getauthuid( pass->pw_uid );
- if (ap)
- {
- strcpy( pass->pw_passwd, ap->a_password );
- endauthent();
- }
- }
-#endif
-
- /* extract relevant info */
- strcpy(this_user,pass->pw_name);
- strcpy(this_salt,pass->pw_passwd);
- strcpy(this_crypted,pass->pw_passwd);
-
- if (!*this_crypted) {
- if (!lp_null_passwords()) {
- DEBUG(2,("Disallowing access to %s due to null password\n",this_user));
- return(False);
- }
-#ifndef PWDAUTH
- if (!*password) {
- DEBUG(3,("Allowing access to %s with null password\n",this_user));
- return(True);
- }
-#endif
- }
-
- /* try it as it came to us */
- if (password_check(password))
- {
- update_protected_database(user,True);
- return(True);
- }
-
- /* if the password was given to us with mixed case then we don't
- need to proceed as we know it hasn't been case modified by the
- client */
- if (strhasupper(password) && strhaslower(password))
- return(False);
-
- /* make a copy of it */
- StrnCpy(pass2,password,sizeof(pstring)-1);
-
- /* try all lowercase */
- strlower(password);
- if (password_check(password))
- {
- update_protected_database(user,True);
- return(True);
- }
-
- /* give up? */
- if(level < 1)
- {
- update_protected_database(user,False);
-
- /* restore it */
- strcpy(password,pass2);
-
- return(False);
- }
-
- /* last chance - all combinations of up to level chars upper! */
- strlower(password);
-
- if (string_combinations(password,password_check,level))
- {
- update_protected_database(user,True);
- return(True);
- }
-
- update_protected_database(user,False);
-
- /* restore it */
- strcpy(password,pass2);
-
- return(False);
-}
-
-
-
-/****************************************************************************
-check if a username is valid
-****************************************************************************/
-BOOL user_ok(char *user,int snum)
-{
- pstring valid, invalid;
- BOOL ret;
-
- StrnCpy(valid, lp_valid_users(snum), sizeof(pstring));
- StrnCpy(invalid, lp_invalid_users(snum), sizeof(pstring));
-
- string_sub(valid,"%S",lp_servicename(snum));
- string_sub(invalid,"%S",lp_servicename(snum));
-
- ret = !user_in_list(user,invalid);
-
- if (ret && valid && *valid)
- ret = user_in_list(user,valid);
-
- if (ret && lp_onlyuser(snum)) {
- char *user_list = lp_username(snum);
- string_sub(user_list,"%S",lp_servicename(snum));
- ret = user_in_list(user,user_list);
- }
-
- return(ret);
-}
-
-
-
-
-/****************************************************************************
-validate a group username entry. Return the username or NULL
-****************************************************************************/
-static char *validate_group(char *group,char *password,int pwlen,int snum)
-{
-#ifdef NETGROUP
- {
- char *host, *user, *domain;
- setnetgrent(group);
- while (getnetgrent(&host, &user, &domain)) {
- if (user) {
- if (user_ok(user, snum) &&
- password_ok(user,password,pwlen,NULL)) {
- endnetgrent();
- return(user);
- }
- }
- }
- endnetgrent();
- }
-#endif
-
-#if HAVE_GETGRNAM
- {
- struct group *gptr = (struct group *)getgrnam(group);
- char **member;
- if (gptr)
- {
- member = gptr->gr_mem;
- while (member && *member)
- {
- static fstring name;
- strcpy(name,*member);
- if (user_ok(name,snum) &&
- password_ok(name,password,pwlen,NULL))
- return(&name[0]);
- member++;
- }
-#ifdef GROUP_CHECK_PWENT
- {
- struct passwd *pwd;
- static fstring tm;
-
- setpwent ();
- while (pwd = getpwent ()) {
- if (*(pwd->pw_passwd) && pwd->pw_gid == gptr->gr_gid) {
- /* This Entry have PASSWORD and same GID then check pwd */
- if (password_ok(NULL, password, pwlen, pwd)) {
- strcpy(tm, pwd->pw_name);
- endpwent ();
- return tm;
- }
- }
- }
- endpwent ();
- }
-#endif /* GROUP_CHECK_PWENT */
- }
- }
-#endif
- return(NULL);
-}
-
-
-
-/****************************************************************************
-check for authority to login to a service with a given username/password
-****************************************************************************/
-BOOL authorise_login(int snum,char *user,char *password, int pwlen,
- BOOL *guest,BOOL *force,uint16 vuid)
-{
- BOOL ok = False;
-
- *guest = False;
-
-#if DEBUG_PASSWORD
- DEBUG(100,("checking authorisation on user=%s pass=%s\n",user,password));
-#endif
-
- /* there are several possibilities:
- 1) login as the given user with given password
- 2) login as a previously registered username with the given password
- 3) login as a session list username with the given password
- 4) login as a previously validated user/password pair
- 5) login as the "user =" user with given password
- 6) login as the "user =" user with no password (guest connection)
- 7) login as guest user with no password
-
- if the service is guest_only then steps 1 to 5 are skipped
- */
-
- if (GUEST_ONLY(snum)) *force = True;
-
- if (!(GUEST_ONLY(snum) && GUEST_OK(snum)))
- {
-
- user_struct *vuser = get_valid_user_struct(vuid);
-
- /* check the given username and password */
- if (!ok && (*user) && user_ok(user,snum)) {
- ok = password_ok(user,password, pwlen, NULL);
- if (ok) DEBUG(3,("ACCEPTED: given username password ok\n"));
- }
-
- /* check for a previously registered guest username */
- if (!ok && (vuser != 0) && vuser->guest) {
- if (user_ok(vuser->name,snum) &&
- password_ok(vuser->name, password, pwlen, NULL)) {
- strcpy(user, vuser->name);
- vuser->guest = False;
- DEBUG(3,("ACCEPTED: given password with registered user %s\n", user));
- ok = True;
- }
- }
-
-
- /* now check the list of session users */
- if (!ok)
- {
- char *auser;
- char *user_list = strdup(session_users);
- if (!user_list) return(False);
-
- for (auser=strtok(user_list,LIST_SEP);
- !ok && auser;
- auser = strtok(NULL,LIST_SEP))
- {
- fstring user2;
- strcpy(user2,auser);
- if (!user_ok(user2,snum)) continue;
-
- if (password_ok(user2,password, pwlen, NULL)) {
- ok = True;
- strcpy(user,user2);
- DEBUG(3,("ACCEPTED: session list username and given password ok\n"));
- }
- }
- free(user_list);
- }
-
- /* check for a previously validated username/password pair */
- if (!ok && !lp_revalidate(snum) &&
- (vuser != 0) && !vuser->guest &&
- user_ok(vuser->name,snum)) {
- strcpy(user,vuser->name);
- *guest = False;
- DEBUG(3,("ACCEPTED: validated uid ok as non-guest\n"));
- ok = True;
- }
-
- /* check for a rhosts entry */
- if (!ok && user_ok(user,snum) && check_hosts_equiv(user)) {
- ok = True;
- DEBUG(3,("ACCEPTED: hosts equiv or rhosts entry\n"));
- }
-
- /* check the user= fields and the given password */
- if (!ok && lp_username(snum)) {
- char *auser;
- pstring user_list;
- StrnCpy(user_list,lp_username(snum),sizeof(pstring));
-
- string_sub(user_list,"%S",lp_servicename(snum));
-
- for (auser=strtok(user_list,LIST_SEP);
- auser && !ok;
- auser = strtok(NULL,LIST_SEP))
- {
- if (*auser == '@')
- {
- auser = validate_group(auser+1,password,pwlen,snum);
- if (auser)
- {
- ok = True;
- strcpy(user,auser);
- DEBUG(3,("ACCEPTED: group username and given password ok\n"));
- }
- }
- else
- {
- fstring user2;
- strcpy(user2,auser);
- if (user_ok(user2,snum) &&
- password_ok(user2,password,pwlen,NULL))
- {
- ok = True;
- strcpy(user,user2);
- DEBUG(3,("ACCEPTED: user list username and given password ok\n"));
- }
- }
- }
- }
- } /* not guest only */
-
- /* check for a normal guest connection */
- if (!ok && GUEST_OK(snum))
- {
- fstring guestname;
- StrnCpy(guestname,lp_guestaccount(snum),sizeof(guestname)-1);
- if (Get_Pwnam(guestname,True))
- {
- strcpy(user,guestname);
- ok = True;
- DEBUG(3,("ACCEPTED: guest account and guest ok\n"));
- }
- else
- DEBUG(0,("Invalid guest account %s??\n",guestname));
- *guest = True;
- *force = True;
- }
-
- if (ok && !user_ok(user,snum))
- {
- DEBUG(0,("rejected invalid user %s\n",user));
- ok = False;
- }
-
- return(ok);
-}
-
-
-/****************************************************************************
-read the a hosts.equiv or .rhosts file and check if it
-allows this user from this machine
-****************************************************************************/
-static BOOL check_user_equiv(char *user, char *remote, char *equiv_file)
-{
- pstring buf;
- int plus_allowed = 1;
- char *file_host;
- char *file_user;
- FILE *fp = fopen(equiv_file, "r");
- DEBUG(5, ("check_user_equiv %s %s %s\n", user, remote, equiv_file));
- if (! fp) return False;
- while(fgets(buf, sizeof(buf), fp))
- {
- trim_string(buf," "," ");
-
- if (buf[0] != '#' && buf[0] != '\n')
- {
- BOOL is_group = False;
- int plus = 1;
- char *bp = buf;
- if (strcmp(buf, "NO_PLUS\n") == 0)
- {
- DEBUG(6, ("check_user_equiv NO_PLUS\n"));
- plus_allowed = 0;
- }
- else {
- if (buf[0] == '+')
- {
- bp++;
- if (*bp == '\n' && plus_allowed)
- {
- /* a bare plus means everbody allowed */
- DEBUG(6, ("check_user_equiv everybody allowed\n"));
- fclose(fp);
- return True;
- }
- }
- else if (buf[0] == '-')
- {
- bp++;
- plus = 0;
- }
- if (*bp == '@')
- {
- is_group = True;
- bp++;
- }
- file_host = strtok(bp, " \t\n");
- file_user = strtok(NULL, " \t\n");
- DEBUG(7, ("check_user_equiv %s %s\n", file_host ? file_host : "(null)",
- file_user ? file_user : "(null)" ));
- if (file_host && *file_host)
- {
- BOOL host_ok = False;
-
-#ifdef NETGROUP
- if (is_group)
- {
- static char *mydomain = NULL;
- if (!mydomain)
- yp_get_default_domain(&mydomain);
- if (mydomain && innetgr(file_host,remote,user,mydomain))
- host_ok = True;
- }
-#else
- if (is_group)
- {
- DEBUG(1,("Netgroups not configured - add -DNETGROUP and recompile\n"));
- continue;
- }
-#endif
-
- /* is it this host */
- /* the fact that remote has come from a call of gethostbyaddr
- * means that it may have the fully qualified domain name
- * so we could look up the file version to get it into
- * a canonical form, but I would rather just type it
- * in full in the equiv file
- */
- if (!host_ok && !is_group && strequal(remote, file_host))
- host_ok = True;
-
- if (!host_ok)
- continue;
-
- /* is it this user */
- if (file_user == 0 || strequal(user, file_user))
- {
- fclose(fp);
- DEBUG(5, ("check_user_equiv matched %s%s %s\n",
- (plus ? "+" : "-"), file_host,
- (file_user ? file_user : "")));
- return (plus ? True : False);
- }
- }
- }
- }
- }
- fclose(fp);
- return False;
-}
-
-
-/****************************************************************************
-check for a possible hosts equiv or rhosts entry for the user
-****************************************************************************/
-BOOL check_hosts_equiv(char *user)
-{
- char *fname = NULL;
- pstring rhostsfile;
- struct passwd *pass = Get_Pwnam(user,True);
-
- if (!pass)
- return(False);
-
- fname = lp_hosts_equiv();
-
- /* note: don't allow hosts.equiv on root */
- if (fname && *fname && (pass->pw_uid != 0))
- {
- if (check_user_equiv(user,client_name(),fname))
- return(True);
- }
-
- if (lp_use_rhosts())
- {
- char *home = get_home_dir(user);
- if (home)
- {
- sprintf(rhostsfile, "%s/.rhosts", home);
- if (check_user_equiv(user,client_name(),rhostsfile))
- return(True);
- }
- }
-
- return(False);
-}
-
-
-int password_client = -1;
-static fstring pserver;
-static char *secserver_inbuf = NULL;
-
-/****************************************************************************
-attempted support for server level security
-****************************************************************************/
-BOOL server_cryptkey(char *buf)
-{
- pstring outbuf;
- fstring pass_protocol;
- extern fstring remote_machine;
- char *p;
- int len;
- fstring desthost;
- struct in_addr dest_ip;
- int port = SMB_PORT;
- BOOL ret;
-
- if(secserver_inbuf == NULL) {
- secserver_inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- if(secserver_inbuf == NULL) {
- DEBUG(0,("server_cryptkey: malloc fail for input buffer.\n"));
- return False;
- }
- }
-
- if (password_client >= 0)
- close(password_client);
- password_client = -1;
-
- if (Protocol < PROTOCOL_NT1) {
- strcpy(pass_protocol,"LM1.2X002");
- } else {
- strcpy(pass_protocol,"NT LM 0.12");
- }
-
- bzero(secserver_inbuf,BUFFER_SIZE + SAFETY_MARGIN);
- bzero(outbuf,sizeof(outbuf));
-
- for (p=strtok(lp_passwordserver(),LIST_SEP); p ; p = strtok(NULL,LIST_SEP)) {
- strcpy(desthost,p);
- standard_sub_basic(desthost);
- strupper(desthost);
-
- dest_ip = *interpret_addr2(desthost);
- if (zero_ip(dest_ip)) {
- DEBUG(1,("Can't resolve address for %s\n",p));
- continue;
- }
-
- if (ismyip(dest_ip)) {
- DEBUG(1,("Password server loop - disabling password server %s\n",p));
- continue;
- }
-
- password_client = open_socket_out(SOCK_STREAM, &dest_ip, port, SHORT_CONNECT_TIMEOUT);
- if (password_client >= 0) {
- DEBUG(3,("connected to password server %s\n",p));
- StrnCpy(pserver,p,sizeof(pserver)-1);
- break;
- }
- }
-
- if (password_client < 0) {
- DEBUG(1,("password server not available\n"));
- return(False);
- }
-
-
- /* send a session request (RFC 8002) */
-
- /* put in the destination name */
- len = 4;
- p = outbuf+len;
- name_mangle(desthost,p,' ');
- len += name_len(p);
- p = outbuf+len;
-
- /* and my name */
- /* Fix from Frank Varnavas <varnavas@ny.ubs.com>.
- We cannot use the same name as the client to
- the NT password server, as NT will drop client
- connections if the same client name connects
- twice. Instead, synthesize a name from our pid.
- and the remote machine name.
- */
- {
- char buf2[32]; /* create name as PIDname */
- sprintf(buf2,"%d", getpid());
- strncpy(&buf2[strlen(buf2)], remote_machine, 31 - strlen(buf2));
- buf2[31] = '\0';
- DEBUG(1,("negprot w/password server as %s\n",buf2));
- name_mangle(buf2,p,' ');
- len += name_len(p);
- }
-
- _smb_setlen(outbuf,len);
- CVAL(outbuf,0) = 0x81;
-
- send_smb(password_client,outbuf);
-
-
- if (!receive_smb(password_client,secserver_inbuf,5000) ||
- CVAL(secserver_inbuf,0) != 0x82) {
- DEBUG(1,("%s rejected the session\n",pserver));
- close(password_client); password_client = -1;
- return(False);
- }
-
- DEBUG(3,("got session\n"));
-
- bzero(outbuf,smb_size);
-
- /* setup the protocol string */
- set_message(outbuf,0,strlen(pass_protocol)+2,True);
- p = smb_buf(outbuf);
- *p++ = 2;
- strcpy(p,pass_protocol);
-
- CVAL(outbuf,smb_com) = SMBnegprot;
- CVAL(outbuf,smb_flg) = 0x8;
- SSVAL(outbuf,smb_flg2,0x1);
-
- send_smb(password_client,outbuf);
- ret = receive_smb(password_client,secserver_inbuf,5000);
-
- if (!ret || CVAL(secserver_inbuf,smb_rcls) || SVAL(secserver_inbuf,smb_vwv0)) {
- DEBUG(1,("%s rejected the protocol\n",pserver));
- close(password_client); password_client= -1;
- return(False);
- }
-
- if (!(CVAL(secserver_inbuf,smb_vwv1) & 1)) {
- DEBUG(1,("%s isn't in user level security mode\n",pserver));
- close(password_client); password_client= -1;
- return(False);
- }
-
- memcpy(buf,secserver_inbuf,smb_len(secserver_inbuf)+4);
-
- DEBUG(3,("password server OK\n"));
-
- return(True);
-}
-
-/****************************************************************************
-attempted support for server level security
-****************************************************************************/
-BOOL server_validate(char *buf)
-{
- pstring outbuf;
- BOOL ret;
-
- if(secserver_inbuf == NULL) {
- secserver_inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- if(secserver_inbuf == NULL) {
- DEBUG(0,("server_validate: malloc fail for input buffer.\n"));
- return False;
- }
- }
-
- if (password_client < 0) {
- DEBUG(1,("%s not connected\n",pserver));
- return(False);
- }
-
- bzero(secserver_inbuf,BUFFER_SIZE + SAFETY_MARGIN);
- memcpy(outbuf,buf,sizeof(outbuf));
-
- /* send a session setup command */
- CVAL(outbuf,smb_flg) = 0x8;
- SSVAL(outbuf,smb_flg2,0x1);
- CVAL(outbuf,smb_vwv0) = 0xFF;
-
- set_message(outbuf,smb_numwords(outbuf),smb_buflen(outbuf),False);
-
- SCVAL(secserver_inbuf,smb_rcls,1);
-
- send_smb(password_client,outbuf);
- ret = receive_smb(password_client,secserver_inbuf,5000);
-
- if (!ret || CVAL(secserver_inbuf,smb_rcls) != 0) {
- DEBUG(1,("password server %s rejected the password\n",pserver));
- return(False);
- }
-
- /* if logged in as guest then reject */
- if ((SVAL(secserver_inbuf,smb_vwv2) & 1) != 0) {
- DEBUG(1,("password server %s gave us guest only\n",pserver));
- return(False);
- }
-
- DEBUG(3,("password server %s accepted the password\n",pserver));
-
-#if !KEEP_PASSWORD_SERVER_OPEN
- close(password_client); password_client= -1;
-#endif
-
- return(True);
-}
-
-
diff --git a/source/smbd/pipes.c b/source/smbd/pipes.c
deleted file mode 100644
index 6937412e29f..00000000000
--- a/source/smbd/pipes.c
+++ /dev/null
@@ -1,1196 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Pipe SMB reply routines
- Copyright (C) Andrew Tridgell 1992-1997,
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997.
- Copyright (C) Paul Ashton 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.
-*/
-/*
- This file handles reply_ calls on named pipes that the server
- makes to handle specific protocols
-*/
-
-
-#include "includes.h"
-#include "trans2.h"
-#include "nterr.h"
-
-#define PIPE "\\PIPE\\"
-#define PIPELEN strlen(PIPE)
-
-#define REALLOC(ptr,size) Realloc(ptr,MAX((size),4*1024))
-
-/* look in server.c for some explanation of these variables */
-extern int Protocol;
-extern int DEBUGLEVEL;
-extern int chain_fnum;
-extern char magic_char;
-extern connection_struct Connections[];
-extern files_struct Files[];
-extern BOOL case_sensitive;
-extern pstring sesssetup_user;
-extern int Client;
-extern fstring myworkgroup;
-
-/* this macro should always be used to extract an fnum (smb_fid) from
-a packet to ensure chaining works correctly */
-#define GETFNUM(buf,where) (chain_fnum!= -1?chain_fnum:SVAL(buf,where))
-
-char * known_pipes [] =
-{
- "lsarpc",
-#if NTDOMAIN
- "NETLOGON",
-#endif
- NULL
-};
-
-/****************************************************************************
- reply to an open and X on a named pipe
-
- In fact what we do is to open a regular file with the same name in
- /tmp. This can then be closed as normal. Reading and writing won't
- make much sense, but will do *something*. The real reason for this
- support is to be able to do transactions on them (well, on lsarpc
- for domain login purposes...).
-
- This code is basically stolen from reply_open_and_X with some
- wrinkles to handle pipes.
-****************************************************************************/
-int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
-{
- pstring fname;
- int cnum = SVAL(inbuf,smb_tid);
- int fnum = -1;
- int smb_mode = SVAL(inbuf,smb_vwv3);
- int smb_attr = SVAL(inbuf,smb_vwv5);
-#if 0
- int open_flags = SVAL(inbuf,smb_vwv2);
- int smb_sattr = SVAL(inbuf,smb_vwv4);
- uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
-#endif
- int smb_ofun = SVAL(inbuf,smb_vwv8);
- int unixmode;
- int size=0,fmode=0,mtime=0,rmode=0;
- struct stat sbuf;
- int smb_action = 0;
- int i;
- BOOL bad_path = False;
-
- /* XXXX we need to handle passed times, sattr and flags */
- pstrcpy(fname,smb_buf(inbuf));
-
- /* If the name doesn't start \PIPE\ then this is directed */
- /* at a mailslot or something we really, really don't understand, */
- /* not just something we really don't understand. */
- if ( strncmp(fname,PIPE,PIPELEN) != 0 )
- return(ERROR(ERRSRV,ERRaccess));
-
- DEBUG(4,("Opening pipe %s.\n", fname));
-
- /* Strip \PIPE\ off the name. */
- pstrcpy(fname,smb_buf(inbuf) + PIPELEN);
-
- /* See if it is one we want to handle. */
- for( i = 0; known_pipes[i] ; i++ )
- if( strcmp(fname,known_pipes[i]) == 0 )
- break;
-
- if ( known_pipes[i] == NULL )
- return(ERROR(ERRSRV,ERRaccess));
-
- /* Known pipes arrive with DIR attribs. Remove it so a regular file */
- /* can be opened and add it in after the open. */
- DEBUG(3,("Known pipe %s opening.\n",fname));
- smb_attr &= ~aDIR;
- Connections[cnum].read_only = 0;
- smb_ofun |= 0x10; /* Add Create it not exists flag */
-
- unix_convert(fname,cnum,0,&bad_path);
-
- fnum = find_free_file();
- if (fnum < 0)
- return(ERROR(ERRSRV,ERRnofids));
-
- if (!check_name(fname,cnum))
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- unixmode = unix_mode(cnum,smb_attr);
-
- open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode,
- 0, &rmode,&smb_action);
-
- if (!Files[fnum].open)
- {
- /* Change the error code if bad_path was set. */
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
- close_file(fnum);
- return(ERROR(ERRDOS,ERRnoaccess));
- }
-
- size = sbuf.st_size;
- fmode = dos_mode(cnum,fname,&sbuf);
- mtime = sbuf.st_mtime;
- if (fmode & aDIR) {
- close_file(fnum);
- return(ERROR(ERRDOS,ERRnoaccess));
- }
-
- /* Prepare the reply */
- set_message(outbuf,15,0,True);
-
- /* Put things back the way they were. */
- Connections[cnum].read_only = 1;
-
- /* Mark the opened file as an existing named pipe in message mode. */
- SSVAL(outbuf,smb_vwv9,2);
- SSVAL(outbuf,smb_vwv10,0xc700);
- if (rmode == 2)
- {
- DEBUG(4,("Resetting open result to open from create.\n"));
- rmode = 1;
- }
-
- SSVAL(outbuf,smb_vwv2,fnum);
- SSVAL(outbuf,smb_vwv3,fmode);
- put_dos_date3(outbuf,smb_vwv4,mtime);
- SIVAL(outbuf,smb_vwv6,size);
- SSVAL(outbuf,smb_vwv8,rmode);
- SSVAL(outbuf,smb_vwv11,smb_action);
-
- chain_fnum = fnum;
-
- DEBUG(4,("Opened pipe %s with handle %d, saved name %s.\n",
- fname, fnum, Files[fnum].name));
-
- return chain_reply(inbuf,outbuf,length,bufsize);
-}
-
-
-/****************************************************************************
- api_LsarpcSNPHS
-
- SetNamedPipeHandleState on \PIPE\lsarpc. We can't really do much here,
- so just blithely return True. This is really only for NT domain stuff,
- we we're only handling that - don't assume Samba now does complete
- named pipe handling.
-****************************************************************************/
-BOOL api_LsarpcSNPHS(int cnum,int uid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- uint16 id;
-
- id = param[0] + (param[1] << 8);
- DEBUG(4,("lsarpc SetNamedPipeHandleState to code %x\n",id));
- return(True);
-}
-
-
-/****************************************************************************
- api_LsarpcTNP
-
- TransactNamedPipe on \PIPE\lsarpc.
-****************************************************************************/
-static void LsarpcTNP1(char *data,char **rdata, int *rdata_len)
-{
- uint32 dword1, dword2;
- char pname[] = "\\PIPE\\lsass";
-
- /* All kinds of mysterious numbers here */
- *rdata_len = 68;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- dword1 = IVAL(data,0xC);
- dword2 = IVAL(data,0x10);
-
- SIVAL(*rdata,0,0xc0005);
- SIVAL(*rdata,4,0x10);
- SIVAL(*rdata,8,0x44);
- SIVAL(*rdata,0xC,dword1);
-
- SIVAL(*rdata,0x10,dword2);
- SIVAL(*rdata,0x14,0x15);
- SSVAL(*rdata,0x18,sizeof(pname));
- strcpy(*rdata + 0x1a,pname);
- SIVAL(*rdata,0x28,1);
- memcpy(*rdata + 0x30, data + 0x34, 0x14);
-}
-
-static void LsarpcTNP2(char *data,char **rdata, int *rdata_len)
-{
- uint32 dword1;
-
- /* All kinds of mysterious numbers here */
- *rdata_len = 48;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- dword1 = IVAL(data,0xC);
-
- SIVAL(*rdata,0,0x03020005);
- SIVAL(*rdata,4,0x10);
- SIVAL(*rdata,8,0x30);
- SIVAL(*rdata,0xC,dword1);
- SIVAL(*rdata,0x10,0x18);
- SIVAL(*rdata,0x1c,0x44332211);
- SIVAL(*rdata,0x20,0x88776655);
- SIVAL(*rdata,0x24,0xCCBBAA99);
- SIVAL(*rdata,0x28,0x11FFEEDD);
-}
-
-static void LsarpcTNP3(char *data,char **rdata, int *rdata_len)
-{
- uint32 dword1;
- uint16 word1;
- char * workgroup = myworkgroup;
- int wglen = strlen(workgroup);
- int i;
-
- /* All kinds of mysterious numbers here */
- *rdata_len = 90 + 2 * wglen;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- dword1 = IVAL(data,0xC);
- word1 = SVAL(data,0x2C);
-
- SIVAL(*rdata,0,0x03020005);
- SIVAL(*rdata,4,0x10);
- SIVAL(*rdata,8,0x60);
- SIVAL(*rdata,0xC,dword1);
- SIVAL(*rdata,0x10,0x48);
- SSVAL(*rdata,0x18,0x5988); /* This changes */
- SSVAL(*rdata,0x1A,0x15);
- SSVAL(*rdata,0x1C,word1);
- SSVAL(*rdata,0x20,6);
- SSVAL(*rdata,0x22,8);
- SSVAL(*rdata,0x24,0x8E8); /* So does this */
- SSVAL(*rdata,0x26,0x15);
- SSVAL(*rdata,0x28,0x4D48); /* And this */
- SSVAL(*rdata,0x2A,0x15);
- SIVAL(*rdata,0x2C,4);
- SIVAL(*rdata,0x34,wglen);
- for ( i = 0 ; i < wglen ; i++ )
- (*rdata)[0x38 + i * 2] = workgroup[i];
-
- /* Now fill in the rest */
- i = 0x38 + wglen * 2;
- SSVAL(*rdata,i,0x648);
- SIVAL(*rdata,i+2,4);
- SIVAL(*rdata,i+6,0x401);
- SSVAL(*rdata,i+0xC,0x500);
- SIVAL(*rdata,i+0xE,0x15);
- SIVAL(*rdata,i+0x12,0x2372FE1);
- SIVAL(*rdata,i+0x16,0x7E831BEF);
- SIVAL(*rdata,i+0x1A,0x4B454B2);
-}
-
-static void LsarpcTNP4(char *data,char **rdata, int *rdata_len)
-{
- uint32 dword1;
-
- /* All kinds of mysterious numbers here */
- *rdata_len = 48;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- dword1 = IVAL(data,0xC);
-
- SIVAL(*rdata,0,0x03020005);
- SIVAL(*rdata,4,0x10);
- SIVAL(*rdata,8,0x30);
- SIVAL(*rdata,0xC,dword1);
- SIVAL(*rdata,0x10,0x18);
-}
-
-
-BOOL api_LsarpcTNP(int cnum,int uid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- uint32 id,id2;
-
- id = IVAL(data,0);
-
- DEBUG(4,("lsarpc TransactNamedPipe id %lx\n",id));
- switch (id)
- {
- case 0xb0005:
- LsarpcTNP1(data,rdata,rdata_len);
- break;
-
- case 0x03000005:
- id2 = IVAL(data,8);
- DEBUG(4,("\t- Suboperation %lx\n",id2));
- switch (id2 & 0xF)
- {
- case 8:
- LsarpcTNP2(data,rdata,rdata_len);
- break;
-
- case 0xC:
- LsarpcTNP4(data,rdata,rdata_len);
- break;
-
- case 0xE:
- LsarpcTNP3(data,rdata,rdata_len);
- break;
- }
- break;
- }
- return(True);
-}
-
-
-#ifdef NTDOMAIN
-/*
- PAXX: Someone fix above.
- The above API is indexing RPC calls based on RPC flags and
- fragment length. I've decided to do it based on operation number :-)
-*/
-
-/* this function is due to be replaced */
-static void initrpcreply(char *inbuf, char *q)
-{
- uint32 callid;
-
- SCVAL(q, 0, 5); q++; /* RPC version 5 */
- SCVAL(q, 0, 0); q++; /* minor version 0 */
- SCVAL(q, 0, 2); q++; /* RPC response packet */
- SCVAL(q, 0, 3); q++; /* first frag + last frag */
- RSIVAL(q, 0, 0x10000000); q += 4; /* packed data representation */
- RSSVAL(q, 0, 0); q += 2; /* fragment length, fill in later */
- SSVAL(q, 0, 0); q += 2; /* authentication length */
- callid = RIVAL(inbuf, 12);
- RSIVAL(q, 0, callid); q += 4; /* call identifier - match incoming RPC */
- SIVAL(q, 0, 0x18); q += 4; /* allocation hint (no idea) */
- SSVAL(q, 0, 0); q += 2; /* presentation context identifier */
- SCVAL(q, 0, 0); q++; /* cancel count */
- SCVAL(q, 0, 0); q++; /* reserved */
-}
-
-/* this function is due to be replaced */
-static void endrpcreply(char *inbuf, char *q, int datalen, int rtnval, int *rlen)
-{
- SSVAL(q, 8, datalen + 4);
- SIVAL(q,0x10,datalen+4-0x18); /* allocation hint */
- SIVAL(q, datalen, rtnval);
- *rlen = datalen + 4;
- { int fd; fd = open("/tmp/rpc", O_RDWR); write(fd, q, datalen + 4); }
-}
-
-/* RID username mapping function. just for fun, it maps to the unix uid */
-static uint32 name_to_rid(char *user_name)
-{
- struct passwd *pw = Get_Pwnam(user_name, False);
- if (!pw)
- {
- DEBUG(1,("Username %s is invalid on this system\n", user_name));
- return (uint32)(-1);
- }
-
- return (uint32)(pw->pw_uid);
-}
-
-
-/* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
-char *dom_sid_to_string(DOM_SID *sid)
-{
- static pstring sidstr;
- char subauth[16];
- int i;
- uint32 ia = (sid->id_auth[0]) +
- (sid->id_auth[1] << 8 ) +
- (sid->id_auth[2] << 16) +
- (sid->id_auth[3] << 24);
-
- sprintf(sidstr, "S-%d-%d", sid->sid_no, ia);
-
- for (i = 0; i < sid->num_auths; i++)
- {
- sprintf(subauth, "-%d", sid->sub_auths[i]);
- strcat(sidstr, subauth);
- }
-
- DEBUG(5,("dom_sid_to_string returning %s\n", sidstr));
- return sidstr;
-}
-
-/* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
-/* identauth >= 2^32 can be detected because it will be specified in hex */
-static void make_dom_sid(DOM_SID *sid, char *domsid)
-{
- int identauth;
- char *p;
-
- DEBUG(4,("netlogon domain SID: %s\n", domsid));
-
- /* assume, but should check, that domsid starts "S-" */
- p = strtok(domsid+2,"-");
- sid->sid_no = atoi(p);
-
- /* identauth in decimal should be < 2^32 */
- /* identauth in hex should be >= 2^32 */
- identauth = atoi(strtok(0,"-"));
-
- DEBUG(4,("netlogon rev %d\n", sid->sid_no));
- DEBUG(4,("netlogon %s ia %d\n", p, identauth));
-
- sid->id_auth[0] = 0;
- sid->id_auth[1] = 0;
- sid->id_auth[2] = (identauth & 0xff000000) >> 24;
- sid->id_auth[3] = (identauth & 0x00ff0000) >> 16;
- sid->id_auth[4] = (identauth & 0x0000ff00) >> 8;
- sid->id_auth[5] = (identauth & 0x000000ff);
-
- sid->num_auths = 0;
-
- while ((p = strtok(0, "-")) != NULL)
- {
- sid->sub_auths[sid->num_auths++] = atoi(p);
- }
-}
-
-static void create_rpc_reply(RPC_HDR *hdr, uint32 call_id, int data_len)
-{
- if (hdr == NULL) return;
-
- hdr->major = 5; /* RPC version 5 */
- hdr->minor = 0; /* minor version 0 */
- hdr->pkt_type = 2; /* RPC response packet */
- hdr->frag = 3; /* first frag + last frag */
- hdr->pack_type = 1; /* packed data representation */
- hdr->frag_len = data_len; /* fragment length, fill in later */
- hdr->auth_len = 0; /* authentication length */
- hdr->call_id = call_id; /* call identifier - match incoming RPC */
- hdr->alloc_hint = data_len - 0x18; /* allocation hint (no idea) */
- hdr->context_id = 0; /* presentation context identifier */
- hdr->cancel_count = 0; /* cancel count */
- hdr->reserved = 0; /* reserved */
-}
-
-static void make_rpc_reply(char *inbuf, char *q, int data_len)
-{
- uint32 callid = RIVAL(inbuf, 12);
- RPC_HDR hdr;
-
- create_rpc_reply(&hdr, callid, data_len);
- smb_io_rpc_hdr(False, &hdr, q, q, 4);
-}
-
-static int lsa_reply_open_policy(char *q, char *base)
-{
- char *start = q;
- LSA_R_OPEN_POL r_o;
-
- /* set up the LSA QUERY INFO response */
- bzero(&(r_o.pol.data), POL_HND_SIZE);
- r_o.status = 0x0;
-
- /* store the response in the SMB stream */
- q = lsa_io_r_open_pol(False, &r_o, q, base, 4);
-
- /* return length of SMB data stored */
- return q - start;
-}
-
-static void make_uni_hdr(UNIHDR *hdr, int max_len, int len, uint16 terminate)
-{
- hdr->uni_max_len = max_len;
- hdr->uni_str_len = len;
- hdr->undoc = terminate;
-}
-
-static void make_uni_hdr2(UNIHDR2 *hdr, int max_len, int len, uint16 terminate)
-{
- make_uni_hdr(&(hdr->unihdr), max_len, len, terminate);
- hdr->undoc_buffer = len > 0 ? 1 : 0;
-}
-
-static void make_unistr(UNISTR *str, char *buf)
-{
- /* store the string (null-terminated copy) */
- PutUniCode((char *)(str->buffer), buf);
-}
-
-static void make_unistr2(UNISTR2 *str, char *buf, int len, char terminate)
-{
- /* set up string lengths. add one if string is not null-terminated */
- str->uni_max_len = len + (terminate != 0 ? 1 : 0);
- str->undoc = 0;
- str->uni_str_len = len;
-
- /* store the string (null-terminated copy) */
- PutUniCode((char *)str->buffer, buf);
-
- /* overwrite the last character: some strings are terminated with 4 not 0 */
- str->buffer[len] = (uint16)terminate;
-}
-
-static void make_dom_rid2(DOM_RID2 *rid2, uint32 rid)
-{
- rid2->type = 0x5;
- rid2->undoc = 0x5;
- rid2->rid = rid;
- rid2->rid_idx = 0;
-}
-
-static void make_dom_sid2(DOM_SID2 *sid2, char *sid_str)
-{
- int len_sid_str = strlen(sid_str);
-
- sid2->type = 0x5;
- sid2->undoc = 0;
- make_uni_hdr2(&(sid2->hdr), len_sid_str, len_sid_str, 0);
- make_unistr (&(sid2->str), sid_str);
-}
-
-static void make_dom_query(DOM_QUERY *d_q, char *dom_name, char *dom_sid)
-{
- int domlen = strlen(dom_name);
-
- d_q->uni_dom_max_len = domlen * 2;
- d_q->padding = 0;
- d_q->uni_dom_str_len = domlen * 2;
-
- d_q->buffer_dom_name = 0; /* domain buffer pointer */
- d_q->buffer_dom_sid = 0; /* domain sid pointer */
-
- /* NOT null-terminated: 4-terminated instead! */
- make_unistr2(&(d_q->uni_domain_name), dom_name, domlen, 4);
-
- make_dom_sid(&(d_q->dom_sid), dom_sid);
-}
-
-static int lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, char *q, char *base,
- char *dom_name, char *dom_sid)
-{
- char *start = q;
- LSA_R_QUERY_INFO r_q;
-
- /* set up the LSA QUERY INFO response */
-
- r_q.undoc_buffer = 1; /* not null */
- r_q.info_class = q_q->info_class;
-
- make_dom_query(&r_q.dom.id5, dom_name, dom_sid);
-
- r_q.status = 0x0;
-
- /* store the response in the SMB stream */
- q = lsa_io_r_query(False, &r_q, q, base, 4);
-
- /* return length of SMB data stored */
- return q - start;
-}
-
-/* pretty much hard-coded choice of "other" sids, unfortunately... */
-static void make_dom_ref(DOM_R_REF *ref,
- char *dom_name, char *dom_sid,
- char *other_sid1, char *other_sid2, char *other_sid3)
-{
- int len_dom_name = strlen(dom_name);
- int len_other_sid1 = strlen(other_sid1);
- int len_other_sid2 = strlen(other_sid2);
- int len_other_sid3 = strlen(other_sid3);
-
- ref->undoc_buffer = 1;
- ref->num_ref_doms_1 = 4;
- ref->buffer_dom_name = 1;
- ref->max_entries = 32;
- ref->num_ref_doms_2 = 4;
-
- make_uni_hdr2(&(ref->hdr_dom_name ), len_dom_name , len_dom_name , 0);
- make_uni_hdr2(&(ref->hdr_ref_dom[0]), len_other_sid1, len_other_sid1, 0);
- make_uni_hdr2(&(ref->hdr_ref_dom[1]), len_other_sid2, len_other_sid2, 0);
- make_uni_hdr2(&(ref->hdr_ref_dom[2]), len_other_sid3, len_other_sid3, 0);
-
- if (dom_name != NULL)
- {
- make_unistr(&(ref->uni_dom_name), dom_name);
- }
-
- make_dom_sid(&(ref->ref_dom[0]), dom_sid );
- make_dom_sid(&(ref->ref_dom[1]), other_sid1);
- make_dom_sid(&(ref->ref_dom[2]), other_sid2);
- make_dom_sid(&(ref->ref_dom[3]), other_sid3);
-}
-
-static void make_reply_lookup_rids(LSA_R_LOOKUP_RIDS *r_l,
- int num_entries, uint32 dom_rids[MAX_LOOKUP_SIDS],
- char *dom_name, char *dom_sid,
- char *other_sid1, char *other_sid2, char *other_sid3)
-{
- int i;
-
- make_dom_ref(&(r_l->dom_ref), dom_name, dom_sid,
- other_sid1, other_sid2, other_sid3);
-
- r_l->num_entries = num_entries;
- r_l->undoc_buffer = 1;
- r_l->num_entries2 = num_entries;
-
- for (i = 0; i < num_entries; i++)
- {
- make_dom_rid2(&(r_l->dom_rid[i]), dom_rids[i]);
- }
-
- r_l->num_entries3 = num_entries;
-}
-
-static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
- int num_entries, fstring dom_sids[MAX_LOOKUP_SIDS],
- char *dom_name, char *dom_sid,
- char *other_sid1, char *other_sid2, char *other_sid3)
-{
- int i;
-
- make_dom_ref(&(r_l->dom_ref), dom_name, dom_sid,
- other_sid1, other_sid2, other_sid3);
-
- r_l->num_entries = num_entries;
- r_l->undoc_buffer = 1;
- r_l->num_entries2 = num_entries;
-
- for (i = 0; i < num_entries; i++)
- {
- make_dom_sid2(&(r_l->dom_sid[i]), dom_sids[i]);
- }
-
- r_l->num_entries3 = num_entries;
-}
-
-static int lsa_reply_lookup_sids(char *q, char *base,
- int num_entries, fstring dom_sids[MAX_LOOKUP_SIDS],
- char *dom_name, char *dom_sid,
- char *other_sid1, char *other_sid2, char *other_sid3)
-{
- char *start = q;
- LSA_R_LOOKUP_SIDS r_l;
-
- /* set up the LSA Lookup SIDs response */
- make_reply_lookup_sids(&r_l, num_entries, dom_sids,
- dom_name, dom_sid, other_sid1, other_sid2, other_sid3);
- r_l.status = 0x0;
-
- /* store the response in the SMB stream */
- q = lsa_io_r_lookup_sids(False, &r_l, q, base, 4);
-
- /* return length of SMB data stored */
- return q - start;
-}
-
-static int lsa_reply_lookup_rids(char *q, char *base,
- int num_entries, uint32 dom_rids[MAX_LOOKUP_SIDS],
- char *dom_name, char *dom_sid,
- char *other_sid1, char *other_sid2, char *other_sid3)
-{
- char *start = q;
- LSA_R_LOOKUP_RIDS r_l;
-
- /* set up the LSA Lookup RIDs response */
- make_reply_lookup_rids(&r_l, num_entries, dom_rids,
- dom_name, dom_sid, other_sid1, other_sid2, other_sid3);
- r_l.status = 0x0;
-
- /* store the response in the SMB stream */
- q = lsa_io_r_lookup_rids(False, &r_l, q, base, 4);
-
- /* return length of SMB data stored */
- return q - start;
-}
-
-static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c, char chal[8], int status)
-{
- memcpy(r_c->srv_chal.data, chal, sizeof(r_c->srv_chal.data));
- r_c->status = status;
-}
-
-#if 0
- char chal[8];
- /* PAXX: set these to random values */
- for (int i = 0; i < 8; i+++)
- {
- chal[i] = 0xA5;
- }
-#endif
-
-static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base,
- char chal[8])
-{
- char *start = q;
- LSA_R_REQ_CHAL r_c;
-
- /* set up the LSA REQUEST CHALLENGE response */
-
- make_lsa_r_req_chal(&r_c, chal, 0);
-
- /* store the response in the SMB stream */
- q = lsa_io_r_req_chal(False, &r_c, q, base, 4);
-
- /* return length of SMB data stored */
- return q - start;
-}
-
-static void make_lsa_chal(DOM_CHAL *cred, char resp_cred[8])
-{
- memcpy(cred->data, resp_cred, sizeof(cred->data));
-}
-
-static void make_lsa_r_auth_2(LSA_R_AUTH_2 *r_a,
- char resp_cred[8], NEG_FLAGS *flgs, int status)
-{
- make_lsa_chal(&(r_a->srv_chal), resp_cred);
- memcpy(&(r_a->srv_flgs), flgs, sizeof(r_a->srv_flgs));
- r_a->status = status;
-}
-
-static int lsa_reply_auth_2(LSA_Q_AUTH_2 *q_a, char *q, char *base,
- char resp_cred[8], int status)
-{
- char *start = q;
- LSA_R_AUTH_2 r_a;
-
- /* set up the LSA AUTH 2 response */
-
- make_lsa_r_auth_2(&r_a, resp_cred, &(q_a->clnt_flgs), status);
-
- /* store the response in the SMB stream */
- q = lsa_io_r_auth_2(False, &r_a, q, base, 4);
-
- /* return length of SMB data stored */
- return q - start;
-}
-
-static void make_lsa_dom_chal(DOM_CRED *cred, char srv_chal[8], UTIME srv_time)
-{
- make_lsa_chal(&(cred->challenge), srv_chal);
- cred->timestamp = srv_time;
-}
-
-
-static void make_lsa_r_srv_pwset(LSA_R_SRV_PWSET *r_a,
- char srv_chal[8], UTIME srv_time, int status)
-{
- make_lsa_dom_chal(&(r_a->srv_cred), srv_chal, srv_time);
- r_a->status = status;
-}
-
-static int lsa_reply_srv_pwset(LSA_Q_SRV_PWSET *q_s, char *q, char *base,
- char srv_cred[8], UTIME srv_time,
- int status)
-{
- char *start = q;
- LSA_R_SRV_PWSET r_s;
-
- /* set up the LSA Server Password Set response */
- make_lsa_r_srv_pwset(&r_s, srv_cred, srv_time, status);
-
- /* store the response in the SMB stream */
- q = lsa_io_r_srv_pwset(False, &r_s, q, base, 4);
-
- /* return length of SMB data stored */
- return q - start;
-}
-
-static void make_lsa_user_info(LSA_USER_INFO *usr,
-
- NTTIME *logon_time,
- NTTIME *logoff_time,
- NTTIME *kickoff_time,
- NTTIME *pass_last_set_time,
- NTTIME *pass_can_change_time,
- NTTIME *pass_must_change_time,
-
- char *user_name,
- char *full_name,
- char *logon_script,
- char *profile_path,
- char *home_dir,
- char *dir_drive,
-
- uint16 logon_count,
- uint16 bad_pw_count,
-
- uint32 user_id,
- uint32 group_id,
- uint32 num_groups,
- DOM_GID *gids,
- uint32 user_flgs,
-
- char sess_key[16],
-
- char *logon_srv,
- char *logon_dom,
-
- char *dom_sid,
- char *other_sids) /* space-delimited set of SIDs */
-{
- /* only cope with one "other" sid, right now. */
- /* need to count the number of space-delimited sids */
- int i;
- int num_other_sids = other_sids != NULL ? 1 : 0;
-
- int len_user_name = strlen(user_name );
- int len_full_name = strlen(full_name );
- int len_logon_script = strlen(logon_script);
- int len_profile_path = strlen(profile_path);
- int len_home_dir = strlen(home_dir );
- int len_dir_drive = strlen(dir_drive );
-
- int len_logon_srv = strlen(logon_srv);
- int len_logon_dom = strlen(logon_dom);
-
- usr->undoc_buffer = 1; /* yes, we're bothering to put USER_INFO data here */
-
- usr->logon_time = *logon_time;
- usr->logoff_time = *logoff_time;
- usr->kickoff_time = *kickoff_time;
- usr->pass_last_set_time = *pass_last_set_time;
- usr->pass_can_change_time = *pass_can_change_time;
- usr->pass_must_change_time = *pass_must_change_time;
-
- make_uni_hdr(&(usr->hdr_user_name ), len_user_name , len_user_name , 4);
- make_uni_hdr(&(usr->hdr_full_name ), len_full_name , len_full_name , 4);
- make_uni_hdr(&(usr->hdr_logon_script), len_logon_script, len_logon_script, 4);
- make_uni_hdr(&(usr->hdr_profile_path), len_profile_path, len_profile_path, 4);
- make_uni_hdr(&(usr->hdr_home_dir ), len_home_dir , len_home_dir , 4);
- make_uni_hdr(&(usr->hdr_dir_drive ), len_dir_drive , len_dir_drive , 4);
-
- usr->logon_count = logon_count;
- usr->bad_pw_count = bad_pw_count;
-
- usr->user_id = user_id;
- usr->group_id = group_id;
- usr->num_groups = num_groups;
- usr->buffer_groups = num_groups ? 1 : 0; /* yes, we're bothering to put group info in */
- usr->user_flgs = user_flgs;
-
- if (sess_key != NULL)
- {
- memcpy(usr->sess_key, sess_key, sizeof(usr->sess_key));
- }
- else
- {
- bzero(usr->sess_key, sizeof(usr->sess_key));
- }
-
- make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv, len_logon_srv, 4);
- make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom, len_logon_dom, 4);
-
- usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
-
- bzero(usr->padding, sizeof(usr->padding));
-
- usr->num_other_sids = num_other_sids;
- usr->buffer_other_sids = num_other_sids != 0 ? 1 : 0;
-
- make_unistr2(&(usr->uni_user_name ), user_name , len_user_name , 0);
- make_unistr2(&(usr->uni_full_name ), full_name , len_full_name , 0);
- make_unistr2(&(usr->uni_logon_script), logon_script, len_logon_script, 0);
- make_unistr2(&(usr->uni_profile_path), profile_path, len_profile_path, 0);
- make_unistr2(&(usr->uni_home_dir ), home_dir , len_home_dir , 0);
- make_unistr2(&(usr->uni_dir_drive ), dir_drive , len_dir_drive , 0);
-
- usr->num_groups2 = num_groups;
- for (i = 0; i < num_groups; i++)
- {
- usr->gids[i] = gids[i];
- }
-
- make_unistr2(&(usr->uni_logon_srv), logon_srv, len_logon_srv, 0);
- make_unistr2(&(usr->uni_logon_dom), logon_dom, len_logon_dom, 0);
-
- make_dom_sid(&(usr->dom_sid), dom_sid);
- make_dom_sid(&(usr->other_sids[0]), other_sids);
-}
-
-
-static int lsa_reply_sam_logon(LSA_Q_SAM_LOGON *q_s, char *q, char *base,
- char srv_cred[8], UTIME srv_time,
- LSA_USER_INFO *user_info)
-{
- char *start = q;
- LSA_R_SAM_LOGON r_s;
-
- /* XXXX maybe we want to say 'no', reject the client's credentials */
- r_s.buffer_creds = 1; /* yes, we have valid server credentials */
- make_lsa_dom_chal(&(r_s.srv_creds), srv_cred, srv_time);
-
- /* store the user information, if there is any. */
- r_s.user = user_info;
- r_s.buffer_user = user_info != NULL ? 1 : 0;
- r_s.status = user_info != NULL ? 0 : (0xC000000|NT_STATUS_NO_SUCH_USER);
-
- /* store the response in the SMB stream */
- q = lsa_io_r_sam_logon(False, &r_s, q, base, 4);
-
- /* return length of SMB data stored */
- return q - start;
-}
-
-
-static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base,
- char srv_cred[8], UTIME srv_time,
- uint32 status)
-{
- char *start = q;
- LSA_R_SAM_LOGOFF r_s;
-
- /* XXXX maybe we want to say 'no', reject the client's credentials */
- r_s.buffer_creds = 1; /* yes, we have valid server credentials */
- make_lsa_dom_chal(&(r_s.srv_creds), srv_cred, srv_time);
-
- r_s.status = status;
-
- /* store the response in the SMB stream */
- q = lsa_io_r_sam_logoff(False, &r_s, q, base, 4);
-
- /* return length of SMB data stored */
- return q - start;
-}
-
-
-static void api_lsa_open_policy( char *param, char *data,
- char **rdata, int *rdata_len )
-{
- int reply_len;
-
- /* we might actually want to decode the query, but it's not necessary */
- /* lsa_io_q_open_policy(...); */
-
- /* return a 20 byte policy handle */
- reply_len = lsa_reply_open_policy(*rdata + 0x18, *rdata + 0x18);
-
- /* construct header, now that we know the reply length */
- make_rpc_reply(data, *rdata, reply_len);
- *rdata_len = reply_len + 0x18;
-}
-
-static void api_lsa_query_info( char *param, char *data,
- char **rdata, int *rdata_len )
-{
- int reply_len;
-
- LSA_Q_QUERY_INFO q_i;
- pstring dom_name;
- pstring dom_sid;
-
- /* grab the info class and policy handle */
- lsa_io_q_query(True, &q_i, data + 0x18, data + 0x18, 4);
-
- pstrcpy(dom_name, lp_workgroup());
- pstrcpy(dom_sid , lp_domainsid());
-
- /* construct reply. return status is always 0x0 */
- reply_len = lsa_reply_query_info(&q_i, *rdata + 0x18, *rdata + 0x18,
- dom_name, dom_sid);
-
- /* construct header, now that we know the reply length */
- make_rpc_reply(data, *rdata, reply_len);
- *rdata_len = reply_len + 0x18;
-}
-
-static void api_lsa_lookup_sids( char *param, char *data,
- char **rdata, int *rdata_len )
-{
- int reply_len;
-
- int i;
- LSA_Q_LOOKUP_SIDS q_l;
- pstring dom_name;
- pstring dom_sid;
- fstring dom_sids[MAX_LOOKUP_SIDS];
-
- /* grab the info class and policy handle */
- lsa_io_q_lookup_sids(True, &q_l, data + 0x18, data + 0x18, 4);
-
- pstrcpy(dom_name, lp_workgroup());
- pstrcpy(dom_sid , lp_domainsid());
-
- /* convert received SIDs to strings, so we can do them. */
- for (i = 0; i < q_l.num_entries; i++)
- {
- fstrcpy(dom_sids[i], dom_sid_to_string(&(q_l.dom_sids[i])));
- }
-
- /* construct reply. return status is always 0x0 */
- reply_len = lsa_reply_lookup_sids(*rdata + 0x18, *rdata + 0x18,
- q_l.num_entries, dom_sids, /* text-converted SIDs */
- dom_name, dom_sid, /* domain name, domain SID */
- "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */
-
- /* construct header, now that we know the reply length */
- make_rpc_reply(data, *rdata, reply_len);
- *rdata_len = reply_len + 0x18;
-}
-
-static void api_lsa_lookup_names( char *param, char *data,
- char **rdata, int *rdata_len )
-{
- int reply_len;
-
- int i;
- LSA_Q_LOOKUP_RIDS q_l;
- pstring dom_name;
- pstring dom_sid;
- uint32 dom_rids[MAX_LOOKUP_SIDS];
-
- /* grab the info class and policy handle */
- lsa_io_q_lookup_rids(True, &q_l, data + 0x18, data + 0x18, 4);
-
- pstrcpy(dom_name, lp_workgroup());
- pstrcpy(dom_sid , lp_domainsid());
-
- /* convert received RIDs to strings, so we can do them. */
- for (i = 0; i < q_l.num_entries; i++)
- {
- char *user_name = unistr2(q_l.lookup_name[i].str.buffer);
- dom_rids[i] = name_to_rid(user_name);
- }
-
- /* construct reply. return status is always 0x0 */
- reply_len = lsa_reply_lookup_rids(*rdata + 0x18, *rdata + 0x18,
- q_l.num_entries, dom_rids, /* text-converted SIDs */
- dom_name, dom_sid, /* domain name, domain SID */
- "S-1-1", "S-1-3", "S-1-5"); /* the three other SIDs */
-
- /* construct header, now that we know the reply length */
- make_rpc_reply(data, *rdata, reply_len);
- *rdata_len = reply_len + 0x18;
-}
-
-BOOL api_ntlsarpcTNP(int cnum,int uid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- uint16 opnum = SVAL(data,22);
-
- int pkttype = CVAL(data, 2);
- if (pkttype == 0x0b) /* RPC BIND */
- {
- DEBUG(4,("netlogon rpc bind %x\n",pkttype));
- LsarpcTNP1(data,rdata,rdata_len);
- return True;
- }
-
- DEBUG(4,("ntlsa TransactNamedPipe op %x\n",opnum));
- switch (opnum)
- {
- case LSA_OPENPOLICY:
- {
- DEBUG(3,("LSA_OPENPOLICY\n"));
- api_lsa_open_policy(param, data, rdata, rdata_len);
- break;
- }
-
- case LSA_QUERYINFOPOLICY:
- {
- DEBUG(3,("LSA_QUERYINFOPOLICY\n"));
-
- api_lsa_query_info(param, data, rdata, rdata_len);
- break;
- }
-
- case LSA_ENUMTRUSTDOM:
- {
- char *q = *rdata + 0x18;
-
- DEBUG(3,("LSA_ENUMTRUSTDOM\n"));
-
- initrpcreply(data, *rdata);
-
- SIVAL(q, 0, 0); /* enumeration context */
- SIVAL(q, 0, 4); /* entries read */
- SIVAL(q, 0, 8); /* trust information */
-
- endrpcreply(data, *rdata, q-*rdata, 0x8000001a, rdata_len);
-
- break;
- }
-
- case LSA_CLOSE:
- {
- char *q = *rdata + 0x18;
-
- DEBUG(3,("LSA_CLOSE\n"));
-
- initrpcreply(data, *rdata);
-
- SIVAL(q, 0, 0);
- SIVAL(q, 0, 4);
- SIVAL(q, 0, 8);
- SIVAL(q, 0, 12);
- SIVAL(q, 0, 16);
-
- endrpcreply(data, *rdata, q-*rdata, 0, rdata_len);
-
- break;
- }
-
- case LSA_OPENSECRET:
- {
- char *q = *rdata + 0x18;
- DEBUG(3,("LSA_OPENSECRET\n"));
-
- initrpcreply(data, *rdata);
-
- SIVAL(q, 0, 0);
- SIVAL(q, 0, 4);
- SIVAL(q, 0, 8);
- SIVAL(q, 0, 12);
- SIVAL(q, 0, 16);
-
- endrpcreply(data, *rdata, q-*rdata, 0xc000034, rdata_len);
-
- break;
- }
-
- case LSA_LOOKUPSIDS:
- {
- DEBUG(3,("LSA_OPENSECRET\n"));
- api_lsa_lookup_sids(param, data, rdata, rdata_len);
- break;
- }
-
- case LSA_LOOKUPNAMES:
- {
- DEBUG(3,("LSA_LOOKUPNAMES\n"));
- api_lsa_lookup_names(param, data, rdata, rdata_len);
- break;
- }
-
- default:
- {
- DEBUG(4, ("NTLSARPC, unknown code: %lx\n", opnum));
- break;
- }
- }
- return True;
-}
-
-#endif /* NTDOMAIN */
diff --git a/source/smbd/predict.c b/source/smbd/predict.c
deleted file mode 100644
index 7d6b2498f5a..00000000000
--- a/source/smbd/predict.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- file read prediction routines
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-
-#include "includes.h"
-
-extern int DEBUGLEVEL;
-
-
-/* variables used by the read prediction module */
-static int rp_fd = -1;
-static int rp_offset = 0;
-static int rp_length = 0;
-static int rp_alloced = 0;
-static int rp_predict_fd = -1;
-static int rp_predict_offset = 0;
-static int rp_predict_length = 0;
-static int rp_timeout = 5;
-static time_t rp_time = 0;
-static char *rp_buffer = NULL;
-static BOOL predict_skip=False;
-time_t smb_last_time=(time_t)0;
-
-/****************************************************************************
-handle read prediction on a file
-****************************************************************************/
-int read_predict(int fd,int offset,char *buf,char **ptr,int num)
-{
- int ret = 0;
- int possible = rp_length - (offset - rp_offset);
-
- possible = MIN(possible,num);
-
- /* give data if possible */
- if (fd == rp_fd &&
- offset >= rp_offset &&
- possible>0 &&
- smb_last_time-rp_time < rp_timeout)
- {
- ret = possible;
- if (buf)
- memcpy(buf,rp_buffer + (offset-rp_offset),possible);
- else
- *ptr = rp_buffer + (offset-rp_offset);
- DEBUG(5,("read-prediction gave %d bytes of %d\n",ret,num));
- }
-
- if (ret == num) {
- predict_skip = True;
- } else {
- struct stat rp_stat;
-
- /* Find the end of the file - ensure we don't
- read predict beyond it. */
- if(fstat(fd,&rp_stat) < 0)
- {
- DEBUG(0,("read-prediction failed on fstat. Error was %s\n", strerror(errno)));
- predict_skip = True;
- }
- else
- {
- predict_skip = False;
-
- /* prepare the next prediction */
- rp_predict_fd = fd;
- /* Make sure we don't seek beyond the end of the file. */
- rp_predict_offset = MIN((offset + num),rp_stat.st_size);
- rp_predict_length = num;
- }
- }
-
- if (ret < 0) ret = 0;
-
- return(ret);
-}
-
-/****************************************************************************
-pre-read some data
-****************************************************************************/
-void do_read_prediction()
-{
- static int readsize = 0;
-
- if (predict_skip) return;
-
- if (rp_predict_fd == -1)
- return;
-
- rp_fd = rp_predict_fd;
- rp_offset = rp_predict_offset;
- rp_length = 0;
-
- rp_predict_fd = -1;
-
- if (readsize == 0) {
- readsize = lp_readsize();
- readsize = MAX(readsize,1024);
- }
-
- rp_predict_length = MIN(rp_predict_length,2*readsize);
- rp_predict_length = MAX(rp_predict_length,1024);
- rp_offset = (rp_offset/1024)*1024;
- rp_predict_length = (rp_predict_length/1024)*1024;
-
- if (rp_predict_length > rp_alloced)
- {
- rp_buffer = Realloc(rp_buffer,rp_predict_length);
- rp_alloced = rp_predict_length;
- if (!rp_buffer)
- {
- DEBUG(0,("can't allocate read-prediction buffer\n"));
- rp_predict_fd = -1;
- rp_fd = -1;
- rp_alloced = 0;
- return;
- }
- }
-
- if (lseek(rp_fd,rp_offset,SEEK_SET) != rp_offset) {
- rp_fd = -1;
- rp_predict_fd = -1;
- return;
- }
-
- rp_length = read(rp_fd,rp_buffer,rp_predict_length);
- rp_time = time(NULL);
- if (rp_length < 0)
- rp_length = 0;
-}
-
-/****************************************************************************
-invalidate read-prediction on a fd
-****************************************************************************/
-void invalidate_read_prediction(int fd)
-{
- if (rp_fd == fd)
- rp_fd = -1;
- if (rp_predict_fd == fd)
- rp_predict_fd = -1;
-}
-
diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c
deleted file mode 100644
index 8810bcd909d..00000000000
--- a/source/smbd/quotas.c
+++ /dev/null
@@ -1,657 +0,0 @@
-#ifdef QUOTAS
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- support for quotas
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-
-
-/*
- * This is one of the most system dependent parts of Samba, and its
- * done a litle differently. Each system has its own way of doing
- * things :-(
- */
-
-#include "includes.h"
-
-extern int DEBUGLEVEL;
-
-#ifdef LINUX
-
-#include <sys/types.h>
-#include <asm/types.h>
-#include <sys/quota.h>
-
-#include <mntent.h>
-#include <linux/unistd.h>
-
-_syscall4(int, quotactl, int, cmd, const char *, special, int, id, caddr_t, addr);
-
-/****************************************************************************
-try to get the disk space from disk quotas (LINUX version)
-****************************************************************************/
-
-BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
-{
- uid_t euser_id;
- int r;
- struct dqblk D;
- struct stat S;
- FILE *fp;
- struct mntent *mnt;
- int devno;
- int found;
-
- /* find the block device file */
-
- if ( stat(path, &S) == -1 ) {
- return(False) ;
- }
-
- devno = S.st_dev ;
-
- fp = setmntent(MOUNTED,"r");
- found = False ;
-
- while ((mnt = getmntent(fp))) {
- if ( stat(mnt->mnt_dir,&S) == -1 )
- continue ;
- if (S.st_dev == devno) {
- found = True ;
- break ;
- }
- }
- endmntent(fp) ;
-
- if (!found) {
- return(False);
- }
-
- euser_id=geteuid();
- seteuid(0);
- r=quotactl(QCMD(Q_GETQUOTA,USRQUOTA), mnt->mnt_fsname, euser_id, (caddr_t)&D);
- seteuid(euser_id);
-
- /* Use softlimit to determine disk space, except when it has been exceeded */
- *bsize = 1024;
- if (r)
- {
- if (errno == EDQUOT)
- {
- *dfree =0;
- *dsize =D.dqb_curblocks;
- return (True);
- }
- else return(False);
- }
- /* Use softlimit to determine disk space, except when it has been exceeded */
- if (
- (D.dqb_bsoftlimit && D.dqb_curblocks>=D.dqb_bsoftlimit) ||
- (D.dqb_bhardlimit && D.dqb_curblocks>=D.dqb_bhardlimit) ||
- (D.dqb_isoftlimit && D.dqb_curinodes>=D.dqb_isoftlimit) ||
- (D.dqb_ihardlimit && D.dqb_curinodes>=D.dqb_ihardlimit)
- )
- {
- *dfree = 0;
- *dsize = D.dqb_curblocks;
- }
- else if (D.dqb_bsoftlimit==0 && D.dqb_bhardlimit==0)
- {
- return(False);
- }
- else {
- *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
- *dsize = D.dqb_bsoftlimit;
- }
- return (True);
-}
-
-#elif defined(CRAY)
-
-#include <sys/quota.h>
-#include <mntent.h>
-
-/****************************************************************************
-try to get the disk space from disk quotas (CRAY VERSION)
-****************************************************************************/
-BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
-{
- struct mntent *mnt;
- FILE *fd;
- struct stat sbuf;
- dev_t devno ;
- static dev_t devno_cached = 0 ;
- static char name[MNTMAXSTR] ;
- struct q_request request ;
- struct qf_header header ;
- static int quota_default = 0 ;
- int found ;
-
- if ( stat(path,&sbuf) == -1 )
- return(False) ;
-
- devno = sbuf.st_dev ;
-
- if ( devno != devno_cached ) {
-
- devno_cached = devno ;
-
- if ((fd = setmntent(KMTAB)) == NULL)
- return(False) ;
-
- found = False ;
-
- while ((mnt = getmntent(fd)) != NULL) {
-
- if ( stat(mnt->mnt_dir,&sbuf) == -1 )
- continue ;
-
- if (sbuf.st_dev == devno) {
-
- found = True ;
- break ;
-
- }
-
- }
-
- strcpy(name,mnt->mnt_dir) ;
- endmntent(fd) ;
-
- if ( ! found )
- return(False) ;
- }
-
- request.qf_magic = QF_MAGIC ;
- request.qf_entry.id = geteuid() ;
-
- if (quotactl(name, Q_GETQUOTA, &request) == -1)
- return(False) ;
-
- if ( ! request.user )
- return(False) ;
-
- if ( request.qf_entry.user_q.f_quota == QFV_DEFAULT ) {
-
- if ( ! quota_default ) {
-
- if ( quotactl(name, Q_GETHEADER, &header) == -1 )
- return(False) ;
- else
- quota_default = header.user_h.def_fq ;
- }
-
- *dfree = quota_default ;
-
- }else if ( request.qf_entry.user_q.f_quota == QFV_PREVENT ) {
-
- *dfree = 0 ;
-
- }else{
-
- *dfree = request.qf_entry.user_q.f_quota ;
-
- }
-
- *dsize = request.qf_entry.user_q.f_use ;
-
- if ( *dfree )
- *dfree -= *dsize ;
-
- if ( *dfree < 0 )
- *dfree = 0 ;
-
- *bsize = 4096 ; /* Cray blocksize */
-
- return(True) ;
-
-}
-
-
-#elif defined(SUNOS5) || defined(SUNOS4)
-
-#include <fcntl.h>
-#if defined(SUNOS5)
-#include <sys/fs/ufs_quota.h>
-#include <sys/mnttab.h>
-#else /* defined(SUNOS4) */
-#include <ufs/quota.h>
-#include <mntent.h>
-#endif
-
-/****************************************************************************
-try to get the disk space from disk quotas (solaris 2 version)
-****************************************************************************/
-/* Quota code by Peter Urbanec (amiga@cse.unsw.edu.au) */
-BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
-{
- uid_t user_id, euser_id;
- int ret;
- struct dqblk D;
-#if defined(SUNOS5)
- struct quotctl command;
- int file;
- struct mnttab mnt;
- static char name[MNT_LINE_MAX] ;
-#else
- struct mntent *mnt;
- static char name[MNTMAXSTR] ;
-#endif
- FILE *fd;
- struct stat sbuf;
- dev_t devno ;
- static dev_t devno_cached = 0 ;
- int found ;
-
- if ( stat(path,&sbuf) == -1 )
- return(False) ;
-
- devno = sbuf.st_dev ;
- DEBUG(5,("disk_quotas: looking for path \"%s\" devno=%o\n", path,devno));
- if ( devno != devno_cached ) {
- devno_cached = devno ;
-#if defined(SUNOS5)
- if ((fd = fopen(MNTTAB, "r")) == NULL)
- return(False) ;
-
- found = False ;
- while (getmntent(fd, &mnt) == 0) {
- if ( stat(mnt.mnt_mountp,&sbuf) == -1 )
- continue ;
- DEBUG(5,("disk_quotas: testing \"%s\" devno=%o\n",
- mnt.mnt_mountp,sbuf.st_dev));
- if (sbuf.st_dev == devno) {
- found = True ;
- break ;
- }
- }
-
- strcpy(name,mnt.mnt_mountp) ;
- strcat(name,"/quotas") ;
- fclose(fd) ;
-#else
- if ((fd = setmntent(MOUNTED, "r")) == NULL)
- return(False) ;
-
- found = False ;
- while ((mnt = getmntent(fd)) != NULL) {
- if ( stat(mnt->mnt_dir,&sbuf) == -1 )
- continue ;
- DEBUG(5,("disk_quotas: testing \"%s\" devno=%o\n",
- mnt->mnt_dir,sbuf.st_dev));
- if (sbuf.st_dev == devno) {
- found = True ;
- break ;
- }
- }
-
- strcpy(name,mnt->mnt_fsname) ;
- endmntent(fd) ;
-#endif
-
- if ( ! found )
- return(False) ;
- }
-
- euser_id = geteuid();
- user_id = getuid();
-
- setuid(0); /* Solaris seems to want to give info only to super-user */
- seteuid(0);
-
-#if defined(SUNOS5)
- DEBUG(5,("disk_quotas: looking for quotas file \"%s\"\n", name));
- if((file=open(name, O_RDONLY))<0) {
- setuid(user_id); /* Restore the original UID status */
- seteuid(euser_id);
- return(False);
- }
- command.op = Q_GETQUOTA;
- command.uid = euser_id;
- command.addr = (caddr_t) &D;
- ret = ioctl(file, Q_QUOTACTL, &command);
- close(file);
-#else
- DEBUG(5,("disk_quotas: trying quotactl on device \"%s\"\n", name));
- ret = quotactl(Q_GETQUOTA, name, euser_id, &D);
-#endif
-
- setuid(user_id); /* Restore the original uid status. */
- seteuid(euser_id);
-
- if (ret < 0) {
- DEBUG(2,("disk_quotas ioctl (Solaris) failed\n"));
- return(False);
- }
-
-
- /* Use softlimit to determine disk space. A user exceeding the quota is told
- * that there's no space left. Writes might actually work for a bit if the
- * hardlimit is set higher than softlimit. Effectively the disk becomes
- * made of rubber latex and begins to expand to accommodate the user :-)
- */
-
- if (D.dqb_bsoftlimit==0)
- return(False);
- *bsize = 512;
- *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
- *dsize = D.dqb_bsoftlimit;
- if(*dfree < 0)
- {
- *dfree = 0;
- *dsize = D.dqb_curblocks;
- }
-
-DEBUG(5,("disk_quotas for path \"%s\" returning bsize %d, dfree %d, dsize %d\n",
- path,*bsize,*dfree,*dsize));
-
- return(True);
-}
-
-
-#elif defined(OSF1)
-#include <ufs/quota.h>
-
-/****************************************************************************
-try to get the disk space from disk quotas - OFS1 version
-****************************************************************************/
-BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
-{
- uid_t user_id, euser_id;
- int r, save_errno;
- struct dqblk D;
- struct stat S;
-
- euser_id = geteuid();
- user_id = getuid();
-
- setreuid(euser_id, -1);
- r= quotactl(path,QCMD(Q_GETQUOTA, USRQUOTA),euser_id,(char *) &D);
- if (r)
- save_errno = errno;
-
- if (setreuid(user_id, -1) == -1)
- DEBUG(5,("Unable to reset uid to %d\n", user_id));
-
- *bsize = DEV_BSIZE;
-
- if (r)
- {
- if (save_errno == EDQUOT) // disk quota exceeded
- {
- *dfree = 0;
- *dsize = D.dqb_curblocks;
- return (True);
- }
- else
- return (False);
- }
-
- /* Use softlimit to determine disk space, except when it has been exceeded */
-
- if (D.dqb_bsoftlimit==0)
- return(False);
-
- if ((D.dqb_curblocks>D.dqb_bsoftlimit)) {
- *dfree = 0;
- *dsize = D.dqb_curblocks;
- } else {
- *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
- *dsize = D.dqb_bsoftlimit;
- }
- return (True);
-}
-
-#elif defined (SGI6)
-/****************************************************************************
-try to get the disk space from disk quotas (IRIX 6.2 version)
-****************************************************************************/
-
-#include <sys/quota.h>
-#include <mntent.h>
-
-BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
-{
- uid_t euser_id;
- int r;
- struct dqblk D;
- struct fs_disk_quota F;
- struct stat S;
- FILE *fp;
- struct mntent *mnt;
- int devno;
- int found;
-
- /* find the block device file */
-
- if ( stat(path, &S) == -1 ) {
- return(False) ;
- }
-
- devno = S.st_dev ;
-
- fp = setmntent(MOUNTED,"r");
- found = False ;
-
- while ((mnt = getmntent(fp))) {
- if ( stat(mnt->mnt_dir,&S) == -1 )
- continue ;
- if (S.st_dev == devno) {
- found = True ;
- break ;
- }
- }
- endmntent(fp) ;
-
- if (!found) {
- return(False);
- }
-
- euser_id=geteuid();
- seteuid(0);
-
- /* Use softlimit to determine disk space, except when it has been exceeded */
-
- *bsize = 512;
-
- if ( 0 == strcmp ( mnt->mnt_type, "efs" ))
- {
- r=quotactl (Q_GETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &D);
-
- if (r==-1)
- return(False);
-
- /* Use softlimit to determine disk space, except when it has been exceeded */
- if (
- (D.dqb_bsoftlimit && D.dqb_curblocks>=D.dqb_bsoftlimit) ||
- (D.dqb_bhardlimit && D.dqb_curblocks>=D.dqb_bhardlimit) ||
- (D.dqb_fsoftlimit && D.dqb_curfiles>=D.dqb_fsoftlimit) ||
- (D.dqb_fhardlimit && D.dqb_curfiles>=D.dqb_fhardlimit)
- )
- {
- *dfree = 0;
- *dsize = D.dqb_curblocks;
- }
- else if (D.dqb_bsoftlimit==0 && D.dqb_bhardlimit==0)
- {
- return(False);
- }
- else
- {
- *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
- *dsize = D.dqb_bsoftlimit;
- }
-
- }
- else if ( 0 == strcmp ( mnt->mnt_type, "xfs" ))
- {
- r=quotactl (Q_XGETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &F);
-
- if (r==-1)
- return(False);
-
- /* Use softlimit to determine disk space, except when it has been exceeded */
- if (
- (F.d_blk_softlimit && F.d_bcount>=F.d_blk_softlimit) ||
- (F.d_blk_hardlimit && F.d_bcount>=F.d_blk_hardlimit) ||
- (F.d_ino_softlimit && F.d_icount>=F.d_ino_softlimit) ||
- (F.d_ino_hardlimit && F.d_icount>=F.d_ino_hardlimit)
- )
- {
- /*
- * Fixme!: these are __uint64_t, this may truncate values
- */
- *dfree = 0;
- *dsize = (int) F.d_bcount;
- }
- else if (F.d_blk_softlimit==0 && F.d_blk_hardlimit==0)
- {
- return(False);
- }
- else
- {
- *dfree = (int)(F.d_blk_softlimit - F.d_bcount);
- *dsize = (int)F.d_blk_softlimit;
- }
-
- }
- else
- return(False);
-
- return (True);
-
-}
-
-#else
-
-#ifdef __FreeBSD__
-#include <ufs/ufs/quota.h>
-#include <machine/param.h>
-#elif AIX
-/* AIX quota patch from Ole Holm Nielsen <ohnielse@fysik.dtu.dk> */
-#include <jfs/quota.h>
-/* AIX 4.X: Rename members of the dqblk structure (ohnielse@fysik.dtu.dk) */
-#define dqb_curfiles dqb_curinodes
-#define dqb_fhardlimit dqb_ihardlimit
-#define dqb_fsoftlimit dqb_isoftlimit
-#else /* !__FreeBSD__ && !AIX */
-#include <sys/quota.h>
-#include <devnm.h>
-#endif
-
-/****************************************************************************
-try to get the disk space from disk quotas - default version
-****************************************************************************/
-BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize)
-{
- uid_t euser_id;
- int r;
- struct dqblk D;
-#if !defined(__FreeBSD__) && !defined(AIX)
- char dev_disk[256];
- struct stat S;
- /* find the block device file */
- if ((stat(path, &S)<0) ||
- (devnm(S_IFBLK, S.st_dev, dev_disk, 256, 0)<0)) return (False);
-#endif
-
- euser_id = geteuid();
-
-#ifdef USE_SETRES
- {
- uid_t user_id;
-
- /* for HPUX, real uid must be same as euid to execute quotactl for euid */
- user_id = getuid();
- setresuid(euser_id,-1,-1);
- r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);
- if (setresuid(user_id,-1,-1))
- DEBUG(5,("Unable to reset uid to %d\n", user_id));
- }
-#else /* USE_SETRES */
-#if defined(__FreeBSD__)
- {
- /* FreeBSD patches from Marty Moll <martym@arbor.edu> */
- uid_t user_id;
- gid_t egrp_id;
-
- /* Need to be root to get quotas in FreeBSD */
- user_id = getuid();
- egrp_id = getegid();
- setuid(0);
- seteuid(0);
- r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D);
-
- /* As FreeBSD has group quotas, if getting the user
- quota fails, try getting the group instead. */
- if (r)
- r= quotactl(path,QCMD(Q_GETQUOTA,GRPQUOTA),egrp_id,(char *) &D);
- setuid(user_id);
- seteuid(euser_id);
- }
-#elif defined(AIX)
- /* AIX has both USER and GROUP quotas:
- Get the USER quota (ohnielse@fysik.dtu.dk) */
- r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D);
-#else /* !__FreeBSD__ && !AIX */
- r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);
-#endif /* !__FreeBSD__ && !AIX */
-#endif /* USE_SETRES */
-
- /* Use softlimit to determine disk space, except when it has been exceeded */
-#if defined(__FreeBSD__)
- *bsize = DEV_BSIZE;
-#else /* !__FreeBSD__ */
- *bsize = 1024;
-#endif /*!__FreeBSD__ */
-
- if (r)
- {
- if (errno == EDQUOT)
- {
- *dfree =0;
- *dsize =D.dqb_curblocks;
- return (True);
- }
- else return(False);
- }
- if (D.dqb_bsoftlimit==0)
- return(False);
- /* Use softlimit to determine disk space, except when it has been exceeded */
- if ((D.dqb_curblocks>D.dqb_bsoftlimit)
-#if !defined(__FreeBSD__)
-||((D.dqb_curfiles>D.dqb_fsoftlimit) && (D.dqb_fsoftlimit != 0))
-#endif
- ) {
- *dfree = 0;
- *dsize = D.dqb_curblocks;
- }
- else {
- *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
- *dsize = D.dqb_bsoftlimit;
- }
- return (True);
-}
-
-#endif
-
-#else
-/* this keeps fussy compilers happy */
- void quotas_dummy(void) {}
-#endif /* QUOTAS */
-
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
deleted file mode 100644
index baccb762911..00000000000
--- a/source/smbd/reply.c
+++ /dev/null
@@ -1,3821 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Main SMB reply routines
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-/*
- This file handles most of the reply_ calls that the server
- makes to handle specific protocols
-*/
-
-
-#include "includes.h"
-#include "trans2.h"
-
-/* look in server.c for some explanation of these variables */
-extern int Protocol;
-extern int DEBUGLEVEL;
-extern int max_send;
-extern int max_recv;
-extern int chain_fnum;
-extern char magic_char;
-extern connection_struct Connections[];
-extern files_struct Files[];
-extern BOOL case_sensitive;
-extern BOOL case_preserve;
-extern BOOL short_case_preserve;
-extern pstring sesssetup_user;
-extern fstring myworkgroup;
-extern int Client;
-extern int global_oplock_break;
-
-/* this macro should always be used to extract an fnum (smb_fid) from
-a packet to ensure chaining works correctly */
-#define GETFNUM(buf,where) (chain_fnum!= -1?chain_fnum:SVAL(buf,where))
-
-
-/****************************************************************************
-report a possible attack via the password buffer overflow bug
-****************************************************************************/
-static void overflow_attack(int len)
-{
- DEBUG(0,("ERROR: Invalid password length %d\n", len));
- DEBUG(0,("your machine may be under attack by a user exploiting an old bug\n"));
- DEBUG(0,("Attack was from IP=%s\n", client_addr()));
- exit_server("possible attack");
-}
-
-
-/****************************************************************************
- reply to an special message
-****************************************************************************/
-int reply_special(char *inbuf,char *outbuf)
-{
- int outsize = 4;
- int msg_type = CVAL(inbuf,0);
- int msg_flags = CVAL(inbuf,1);
- pstring name1,name2;
- extern fstring remote_machine;
- extern fstring local_machine;
- char *p;
-
- *name1 = *name2 = 0;
-
- smb_setlen(outbuf,0);
-
- switch (msg_type) {
- case 0x81: /* session request */
- CVAL(outbuf,0) = 0x82;
- CVAL(outbuf,3) = 0;
- if (name_len(inbuf+4) > 50 || name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
- DEBUG(0,("Invalid name length in session request\n"));
- return(0);
- }
- name_extract(inbuf,4,name1);
- name_extract(inbuf,4 + name_len(inbuf + 4),name2);
- DEBUG(2,("netbios connect: name1=%s name2=%s\n",
- name1,name2));
-
- fstrcpy(remote_machine,name2);
- trim_string(remote_machine," "," ");
- p = strchr(remote_machine,' ');
- strlower(remote_machine);
- if (p) *p = 0;
-
- fstrcpy(local_machine,name1);
- trim_string(local_machine," "," ");
- p = strchr(local_machine,' ');
- strlower(local_machine);
- if (p) *p = 0;
-
- add_session_user(remote_machine);
-
- reload_services(True);
- reopen_logs();
-
- break;
-
- case 0x89: /* session keepalive request
- (some old clients produce this?) */
- CVAL(outbuf,0) = 0x85;
- CVAL(outbuf,3) = 0;
- break;
-
- case 0x82: /* positive session response */
- case 0x83: /* negative session response */
- case 0x84: /* retarget session response */
- DEBUG(0,("Unexpected session response\n"));
- break;
-
- case 0x85: /* session keepalive */
- default:
- return(0);
- }
-
- DEBUG(5,("%s init msg_type=0x%x msg_flags=0x%x\n",
- timestring(),msg_type,msg_flags));
-
- return(outsize);
-}
-
-
-/*******************************************************************
-work out what error to give to a failed connection
-********************************************************************/
-static int connection_error(char *inbuf,char *outbuf,int connection_num)
-{
- switch (connection_num)
- {
- case -8:
- return(ERROR(ERRSRV,ERRnoresource));
- case -7:
- return(ERROR(ERRSRV,ERRbaduid));
- case -6:
- return(ERROR(ERRSRV,ERRinvdevice));
- case -5:
- return(ERROR(ERRSRV,ERRinvnetname));
- case -4:
- return(ERROR(ERRSRV,ERRaccess));
- case -3:
- return(ERROR(ERRDOS,ERRnoipc));
- case -2:
- return(ERROR(ERRSRV,ERRinvnetname));
- }
- return(ERROR(ERRSRV,ERRbadpw));
-}
-
-
-
-/****************************************************************************
- parse a share descriptor string
-****************************************************************************/
-static void parse_connect(char *p,char *service,char *user,
- char *password,int *pwlen,char *dev)
-{
- char *p2;
-
- DEBUG(4,("parsing connect string %s\n",p));
-
- p2 = strrchr(p,'\\');
- if (p2 == NULL)
- fstrcpy(service,p);
- else
- fstrcpy(service,p2+1);
-
- p += strlen(p) + 2;
-
- fstrcpy(password,p);
- *pwlen = strlen(password);
-
- p += strlen(p) + 2;
-
- fstrcpy(dev,p);
-
- *user = 0;
- p = strchr(service,'%');
- if (p != NULL)
- {
- *p = 0;
- fstrcpy(user,p+1);
- }
-}
-
-
-
-
-/****************************************************************************
- reply to a tcon
-****************************************************************************/
-int reply_tcon(char *inbuf,char *outbuf)
-{
- pstring service;
- pstring user;
- pstring password;
- pstring dev;
- int connection_num;
- int outsize = 0;
- uint16 vuid = SVAL(inbuf,smb_uid);
- int pwlen=0;
-
- *service = *user = *password = *dev = 0;
-
- parse_connect(smb_buf(inbuf)+1,service,user,password,&pwlen,dev);
-
- connection_num = make_connection(service,user,password,pwlen,dev,vuid);
-
- if (connection_num < 0)
- return(connection_error(inbuf,outbuf,connection_num));
-
- outsize = set_message(outbuf,2,0,True);
- SSVAL(outbuf,smb_vwv0,max_recv);
- SSVAL(outbuf,smb_vwv1,connection_num);
- SSVAL(outbuf,smb_tid,connection_num);
-
- DEBUG(3,("%s tcon service=%s user=%s cnum=%d\n",timestring(),service,user,connection_num));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a tcon and X
-****************************************************************************/
-int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize)
-{
- pstring service;
- pstring user;
- pstring password;
- pstring devicename;
- int connection_num;
- uint16 vuid = SVAL(inbuf,smb_uid);
- int passlen = SVAL(inbuf,smb_vwv3);
- BOOL doencrypt = SMBENCRYPT();
-
- *service = *user = *password = *devicename = 0;
-
- /* we might have to close an old one */
- if ((SVAL(inbuf,smb_vwv2) & 0x1) != 0)
- close_cnum(SVAL(inbuf,smb_tid),vuid);
-
- if (passlen > MAX_PASS_LEN) {
- overflow_attack(passlen);
- }
-
- {
- char *path;
- char *p;
- memcpy(password,smb_buf(inbuf),passlen);
- password[passlen]=0;
- path = smb_buf(inbuf) + passlen;
-
- if (!doencrypt || passlen != 24) {
- if (strequal(password," "))
- *password = 0;
- passlen = strlen(password);
- }
-
- fstrcpy(service,path+2);
- p = strchr(service,'\\');
- if (!p)
- return(ERROR(ERRSRV,ERRinvnetname));
- *p = 0;
- fstrcpy(service,p+1);
- p = strchr(service,'%');
- if (p)
- {
- *p++ = 0;
- fstrcpy(user,p);
- }
- StrnCpy(devicename,path + strlen(path) + 1,6);
- DEBUG(4,("Got device type %s\n",devicename));
- }
-
- connection_num = make_connection(service,user,password,passlen,devicename,vuid);
-
- if (connection_num < 0)
- return(connection_error(inbuf,outbuf,connection_num));
-
- if (Protocol < PROTOCOL_NT1)
- {
- set_message(outbuf,2,strlen(devicename)+1,True);
- strcpy(smb_buf(outbuf),devicename);
- }
- else
- {
- char *fsname = "SAMBA";
- char *p;
-
- set_message(outbuf,3,3,True);
-
- p = smb_buf(outbuf);
- strcpy(p,devicename); p = skip_string(p,1); /* device name */
- strcpy(p,fsname); p = skip_string(p,1); /* filesystem type e.g NTFS */
-
- set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
-
- SSVAL(outbuf, smb_vwv2, 0x0); /* optional support */
- }
-
- DEBUG(3,("%s tconX service=%s user=%s cnum=%d\n",timestring(),service,user,connection_num));
-
- /* set the incoming and outgoing tid to the just created one */
- SSVAL(inbuf,smb_tid,connection_num);
- SSVAL(outbuf,smb_tid,connection_num);
-
- return chain_reply(inbuf,outbuf,length,bufsize);
-}
-
-
-/****************************************************************************
- reply to an unknown type
-****************************************************************************/
-int reply_unknown(char *inbuf,char *outbuf)
-{
- int cnum;
- int type;
- cnum = SVAL(inbuf,smb_tid);
- type = CVAL(inbuf,smb_com);
-
- DEBUG(0,("%s unknown command type (%s): cnum=%d type=%d (0x%X)\n",
- timestring(),
- smb_fn_name(type),
- cnum,type,type));
-
- return(ERROR(ERRSRV,ERRunknownsmb));
-}
-
-
-/****************************************************************************
- reply to an ioctl
-****************************************************************************/
-int reply_ioctl(char *inbuf,char *outbuf)
-{
- DEBUG(3,("ignoring ioctl\n"));
-#if 0
- /* we just say it succeeds and hope its all OK.
- some day it would be nice to interpret them individually */
- return set_message(outbuf,1,0,True);
-#else
- return(ERROR(ERRSRV,ERRnosupport));
-#endif
-}
-
-
-/****************************************************************************
-reply to a session setup command
-****************************************************************************/
-int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
-{
- uint16 sess_vuid;
- int gid;
- int uid;
- int smb_bufsize;
- int smb_mpxmax;
- int smb_vc_num;
- uint32 smb_sesskey;
- int smb_apasslen = 0;
- pstring smb_apasswd;
- int smb_ntpasslen = 0;
- pstring smb_ntpasswd;
- BOOL valid_nt_password = False;
- pstring user;
- BOOL guest=False;
- BOOL computer_id=False;
- static BOOL done_sesssetup = False;
- BOOL doencrypt = SMBENCRYPT();
-
- *smb_apasswd = 0;
-
- smb_bufsize = SVAL(inbuf,smb_vwv2);
- smb_mpxmax = SVAL(inbuf,smb_vwv3);
- smb_vc_num = SVAL(inbuf,smb_vwv4);
- smb_sesskey = IVAL(inbuf,smb_vwv5);
-
- if (Protocol < PROTOCOL_NT1) {
- smb_apasslen = SVAL(inbuf,smb_vwv7);
- if (smb_apasslen > MAX_PASS_LEN)
- {
- overflow_attack(smb_apasslen);
- }
-
- memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen);
- pstrcpy(user,smb_buf(inbuf)+smb_apasslen);
-
- if (lp_security() != SEC_SERVER && !doencrypt) {
- smb_apasslen = strlen(smb_apasswd);
- }
- } else {
- uint16 passlen1 = SVAL(inbuf,smb_vwv7);
- uint16 passlen2 = SVAL(inbuf,smb_vwv8);
- uint32 client_caps = IVAL(inbuf,smb_vwv11);
- enum remote_arch_types ra_type = get_remote_arch();
-
- char *p = smb_buf(inbuf);
-
- /* client_caps is used as final determination if client is NT or Win95.
- This is needed to return the correct error codes in some
- circumstances.
- */
-
- if(ra_type == RA_WINNT || ra_type == RA_WIN95)
- {
- if(client_caps & (CAP_NT_SMBS | CAP_STATUS32))
- set_remote_arch( RA_WINNT);
- else
- set_remote_arch( RA_WIN95);
- }
-
- if (passlen1 != 24 && passlen2 != 24)
- doencrypt = False;
-
- if (passlen1 > MAX_PASS_LEN) {
- overflow_attack(passlen1);
- }
-
- passlen1 = MIN(passlen1, MAX_PASS_LEN);
- passlen2 = MIN(passlen2, MAX_PASS_LEN);
-
- if(doencrypt) {
- /* Save the lanman2 password and the NT md4 password. */
- smb_apasslen = passlen1;
- memcpy(smb_apasswd,p,smb_apasslen);
- smb_ntpasslen = passlen2;
- memcpy(smb_ntpasswd,p+passlen1,smb_ntpasslen);
- } else {
- /* both Win95 and WinNT stuff up the password lengths for
- non-encrypting systems. Uggh.
-
- if passlen1==24 its a win95 system, and its setting the
- password length incorrectly. Luckily it still works with the
- default code because Win95 will null terminate the password
- anyway
-
- if passlen1>0 and passlen2>0 then maybe its a NT box and its
- setting passlen2 to some random value which really stuffs
- things up. we need to fix that one. */
- if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 &&
- passlen2 != 1) {
- passlen2 = 0;
- }
- /* we use the first password that they gave */
- smb_apasslen = passlen1;
- StrnCpy(smb_apasswd,p,smb_apasslen);
-
- /* trim the password */
- smb_apasslen = strlen(smb_apasswd);
-
- /* wfwg sometimes uses a space instead of a null */
- if (strequal(smb_apasswd," ")) {
- smb_apasslen = 0;
- *smb_apasswd = 0;
- }
- }
-
- p += passlen1 + passlen2;
- fstrcpy(user,p); p = skip_string(p,1);
- DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n",
- p,skip_string(p,1),skip_string(p,2)));
- }
-
-
- DEBUG(3,("sesssetupX:name=[%s]\n",user));
-
- /* If name ends in $ then I think it's asking about whether a */
- /* computer with that name (minus the $) has access. For now */
- /* say yes to everything ending in $. */
- if (user[strlen(user) - 1] == '$') {
- computer_id = True;
- user[strlen(user) - 1] = '\0';
- }
-
-
- /* If no username is sent use the guest account */
- if (!*user)
- {
- strcpy(user,lp_guestaccount(-1));
- /* If no user and no password then set guest flag. */
- if( *smb_apasswd == 0)
- guest = True;
- }
-
- strlower(user);
-
- strcpy(sesssetup_user,user);
-
- reload_services(True);
-
- add_session_user(user);
-
- /* Check if the given username was the guest user with no password.
- We need to do this check after add_session_user() as that
- call can potentially change the username (via map_user).
- */
-
- if(!guest && strequal(user,lp_guestaccount(-1)) && (*smb_apasswd == 0))
- guest = True;
-
- if (!guest && !(lp_security() == SEC_SERVER && server_validate(inbuf)) &&
- !check_hosts_equiv(user))
- {
-
- /* now check if it's a valid username/password */
- /* If an NT password was supplied try and validate with that
- first. This is superior as the passwords are mixed case
- 128 length unicode */
- if(smb_ntpasslen)
- {
- if(!password_ok(user,smb_ntpasswd,smb_ntpasslen,NULL))
- DEBUG(0,("NT Password did not match ! Defaulting to Lanman\n"));
- else
- valid_nt_password = True;
- }
- if (!valid_nt_password && !password_ok(user,smb_apasswd,smb_apasslen,NULL))
- {
- if (!computer_id && lp_security() >= SEC_USER) {
-#if (GUEST_SESSSETUP == 0)
- return(ERROR(ERRSRV,ERRbadpw));
-#endif
-#if (GUEST_SESSSETUP == 1)
- if (Get_Pwnam(user,True))
- return(ERROR(ERRSRV,ERRbadpw));
-#endif
- }
- if (*smb_apasswd || !Get_Pwnam(user,True))
- strcpy(user,lp_guestaccount(-1));
- DEBUG(3,("Registered username %s for guest access\n",user));
- guest = True;
- }
- }
-
- if (!Get_Pwnam(user,True)) {
- DEBUG(3,("No such user %s - using guest account\n",user));
- strcpy(user,lp_guestaccount(-1));
- guest = True;
- }
-
- if (!strequal(user,lp_guestaccount(-1)) &&
- lp_servicenumber(user) < 0)
- {
- int homes = lp_servicenumber(HOMES_NAME);
- char *home = get_home_dir(user);
- if (homes >= 0 && home)
- lp_add_home(user,homes,home);
- }
-
-
- /* it's ok - setup a reply */
- if (Protocol < PROTOCOL_NT1) {
- set_message(outbuf,3,0,True);
- } else {
- char *p;
- set_message(outbuf,3,3,True);
- p = smb_buf(outbuf);
- strcpy(p,"Unix"); p = skip_string(p,1);
- strcpy(p,"Samba "); strcat(p,VERSION); p = skip_string(p,1);
- strcpy(p,myworkgroup); p = skip_string(p,1);
- set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
- /* perhaps grab OS version here?? */
- }
-
- /* Set the correct uid in the outgoing and incoming packets
- We will use this on future requests to determine which
- user we should become.
- */
- {
- struct passwd *pw = Get_Pwnam(user,False);
- if (!pw) {
- DEBUG(1,("Username %s is invalid on this system\n",user));
- return(ERROR(ERRSRV,ERRbadpw));
- }
- gid = pw->pw_gid;
- uid = pw->pw_uid;
- }
-
- if (guest && !computer_id)
- SSVAL(outbuf,smb_vwv2,1);
-
- /* register the name and uid as being validated, so further connections
- to a uid can get through without a password, on the same VC */
- sess_vuid = register_vuid(uid,gid,user,guest);
-
- SSVAL(outbuf,smb_uid,sess_vuid);
- SSVAL(inbuf,smb_uid,sess_vuid);
-
- if (!done_sesssetup)
- max_send = MIN(max_send,smb_bufsize);
-
- DEBUG(6,("Client requested max send size of %d\n", max_send));
-
- done_sesssetup = True;
-
- return chain_reply(inbuf,outbuf,length,bufsize);
-}
-
-
-/****************************************************************************
- reply to a chkpth
-****************************************************************************/
-int reply_chkpth(char *inbuf,char *outbuf)
-{
- int outsize = 0;
- int cnum,mode;
- pstring name;
- BOOL ok = False;
- BOOL bad_path = False;
-
- cnum = SVAL(inbuf,smb_tid);
-
- pstrcpy(name,smb_buf(inbuf) + 1);
- unix_convert(name,cnum,0,&bad_path);
-
- mode = SVAL(inbuf,smb_vwv0);
-
- if (check_name(name,cnum))
- ok = directory_exist(name,NULL);
-
- if (!ok)
- {
- /* We special case this - as when a Windows machine
- is parsing a path is steps through the components
- one at a time - if a component fails it expects
- ERRbadpath, not ERRbadfile.
- */
- if(errno == ENOENT)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
-
-#if 0
- /* Ugly - NT specific hack - maybe not needed ? (JRA) */
- if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
- (get_remote_arch() == RA_WINNT))
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbaddirectory;
- }
-#endif
-
- return(UNIXERROR(ERRDOS,ERRbadpath));
- }
-
- outsize = set_message(outbuf,0,0,True);
-
- DEBUG(3,("%s chkpth %s cnum=%d mode=%d\n",timestring(),name,cnum,mode));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a getatr
-****************************************************************************/
-int reply_getatr(char *inbuf,char *outbuf)
-{
- pstring fname;
- int cnum;
- int outsize = 0;
- struct stat sbuf;
- BOOL ok = False;
- int mode=0;
- uint32 size=0;
- time_t mtime=0;
- BOOL bad_path = False;
-
- cnum = SVAL(inbuf,smb_tid);
-
- pstrcpy(fname,smb_buf(inbuf) + 1);
- unix_convert(fname,cnum,0,&bad_path);
-
- /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
- under WfWg - weird! */
- if (! (*fname))
- {
- mode = aHIDDEN | aDIR;
- if (!CAN_WRITE(cnum)) mode |= aRONLY;
- size = 0;
- mtime = 0;
- ok = True;
- }
- else
- if (check_name(fname,cnum))
- {
- if (sys_stat(fname,&sbuf) == 0)
- {
- mode = dos_mode(cnum,fname,&sbuf);
- size = sbuf.st_size;
- mtime = sbuf.st_mtime;
- if (mode & aDIR)
- size = 0;
- ok = True;
- }
- else
- DEBUG(3,("stat of %s failed (%s)\n",fname,strerror(errno)));
- }
-
- if (!ok)
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
-
- return(UNIXERROR(ERRDOS,ERRbadfile));
- }
-
- outsize = set_message(outbuf,10,0,True);
-
- SSVAL(outbuf,smb_vwv0,mode);
- put_dos_date3(outbuf,smb_vwv1,mtime);
- SIVAL(outbuf,smb_vwv3,size);
-
- if (Protocol >= PROTOCOL_NT1) {
- char *p = strrchr(fname,'/');
- uint16 flg2 = SVAL(outbuf,smb_flg2);
- if (!p) p = fname;
- if (!is_8_3(fname, True))
- SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
- }
-
- DEBUG(3,("%s getatr name=%s mode=%d size=%d\n",timestring(),fname,mode,size));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a setatr
-****************************************************************************/
-int reply_setatr(char *inbuf,char *outbuf)
-{
- pstring fname;
- int cnum;
- int outsize = 0;
- BOOL ok=False;
- int mode;
- time_t mtime;
- BOOL bad_path = False;
-
- cnum = SVAL(inbuf,smb_tid);
-
- pstrcpy(fname,smb_buf(inbuf) + 1);
- unix_convert(fname,cnum,0,&bad_path);
-
- mode = SVAL(inbuf,smb_vwv0);
- mtime = make_unix_date3(inbuf+smb_vwv1);
-
- if (directory_exist(fname,NULL))
- mode |= aDIR;
- if (check_name(fname,cnum))
- ok = (dos_chmod(cnum,fname,mode,NULL) == 0);
- if (ok)
- ok = set_filetime(fname,mtime);
-
- if (!ok)
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
-
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- outsize = set_message(outbuf,0,0,True);
-
- DEBUG(3,("%s setatr name=%s mode=%d\n",timestring(),fname,mode));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a dskattr
-****************************************************************************/
-int reply_dskattr(char *inbuf,char *outbuf)
-{
- int cnum;
- int outsize = 0;
- int dfree,dsize,bsize;
-
- cnum = SVAL(inbuf,smb_tid);
-
- sys_disk_free(".",&bsize,&dfree,&dsize);
-
- outsize = set_message(outbuf,5,0,True);
-
- SSVAL(outbuf,smb_vwv0,dsize);
- SSVAL(outbuf,smb_vwv1,bsize/512);
- SSVAL(outbuf,smb_vwv2,512);
- SSVAL(outbuf,smb_vwv3,dfree);
-
- DEBUG(3,("%s dskattr cnum=%d dfree=%d\n",timestring(),cnum,dfree));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a search
- Can be called from SMBsearch, SMBffirst or SMBfunique.
-****************************************************************************/
-int reply_search(char *inbuf,char *outbuf)
-{
- pstring mask;
- pstring directory;
- pstring fname;
- int size,mode;
- time_t date;
- int dirtype;
- int cnum;
- int outsize = 0;
- int numentries = 0;
- BOOL finished = False;
- int maxentries;
- int i;
- char *p;
- BOOL ok = False;
- int status_len;
- char *path;
- char status[21];
- int dptr_num= -1;
- BOOL check_descend = False;
- BOOL expect_close = False;
- BOOL can_open = True;
- BOOL bad_path = False;
-
- *mask = *directory = *fname = 0;
-
- /* If we were called as SMBffirst then we must expect close. */
- if(CVAL(inbuf,smb_com) == SMBffirst)
- expect_close = True;
-
- cnum = SVAL(inbuf,smb_tid);
-
- outsize = set_message(outbuf,1,3,True);
- maxentries = SVAL(inbuf,smb_vwv0);
- dirtype = SVAL(inbuf,smb_vwv1);
- path = smb_buf(inbuf) + 1;
- status_len = SVAL(smb_buf(inbuf),3 + strlen(path));
-
-
- /* dirtype &= ~aDIR; */
-
- DEBUG(5,("path=%s status_len=%d\n",path,status_len));
-
-
- if (status_len == 0)
- {
- pstring dir2;
-
- pstrcpy(directory,smb_buf(inbuf)+1);
- pstrcpy(dir2,smb_buf(inbuf)+1);
- unix_convert(directory,cnum,0,&bad_path);
- unix_format(dir2);
-
- if (!check_name(directory,cnum))
- can_open = False;
-
- p = strrchr(dir2,'/');
- if (p == NULL)
- {
- strcpy(mask,dir2);
- *dir2 = 0;
- }
- else
- {
- *p = 0;
- pstrcpy(mask,p+1);
- }
-
- p = strrchr(directory,'/');
- if (!p)
- *directory = 0;
- else
- *p = 0;
-
- if (strlen(directory) == 0)
- strcpy(directory,"./");
- bzero(status,21);
- CVAL(status,0) = dirtype;
- }
- else
- {
- memcpy(status,smb_buf(inbuf) + 1 + strlen(path) + 4,21);
- memcpy(mask,status+1,11);
- mask[11] = 0;
- dirtype = CVAL(status,0) & 0x1F;
- Connections[cnum].dirptr = dptr_fetch(status+12,&dptr_num);
- if (!Connections[cnum].dirptr)
- goto SearchEmpty;
- string_set(&Connections[cnum].dirpath,dptr_path(dptr_num));
- if (!case_sensitive)
- strnorm(mask);
- }
-
- /* turn strings of spaces into a . */
- {
- trim_string(mask,NULL," ");
- if ((p = strrchr(mask,' ')))
- {
- fstring ext;
- fstrcpy(ext,p+1);
- *p = 0;
- trim_string(mask,NULL," ");
- strcat(mask,".");
- strcat(mask,ext);
- }
- }
-
- {
- for (p=mask; *p; p++)
- {
- if (*p != '?' && *p != '*' && !isdoschar(*p))
- {
- DEBUG(5,("Invalid char [%c] in search mask?\n",*p));
- *p = '?';
- }
- }
- }
-
- if (!strchr(mask,'.') && strlen(mask)>8)
- {
- fstring tmp;
- fstrcpy(tmp,&mask[8]);
- mask[8] = '.';
- mask[9] = 0;
- strcat(mask,tmp);
- }
-
- DEBUG(5,("mask=%s directory=%s\n",mask,directory));
-
- if (can_open)
- {
- p = smb_buf(outbuf) + 3;
-
- ok = True;
-
- if (status_len == 0)
- {
- dptr_num = dptr_create(cnum,directory,expect_close,SVAL(inbuf,smb_pid));
- if (dptr_num < 0)
- {
- if(dptr_num == -2)
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return (UNIXERROR(ERRDOS,ERRnofids));
- }
- return(ERROR(ERRDOS,ERRnofids));
- }
- }
-
- DEBUG(4,("dptr_num is %d\n",dptr_num));
-
- if (ok)
- {
- if ((dirtype&0x1F) == aVOLID)
- {
- memcpy(p,status,21);
- make_dir_struct(p,"???????????",volume_label(SNUM(cnum)),0,aVOLID,0);
- dptr_fill(p+12,dptr_num);
- if (dptr_zero(p+12) && (status_len==0))
- numentries = 1;
- else
- numentries = 0;
- p += DIR_STRUCT_SIZE;
- }
- else
- {
- DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum))));
- if (in_list(Connections[cnum].dirpath,
- lp_dontdescend(SNUM(cnum)),True))
- check_descend = True;
-
- for (i=numentries;(i<maxentries) && !finished;i++)
- {
- finished =
- !get_dir_entry(cnum,mask,dirtype,fname,&size,&mode,&date,check_descend);
- if (!finished)
- {
- memcpy(p,status,21);
- make_dir_struct(p,mask,fname,size,mode,date);
- dptr_fill(p+12,dptr_num);
- numentries++;
- }
- p += DIR_STRUCT_SIZE;
- }
- }
- }
- }
-
-
- SearchEmpty:
-
- if (numentries == 0 || !ok)
- {
- CVAL(outbuf,smb_rcls) = ERRDOS;
- SSVAL(outbuf,smb_err,ERRnofiles);
- }
-
- /* If we were called as SMBffirst with smb_search_id == NULL
- and no entries were found then return error and close dirptr
- (X/Open spec) */
-
- if(ok && expect_close && numentries == 0 && status_len == 0)
- {
- CVAL(outbuf,smb_rcls) = ERRDOS;
- SSVAL(outbuf,smb_err,ERRnofiles);
- /* Also close the dptr - we know it's gone */
- dptr_close(dptr_num);
- }
-
- /* If we were called as SMBfunique, then we can close the dirptr now ! */
- if(dptr_num >= 0 && CVAL(inbuf,smb_com) == SMBfunique)
- dptr_close(dptr_num);
-
- SSVAL(outbuf,smb_vwv0,numentries);
- SSVAL(outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
- CVAL(smb_buf(outbuf),0) = 5;
- SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE);
-
- if (Protocol >= PROTOCOL_NT1) {
- uint16 flg2 = SVAL(outbuf,smb_flg2);
- SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
- }
-
- outsize += DIR_STRUCT_SIZE*numentries;
- smb_setlen(outbuf,outsize - 4);
-
- if ((! *directory) && dptr_path(dptr_num))
- sprintf(directory,"(%s)",dptr_path(dptr_num));
-
- DEBUG(4,("%s %s mask=%s path=%s cnum=%d dtype=%d nument=%d of %d\n",
- timestring(),
- smb_fn_name(CVAL(inbuf,smb_com)),
- mask,directory,cnum,dirtype,numentries,maxentries));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a fclose (stop directory search)
-****************************************************************************/
-int reply_fclose(char *inbuf,char *outbuf)
-{
- int cnum;
- int outsize = 0;
- int status_len;
- char *path;
- char status[21];
- int dptr_num= -1;
-
- cnum = SVAL(inbuf,smb_tid);
-
- outsize = set_message(outbuf,1,0,True);
- path = smb_buf(inbuf) + 1;
- status_len = SVAL(smb_buf(inbuf),3 + strlen(path));
-
-
- if (status_len == 0)
- return(ERROR(ERRSRV,ERRsrverror));
-
- memcpy(status,smb_buf(inbuf) + 1 + strlen(path) + 4,21);
-
- if(dptr_fetch(status+12,&dptr_num)) {
- /* Close the dptr - we know it's gone */
- dptr_close(dptr_num);
- }
-
- SSVAL(outbuf,smb_vwv0,0);
-
- DEBUG(3,("%s search close cnum=%d\n",timestring(),cnum));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to an open
-****************************************************************************/
-int reply_open(char *inbuf,char *outbuf)
-{
- pstring fname;
- int cnum;
- int fnum = -1;
- int outsize = 0;
- int fmode=0;
- int share_mode;
- int size = 0;
- time_t mtime=0;
- int unixmode;
- int rmode=0;
- struct stat sbuf;
- BOOL bad_path = False;
- files_struct *fsp;
- int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
-
- cnum = SVAL(inbuf,smb_tid);
-
- share_mode = SVAL(inbuf,smb_vwv0);
-
- pstrcpy(fname,smb_buf(inbuf)+1);
- unix_convert(fname,cnum,0,&bad_path);
-
- fnum = find_free_file();
- if (fnum < 0)
- return(ERROR(ERRSRV,ERRnofids));
-
- if (!check_name(fname,cnum))
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- unixmode = unix_mode(cnum,aARCH);
-
- open_file_shared(fnum,cnum,fname,share_mode,3,unixmode,
- oplock_request,&rmode,NULL);
-
- fsp = &Files[fnum];
-
- if (!fsp->open)
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
- close_file(fnum);
- return(ERROR(ERRDOS,ERRnoaccess));
- }
-
- size = sbuf.st_size;
- fmode = dos_mode(cnum,fname,&sbuf);
- mtime = sbuf.st_mtime;
-
- if (fmode & aDIR) {
- DEBUG(3,("attempt to open a directory %s\n",fname));
- close_file(fnum);
- return(ERROR(ERRDOS,ERRnoaccess));
- }
-
- outsize = set_message(outbuf,7,0,True);
- SSVAL(outbuf,smb_vwv0,fnum);
- SSVAL(outbuf,smb_vwv1,fmode);
- put_dos_date3(outbuf,smb_vwv2,mtime);
- SIVAL(outbuf,smb_vwv4,size);
- SSVAL(outbuf,smb_vwv6,rmode);
-
- if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
- }
-
- if(fsp->granted_oplock)
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to an open and X
-****************************************************************************/
-int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
-{
- pstring fname;
- int cnum = SVAL(inbuf,smb_tid);
- int fnum = -1;
- int smb_mode = SVAL(inbuf,smb_vwv3);
- int smb_attr = SVAL(inbuf,smb_vwv5);
- BOOL oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf);
-#if 0
- int open_flags = SVAL(inbuf,smb_vwv2);
- int smb_sattr = SVAL(inbuf,smb_vwv4);
- uint32 smb_time = make_unix_date3(inbuf+smb_vwv6);
-#endif
- int smb_ofun = SVAL(inbuf,smb_vwv8);
- int unixmode;
- int size=0,fmode=0,mtime=0,rmode=0;
- struct stat sbuf;
- int smb_action = 0;
- BOOL bad_path = False;
- files_struct *fsp;
-
- /* If it's an IPC, pass off the pipe handler. */
- if (IS_IPC(cnum))
- return reply_open_pipe_and_X(inbuf,outbuf,length,bufsize);
-
- /* XXXX we need to handle passed times, sattr and flags */
-
- pstrcpy(fname,smb_buf(inbuf));
- unix_convert(fname,cnum,0,&bad_path);
-
- fnum = find_free_file();
- if (fnum < 0)
- return(ERROR(ERRSRV,ERRnofids));
-
- if (!check_name(fname,cnum))
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- unixmode = unix_mode(cnum,smb_attr | aARCH);
-
- open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode,
- oplock_request, &rmode,&smb_action);
-
- fsp = &Files[fnum];
-
- if (!fsp->open)
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
- close_file(fnum);
- return(ERROR(ERRDOS,ERRnoaccess));
- }
-
- size = sbuf.st_size;
- fmode = dos_mode(cnum,fname,&sbuf);
- mtime = sbuf.st_mtime;
- if (fmode & aDIR) {
- close_file(fnum);
- return(ERROR(ERRDOS,ERRnoaccess));
- }
-
- if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
- smb_action |= EXTENDED_OPLOCK_GRANTED;
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
- }
-
- if(fsp->granted_oplock) {
- smb_action |= EXTENDED_OPLOCK_GRANTED;
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
- }
-
- set_message(outbuf,15,0,True);
- SSVAL(outbuf,smb_vwv2,fnum);
- SSVAL(outbuf,smb_vwv3,fmode);
- put_dos_date3(outbuf,smb_vwv4,mtime);
- SIVAL(outbuf,smb_vwv6,size);
- SSVAL(outbuf,smb_vwv8,rmode);
- SSVAL(outbuf,smb_vwv11,smb_action);
-
- chain_fnum = fnum;
-
- return chain_reply(inbuf,outbuf,length,bufsize);
-}
-
-
-/****************************************************************************
- reply to a SMBulogoffX
-****************************************************************************/
-int reply_ulogoffX(char *inbuf,char *outbuf,int length,int bufsize)
-{
- uint16 vuid = SVAL(inbuf,smb_uid);
- user_struct *vuser = get_valid_user_struct(vuid);
-
- if(vuser == 0) {
- DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid));
- }
-
- /* in user level security we are supposed to close any files
- open by this user */
- if ((vuser != 0) && (lp_security() != SEC_SHARE)) {
- int i;
- for (i=0;i<MAX_OPEN_FILES;i++)
- if (Files[i].uid == vuser->uid && Files[i].open) {
- close_file(i);
- }
- }
-
- invalidate_vuid(vuid);
-
- set_message(outbuf,2,0,True);
-
- DEBUG(3,("%s ulogoffX vuid=%d\n",timestring(),vuid));
-
- return chain_reply(inbuf,outbuf,length,bufsize);
-}
-
-
-/****************************************************************************
- reply to a mknew or a create
-****************************************************************************/
-int reply_mknew(char *inbuf,char *outbuf)
-{
- pstring fname;
- int cnum,com;
- int fnum = -1;
- int outsize = 0;
- int createmode;
- mode_t unixmode;
- int ofun = 0;
- BOOL bad_path = False;
- files_struct *fsp;
- int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
-
- com = SVAL(inbuf,smb_com);
- cnum = SVAL(inbuf,smb_tid);
-
- createmode = SVAL(inbuf,smb_vwv0);
- pstrcpy(fname,smb_buf(inbuf)+1);
- unix_convert(fname,cnum,0,&bad_path);
-
- if (createmode & aVOLID)
- {
- DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
- }
-
- unixmode = unix_mode(cnum,createmode);
-
- fnum = find_free_file();
- if (fnum < 0)
- return(ERROR(ERRSRV,ERRnofids));
-
- if (!check_name(fname,cnum))
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- if(com == SMBmknew)
- {
- /* We should fail if file exists. */
- ofun = 0x10;
- }
- else
- {
- /* SMBcreate - Create if file doesn't exist, truncate if it does. */
- ofun = 0x12;
- }
-
- /* Open file in dos compatibility share mode. */
- open_file_shared(fnum,cnum,fname,(DENY_FCB<<4)|0xF, ofun, unixmode,
- oplock_request, NULL, NULL);
-
- fsp = &Files[fnum];
-
- if (!fsp->open)
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- outsize = set_message(outbuf,1,0,True);
- SSVAL(outbuf,smb_vwv0,fnum);
-
- if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
- }
-
- if(fsp->granted_oplock)
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
-
- DEBUG(2,("new file %s\n",fname));
- DEBUG(3,("%s mknew %s fd=%d fnum=%d cnum=%d dmode=%d umode=%o\n",timestring(),fname,Files[fnum].fd_ptr->fd,fnum,cnum,createmode,unixmode));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a create temporary file
-****************************************************************************/
-int reply_ctemp(char *inbuf,char *outbuf)
-{
- pstring fname;
- pstring fname2;
- int cnum;
- int fnum = -1;
- int outsize = 0;
- int createmode;
- mode_t unixmode;
- BOOL bad_path = False;
- files_struct *fsp;
- int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
-
- cnum = SVAL(inbuf,smb_tid);
- createmode = SVAL(inbuf,smb_vwv0);
- pstrcpy(fname,smb_buf(inbuf)+1);
- strcat(fname,"/TMXXXXXX");
- unix_convert(fname,cnum,0,&bad_path);
-
- unixmode = unix_mode(cnum,createmode);
-
- fnum = find_free_file();
- if (fnum < 0)
- return(ERROR(ERRSRV,ERRnofids));
-
- if (!check_name(fname,cnum))
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- strcpy(fname2,(char *)mktemp(fname));
-
- /* Open file in dos compatibility share mode. */
- /* We should fail if file exists. */
- open_file_shared(fnum,cnum,fname2,(DENY_FCB<<4)|0xF, 0x10, unixmode,
- oplock_request, NULL, NULL);
-
- fsp = &Files[fnum];
-
- if (!fsp->open)
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- outsize = set_message(outbuf,1,2 + strlen(fname2),True);
- SSVAL(outbuf,smb_vwv0,fnum);
- CVAL(smb_buf(outbuf),0) = 4;
- strcpy(smb_buf(outbuf) + 1,fname2);
-
- if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
- }
-
- if(fsp->granted_oplock)
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
-
- DEBUG(2,("created temp file %s\n",fname2));
- DEBUG(3,("%s ctemp %s fd=%d fnum=%d cnum=%d dmode=%d umode=%o\n",timestring(),fname2,Files[fnum].fd_ptr->fd,fnum,cnum,createmode,unixmode));
-
- return(outsize);
-}
-
-
-/*******************************************************************
-check if a user is allowed to delete a file
-********************************************************************/
-static BOOL can_delete(char *fname,int cnum,int dirtype)
-{
- struct stat sbuf;
- int fmode;
-
- if (!CAN_WRITE(cnum)) return(False);
-
- if (sys_lstat(fname,&sbuf) != 0) return(False);
- fmode = dos_mode(cnum,fname,&sbuf);
- if (fmode & aDIR) return(False);
- if (!lp_delete_readonly(SNUM(cnum))) {
- if (fmode & aRONLY) return(False);
- }
- if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM))
- return(False);
- if (!check_file_sharing(cnum,fname)) return(False);
- return(True);
-}
-
-/****************************************************************************
- reply to a unlink
-****************************************************************************/
-int reply_unlink(char *inbuf,char *outbuf)
-{
- int outsize = 0;
- pstring name;
- int cnum;
- int dirtype;
- pstring directory;
- pstring mask;
- char *p;
- int count=0;
- int error = ERRnoaccess;
- BOOL has_wild;
- BOOL exists=False;
- BOOL bad_path = False;
-
- *directory = *mask = 0;
-
- cnum = SVAL(inbuf,smb_tid);
- dirtype = SVAL(inbuf,smb_vwv0);
-
- pstrcpy(name,smb_buf(inbuf) + 1);
-
- DEBUG(3,("reply_unlink : %s\n",name));
-
- unix_convert(name,cnum,0,&bad_path);
-
- p = strrchr(name,'/');
- if (!p) {
- strcpy(directory,"./");
- strcpy(mask,name);
- } else {
- *p = 0;
- strcpy(directory,name);
- strcpy(mask,p+1);
- }
-
- if (is_mangled(mask))
- check_mangled_stack(mask);
-
- has_wild = strchr(mask,'*') || strchr(mask,'?');
-
- if (!has_wild) {
- strcat(directory,"/");
- strcat(directory,mask);
- if (can_delete(directory,cnum,dirtype) && !sys_unlink(directory)) count++;
- if (!count) exists = file_exist(directory,NULL);
- } else {
- void *dirptr = NULL;
- char *dname;
-
- if (check_name(directory,cnum))
- dirptr = OpenDir(cnum, directory, True);
-
- /* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
- the pattern matches against the long name, otherwise the short name
- We don't implement this yet XXXX
- */
-
- if (dirptr)
- {
- error = ERRbadfile;
-
- if (strequal(mask,"????????.???"))
- strcpy(mask,"*");
-
- while ((dname = ReadDirName(dirptr)))
- {
- pstring fname;
- pstrcpy(fname,dname);
-
- if(!mask_match(fname, mask, case_sensitive, False)) continue;
-
- error = ERRnoaccess;
- sprintf(fname,"%s/%s",directory,dname);
- if (!can_delete(fname,cnum,dirtype)) continue;
- if (!sys_unlink(fname)) count++;
- DEBUG(3,("reply_unlink : doing unlink on %s\n",fname));
- }
- CloseDir(dirptr);
- }
- }
-
- if (count == 0) {
- if (exists)
- return(ERROR(ERRDOS,error));
- else
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,error));
- }
- }
-
- outsize = set_message(outbuf,0,0,True);
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a readbraw (core+ protocol)
-****************************************************************************/
-int reply_readbraw(char *inbuf, char *outbuf)
-{
- int cnum,maxcount,mincount,fnum;
- int nread = 0;
- uint32 startpos;
- char *header = outbuf;
- int ret=0;
- int fd;
- char *fname;
-
- /*
- * Special check if an oplock break has been issued
- * and the readraw request croses on the wire, we must
- * return a zero length response here.
- */
-
- if(global_oplock_break)
- {
- _smb_setlen(header,0);
- transfer_file(0,Client,0,header,4,0);
- DEBUG(5,("readbraw - oplock break finished\n"));
- return -1;
- }
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- startpos = IVAL(inbuf,smb_vwv1);
- maxcount = SVAL(inbuf,smb_vwv3);
- mincount = SVAL(inbuf,smb_vwv4);
-
- /* ensure we don't overrun the packet size */
- maxcount = MIN(65535,maxcount);
- maxcount = MAX(mincount,maxcount);
-
- if (!FNUM_OK(fnum,cnum) || !Files[fnum].can_read)
- {
- DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",fnum));
- _smb_setlen(header,0);
- transfer_file(0,Client,0,header,4,0);
- return(-1);
- }
- else
- {
- fd = Files[fnum].fd_ptr->fd;
- fname = Files[fnum].name;
- }
-
-
- if (!is_locked(fnum,cnum,maxcount,startpos))
- {
- int size = Files[fnum].size;
- int sizeneeded = startpos + maxcount;
-
- if (size < sizeneeded) {
- struct stat st;
- if (fstat(Files[fnum].fd_ptr->fd,&st) == 0)
- size = st.st_size;
- if (!Files[fnum].can_write)
- Files[fnum].size = size;
- }
-
- nread = MIN(maxcount,(int)(size - startpos));
- }
-
- if (nread < mincount)
- nread = 0;
-
- DEBUG(3,("%s readbraw fnum=%d cnum=%d start=%d max=%d min=%d nread=%d\n",
- timestring(),
- fnum,cnum,startpos,
- maxcount,mincount,nread));
-
-#if UNSAFE_READRAW
- {
- int predict=0;
- _smb_setlen(header,nread);
-
- if (!Files[fnum].can_write)
- predict = read_predict(fd,startpos,header+4,NULL,nread);
-
- if ((nread-predict) > 0)
- seek_file(fnum,startpos + predict);
-
- ret = transfer_file(fd,Client,nread-predict,header,4+predict,
- startpos+predict);
- }
-
- if (ret != nread+4)
- DEBUG(0,("ERROR: file read failure on %s at %d for %d bytes (%d)\n",
- fname,startpos,nread,ret));
-
-#else
- ret = read_file(fnum,header+4,startpos,nread);
- if (ret < mincount) ret = 0;
-
- _smb_setlen(header,ret);
- transfer_file(0,Client,0,header,4+ret,0);
-#endif
-
- DEBUG(5,("readbraw finished\n"));
- return -1;
-}
-
-
-/****************************************************************************
- reply to a lockread (core+ protocol)
-****************************************************************************/
-int reply_lockread(char *inbuf,char *outbuf)
-{
- int cnum,fnum;
- int nread = -1;
- char *data;
- int outsize = 0;
- uint32 startpos, numtoread;
- int eclass;
- uint32 ecode;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- CHECK_FNUM(fnum,cnum);
- CHECK_READ(fnum);
- CHECK_ERROR(fnum);
-
- numtoread = SVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv2);
-
- outsize = set_message(outbuf,5,3,True);
- numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
- data = smb_buf(outbuf) + 3;
-
- if(!do_lock( fnum, cnum, numtoread, startpos, &eclass, &ecode))
- return (ERROR(eclass,ecode));
-
- nread = read_file(fnum,data,startpos,numtoread);
-
- if (nread < 0)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- outsize += nread;
- SSVAL(outbuf,smb_vwv0,nread);
- SSVAL(outbuf,smb_vwv5,nread+3);
- SSVAL(smb_buf(outbuf),1,nread);
-
- DEBUG(3,("%s lockread fnum=%d cnum=%d num=%d nread=%d\n",timestring(),fnum,cnum,numtoread,nread));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a read
-****************************************************************************/
-int reply_read(char *inbuf,char *outbuf)
-{
- int cnum,numtoread,fnum;
- int nread = 0;
- char *data;
- uint32 startpos;
- int outsize = 0;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- CHECK_FNUM(fnum,cnum);
- CHECK_READ(fnum);
- CHECK_ERROR(fnum);
-
- numtoread = SVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv2);
-
- outsize = set_message(outbuf,5,3,True);
- numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
- data = smb_buf(outbuf) + 3;
-
- if (is_locked(fnum,cnum,numtoread,startpos))
- return(ERROR(ERRDOS,ERRlock));
-
- if (numtoread > 0)
- nread = read_file(fnum,data,startpos,numtoread);
-
- if (nread < 0)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- outsize += nread;
- SSVAL(outbuf,smb_vwv0,nread);
- SSVAL(outbuf,smb_vwv5,nread+3);
- CVAL(smb_buf(outbuf),0) = 1;
- SSVAL(smb_buf(outbuf),1,nread);
-
- DEBUG(3,("%s read fnum=%d cnum=%d num=%d nread=%d\n",timestring(),fnum,cnum,numtoread,nread));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a read and X
-****************************************************************************/
-int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
-{
- int fnum = GETFNUM(inbuf,smb_vwv2);
- uint32 smb_offs = IVAL(inbuf,smb_vwv3);
- int smb_maxcnt = SVAL(inbuf,smb_vwv5);
- int smb_mincnt = SVAL(inbuf,smb_vwv6);
- int cnum;
- int nread = -1;
- char *data;
- BOOL ok = False;
-
- cnum = SVAL(inbuf,smb_tid);
-
- CHECK_FNUM(fnum,cnum);
- CHECK_READ(fnum);
- CHECK_ERROR(fnum);
-
- set_message(outbuf,12,0,True);
- data = smb_buf(outbuf);
-
- if (is_locked(fnum,cnum,smb_maxcnt,smb_offs))
- return(ERROR(ERRDOS,ERRlock));
- nread = read_file(fnum,data,smb_offs,smb_maxcnt);
- ok = True;
-
- if (nread < 0)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- SSVAL(outbuf,smb_vwv5,nread);
- SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
- SSVAL(smb_buf(outbuf),-2,nread);
-
- DEBUG(3,("%s readX fnum=%d cnum=%d min=%d max=%d nread=%d\n",
- timestring(),fnum,cnum,
- smb_mincnt,smb_maxcnt,nread));
-
- chain_fnum = fnum;
-
- return chain_reply(inbuf,outbuf,length,bufsize);
-}
-
-
-/****************************************************************************
- reply to a writebraw (core+ or LANMAN1.0 protocol)
-****************************************************************************/
-int reply_writebraw(char *inbuf,char *outbuf)
-{
- int nwritten=0;
- int total_written=0;
- int numtowrite=0;
- int cnum,fnum;
- int outsize = 0;
- long startpos;
- char *data=NULL;
- BOOL write_through;
- int tcount;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- CHECK_FNUM(fnum,cnum);
- CHECK_WRITE(fnum);
- CHECK_ERROR(fnum);
-
- tcount = IVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv3);
- write_through = BITSETW(inbuf+smb_vwv7,0);
-
- /* We have to deal with slightly different formats depending
- on whether we are using the core+ or lanman1.0 protocol */
- if(Protocol <= PROTOCOL_COREPLUS) {
- numtowrite = SVAL(smb_buf(inbuf),-2);
- data = smb_buf(inbuf);
- } else {
- numtowrite = SVAL(inbuf,smb_vwv10);
- data = smb_base(inbuf) + SVAL(inbuf, smb_vwv11);
- }
-
- /* force the error type */
- CVAL(inbuf,smb_com) = SMBwritec;
- CVAL(outbuf,smb_com) = SMBwritec;
-
- if (is_locked(fnum,cnum,tcount,startpos))
- return(ERROR(ERRDOS,ERRlock));
-
- if (seek_file(fnum,startpos) != startpos)
- DEBUG(0,("couldn't seek to %d in writebraw\n",startpos));
-
- if (numtowrite>0)
- nwritten = write_file(fnum,data,numtowrite);
-
- DEBUG(3,("%s writebraw1 fnum=%d cnum=%d start=%d num=%d wrote=%d sync=%d\n",
- timestring(),fnum,cnum,startpos,numtowrite,nwritten,write_through));
-
- if (nwritten < numtowrite)
- return(UNIXERROR(ERRHRD,ERRdiskfull));
-
- total_written = nwritten;
-
- /* Return a message to the redirector to tell it
- to send more bytes */
- CVAL(outbuf,smb_com) = SMBwritebraw;
- SSVALS(outbuf,smb_vwv0,-1);
- outsize = set_message(outbuf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
- send_smb(Client,outbuf);
-
- /* Now read the raw data into the buffer and write it */
- if (read_smb_length(Client,inbuf,SMB_SECONDARY_WAIT) == -1) {
- exit_server("secondary writebraw failed");
- }
-
- /* Even though this is not an smb message, smb_len
- returns the generic length of an smb message */
- numtowrite = smb_len(inbuf);
-
- if (tcount > nwritten+numtowrite) {
- DEBUG(3,("Client overestimated the write %d %d %d\n",
- tcount,nwritten,numtowrite));
- }
-
- nwritten = transfer_file(Client,Files[fnum].fd_ptr->fd,numtowrite,NULL,0,
- startpos+nwritten);
- total_written += nwritten;
-
- /* Set up outbuf to return the correct return */
- outsize = set_message(outbuf,1,0,True);
- CVAL(outbuf,smb_com) = SMBwritec;
- SSVAL(outbuf,smb_vwv0,total_written);
-
- if (nwritten < numtowrite) {
- CVAL(outbuf,smb_rcls) = ERRHRD;
- SSVAL(outbuf,smb_err,ERRdiskfull);
- }
-
- if (lp_syncalways(SNUM(cnum)) || write_through)
- sync_file(fnum);
-
- DEBUG(3,("%s writebraw2 fnum=%d cnum=%d start=%d num=%d wrote=%d\n",
- timestring(),fnum,cnum,startpos,numtowrite,total_written));
-
- /* we won't return a status if write through is not selected - this
- follows what WfWg does */
- if (!write_through && total_written==tcount)
- return(-1);
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a writeunlock (core+)
-****************************************************************************/
-int reply_writeunlock(char *inbuf,char *outbuf)
-{
- int cnum,fnum;
- int nwritten = -1;
- int outsize = 0;
- char *data;
- uint32 numtowrite,startpos;
- int eclass;
- uint32 ecode;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- CHECK_FNUM(fnum,cnum);
- CHECK_WRITE(fnum);
- CHECK_ERROR(fnum);
-
- numtowrite = SVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv2);
- data = smb_buf(inbuf) + 3;
-
- if (is_locked(fnum,cnum,numtowrite,startpos))
- return(ERROR(ERRDOS,ERRlock));
-
- seek_file(fnum,startpos);
-
- /* The special X/Open SMB protocol handling of
- zero length writes is *NOT* done for
- this call */
- if(numtowrite == 0)
- nwritten = 0;
- else
- nwritten = write_file(fnum,data,numtowrite);
-
- if (lp_syncalways(SNUM(cnum)))
- sync_file(fnum);
-
- if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- if(!do_unlock(fnum, cnum, numtowrite, startpos, &eclass, &ecode))
- return(ERROR(eclass,ecode));
-
- outsize = set_message(outbuf,1,0,True);
-
- SSVAL(outbuf,smb_vwv0,nwritten);
-
- DEBUG(3,("%s writeunlock fnum=%d cnum=%d num=%d wrote=%d\n",
- timestring(),fnum,cnum,numtowrite,nwritten));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a write
-****************************************************************************/
-int reply_write(char *inbuf,char *outbuf,int dum1,int dum2)
-{
- int cnum,numtowrite,fnum;
- int nwritten = -1;
- int outsize = 0;
- int startpos;
- char *data;
-
- dum1 = dum2 = 0;
-
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- CHECK_FNUM(fnum,cnum);
- CHECK_WRITE(fnum);
- CHECK_ERROR(fnum);
-
- numtowrite = SVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv2);
- data = smb_buf(inbuf) + 3;
-
- if (is_locked(fnum,cnum,numtowrite,startpos))
- return(ERROR(ERRDOS,ERRlock));
-
- seek_file(fnum,startpos);
-
- /* X/Open SMB protocol says that if smb_vwv1 is
- zero then the file size should be extended or
- truncated to the size given in smb_vwv[2-3] */
- if(numtowrite == 0)
- nwritten = set_filelen(Files[fnum].fd_ptr->fd, startpos);
- else
- nwritten = write_file(fnum,data,numtowrite);
-
- if (lp_syncalways(SNUM(cnum)))
- sync_file(fnum);
-
- if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- outsize = set_message(outbuf,1,0,True);
-
- SSVAL(outbuf,smb_vwv0,nwritten);
-
- if (nwritten < numtowrite) {
- CVAL(outbuf,smb_rcls) = ERRHRD;
- SSVAL(outbuf,smb_err,ERRdiskfull);
- }
-
- DEBUG(3,("%s write fnum=%d cnum=%d num=%d wrote=%d\n",timestring(),fnum,cnum,numtowrite,nwritten));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a write and X
-****************************************************************************/
-int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
-{
- int fnum = GETFNUM(inbuf,smb_vwv2);
- uint32 smb_offs = IVAL(inbuf,smb_vwv3);
- int smb_dsize = SVAL(inbuf,smb_vwv10);
- int smb_doff = SVAL(inbuf,smb_vwv11);
- BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
- int cnum;
- int nwritten = -1;
- char *data;
-
- cnum = SVAL(inbuf,smb_tid);
-
- CHECK_FNUM(fnum,cnum);
- CHECK_WRITE(fnum);
- CHECK_ERROR(fnum);
-
- data = smb_base(inbuf) + smb_doff;
-
- if (is_locked(fnum,cnum,smb_dsize,smb_offs))
- return(ERROR(ERRDOS,ERRlock));
-
- seek_file(fnum,smb_offs);
-
- /* X/Open SMB protocol says that, unlike SMBwrite
- if the length is zero then NO truncation is
- done, just a write of zero. To truncate a file,
- use SMBwrite. */
- if(smb_dsize == 0)
- nwritten = 0;
- else
- nwritten = write_file(fnum,data,smb_dsize);
-
- if(((nwritten == 0) && (smb_dsize != 0))||(nwritten < 0))
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- set_message(outbuf,6,0,True);
-
- SSVAL(outbuf,smb_vwv2,nwritten);
-
- if (nwritten < smb_dsize) {
- CVAL(outbuf,smb_rcls) = ERRHRD;
- SSVAL(outbuf,smb_err,ERRdiskfull);
- }
-
- DEBUG(3,("%s writeX fnum=%d cnum=%d num=%d wrote=%d\n",timestring(),fnum,cnum,smb_dsize,nwritten));
-
- chain_fnum = fnum;
-
- if (lp_syncalways(SNUM(cnum)) || write_through)
- sync_file(fnum);
-
- return chain_reply(inbuf,outbuf,length,bufsize);
-}
-
-
-/****************************************************************************
- reply to a lseek
-****************************************************************************/
-int reply_lseek(char *inbuf,char *outbuf)
-{
- int cnum,fnum;
- uint32 startpos;
- int32 res= -1;
- int mode,umode;
- int outsize = 0;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- CHECK_FNUM(fnum,cnum);
- CHECK_ERROR(fnum);
-
- mode = SVAL(inbuf,smb_vwv1) & 3;
- startpos = IVAL(inbuf,smb_vwv2);
-
- switch (mode & 3)
- {
- case 0: umode = SEEK_SET; break;
- case 1: umode = SEEK_CUR; break;
- case 2: umode = SEEK_END; break;
- default:
- umode = SEEK_SET; break;
- }
-
- res = lseek(Files[fnum].fd_ptr->fd,startpos,umode);
- Files[fnum].pos = res;
-
- outsize = set_message(outbuf,2,0,True);
- SIVALS(outbuf,smb_vwv0,res);
-
- DEBUG(3,("%s lseek fnum=%d cnum=%d ofs=%d mode=%d\n",timestring(),fnum,cnum,startpos,mode));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a flush
-****************************************************************************/
-int reply_flush(char *inbuf,char *outbuf)
-{
- int cnum, fnum;
- int outsize = set_message(outbuf,0,0,True);
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- if (fnum != 0xFFFF) {
- CHECK_FNUM(fnum,cnum);
- CHECK_ERROR(fnum);
- }
-
- if (fnum == 0xFFFF)
- {
- int i;
- for (i=0;i<MAX_OPEN_FILES;i++)
- if (OPEN_FNUM(i))
- sync_file(i);
- }
- else
- sync_file(fnum);
-
- DEBUG(3,("%s flush fnum=%d\n",timestring(),fnum));
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a exit
-****************************************************************************/
-int reply_exit(char *inbuf,char *outbuf)
-{
- int outsize = set_message(outbuf,0,0,True);
- DEBUG(3,("%s exit\n",timestring()));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a close
-****************************************************************************/
-int reply_close(char *inbuf,char *outbuf)
-{
- int fnum,cnum;
- int outsize = 0;
- time_t mtime;
- int32 eclass = 0, err = 0;
-
- outsize = set_message(outbuf,0,0,True);
-
- cnum = SVAL(inbuf,smb_tid);
-
- fnum = GETFNUM(inbuf,smb_vwv0);
- CHECK_FNUM(fnum,cnum);
-
- if(HAS_CACHED_ERROR(fnum)) {
- eclass = Files[fnum].wbmpx_ptr->wr_errclass;
- err = Files[fnum].wbmpx_ptr->wr_error;
- }
-
- mtime = make_unix_date3(inbuf+smb_vwv1);
-
- /* try and set the date */
- set_filetime(Files[fnum].name,mtime);
-
- close_file(fnum);
-
- /* We have a cached error */
- if(eclass || err)
- return(ERROR(eclass,err));
-
- DEBUG(3,("%s close fd=%d fnum=%d cnum=%d (numopen=%d)\n",
- timestring(),Files[fnum].fd_ptr->fd,fnum,cnum,
- Connections[cnum].num_files_open));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a writeclose (Core+ protocol)
-****************************************************************************/
-int reply_writeclose(char *inbuf,char *outbuf)
-{
- int cnum,numtowrite,fnum;
- int nwritten = -1;
- int outsize = 0;
- int startpos;
- char *data;
- time_t mtime;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- CHECK_FNUM(fnum,cnum);
- CHECK_WRITE(fnum);
- CHECK_ERROR(fnum);
-
- numtowrite = SVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv2);
- mtime = make_unix_date3(inbuf+smb_vwv4);
- data = smb_buf(inbuf) + 1;
-
- if (is_locked(fnum,cnum,numtowrite,startpos))
- return(ERROR(ERRDOS,ERRlock));
-
- seek_file(fnum,startpos);
-
- nwritten = write_file(fnum,data,numtowrite);
-
- set_filetime(Files[fnum].name,mtime);
-
- close_file(fnum);
-
- DEBUG(3,("%s writeclose fnum=%d cnum=%d num=%d wrote=%d (numopen=%d)\n",
- timestring(),fnum,cnum,numtowrite,nwritten,
- Connections[cnum].num_files_open));
-
- if (nwritten <= 0)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- outsize = set_message(outbuf,1,0,True);
-
- SSVAL(outbuf,smb_vwv0,nwritten);
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a lock
-****************************************************************************/
-int reply_lock(char *inbuf,char *outbuf)
-{
- int fnum,cnum;
- int outsize = set_message(outbuf,0,0,True);
- uint32 count,offset;
- int eclass;
- uint32 ecode;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- CHECK_FNUM(fnum,cnum);
- CHECK_ERROR(fnum);
-
- count = IVAL(inbuf,smb_vwv1);
- offset = IVAL(inbuf,smb_vwv3);
-
- DEBUG(3,("%s lock fd=%d fnum=%d cnum=%d ofs=%d cnt=%d\n",timestring(),Files[fnum].fd_ptr->fd,fnum,cnum,offset,count));
-
- if(!do_lock( fnum, cnum, count, offset, &eclass, &ecode))
- return (ERROR(eclass,ecode));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a unlock
-****************************************************************************/
-int reply_unlock(char *inbuf,char *outbuf)
-{
- int fnum,cnum;
- int outsize = set_message(outbuf,0,0,True);
- uint32 count,offset;
- int eclass;
- uint32 ecode;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- CHECK_FNUM(fnum,cnum);
- CHECK_ERROR(fnum);
-
- count = IVAL(inbuf,smb_vwv1);
- offset = IVAL(inbuf,smb_vwv3);
-
- if(!do_unlock(fnum, cnum, count, offset, &eclass, &ecode))
- return (ERROR(eclass,ecode));
-
- DEBUG(3,("%s unlock fd=%d fnum=%d cnum=%d ofs=%d cnt=%d\n",timestring(),Files[fnum].fd_ptr->fd,fnum,cnum,offset,count));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a tdis
-****************************************************************************/
-int reply_tdis(char *inbuf,char *outbuf)
-{
- int cnum;
- int outsize = set_message(outbuf,0,0,True);
- uint16 vuid;
-
- cnum = SVAL(inbuf,smb_tid);
- vuid = SVAL(inbuf,smb_uid);
-
- if (!OPEN_CNUM(cnum)) {
- DEBUG(4,("Invalid cnum in tdis (%d)\n",cnum));
- return(ERROR(ERRSRV,ERRinvnid));
- }
-
- Connections[cnum].used = False;
-
- close_cnum(cnum,vuid);
-
- DEBUG(3,("%s tdis cnum=%d\n",timestring(),cnum));
-
- return outsize;
-}
-
-
-
-/****************************************************************************
- reply to a echo
-****************************************************************************/
-int reply_echo(char *inbuf,char *outbuf)
-{
- int cnum;
- int smb_reverb = SVAL(inbuf,smb_vwv0);
- int seq_num;
- int data_len = smb_buflen(inbuf);
- int outsize = set_message(outbuf,1,data_len,True);
-
- cnum = SVAL(inbuf,smb_tid);
-
- /* According to the latest CIFS spec we shouldn't
- care what the TID is.
- */
-
-#if 0
- if (cnum != 0xFFFF && !OPEN_CNUM(cnum))
- {
- DEBUG(4,("Invalid cnum in echo (%d)\n",cnum));
- return(ERROR(ERRSRV,ERRinvnid));
- }
-#endif
-
- /* copy any incoming data back out */
- if (data_len > 0)
- memcpy(smb_buf(outbuf),smb_buf(inbuf),data_len);
-
- if (smb_reverb > 100)
- {
- DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
- smb_reverb = 100;
- }
-
- for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++)
- {
- SSVAL(outbuf,smb_vwv0,seq_num);
-
- smb_setlen(outbuf,outsize - 4);
-
- send_smb(Client,outbuf);
- }
-
- DEBUG(3,("%s echo %d times cnum=%d\n",timestring(),smb_reverb,cnum));
-
- return -1;
-}
-
-
-/****************************************************************************
- reply to a printopen
-****************************************************************************/
-int reply_printopen(char *inbuf,char *outbuf)
-{
- pstring fname;
- pstring fname2;
- int cnum;
- int fnum = -1;
- int outsize = 0;
-
- *fname = *fname2 = 0;
-
- cnum = SVAL(inbuf,smb_tid);
-
- if (!CAN_PRINT(cnum))
- return(ERROR(ERRDOS,ERRnoaccess));
-
- {
- pstring s;
- char *p;
- pstrcpy(s,smb_buf(inbuf)+1);
- p = s;
- while (*p)
- {
- if (!(isalnum(*p) || strchr("._-",*p)))
- *p = 'X';
- p++;
- }
-
- if (strlen(s) > 10) s[10] = 0;
-
- sprintf(fname,"%s.XXXXXX",s);
- }
-
- fnum = find_free_file();
- if (fnum < 0)
- return(ERROR(ERRSRV,ERRnofids));
-
- strcpy(fname2,(char *)mktemp(fname));
-
- if (!check_name(fname2,cnum))
- return(ERROR(ERRDOS,ERRnoaccess));
-
- /* Open for exclusive use, write only. */
- open_file_shared(fnum,cnum,fname2,(DENY_ALL<<4)|1, 0x12, unix_mode(cnum,0),
- 0, NULL, NULL);
-
- if (!Files[fnum].open)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- /* force it to be a print file */
- Files[fnum].print_file = True;
-
- outsize = set_message(outbuf,1,0,True);
- SSVAL(outbuf,smb_vwv0,fnum);
-
- DEBUG(3,("%s openprint %s fd=%d fnum=%d cnum=%d\n",timestring(),fname2,Files[fnum].fd_ptr->fd,fnum,cnum));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a printclose
-****************************************************************************/
-int reply_printclose(char *inbuf,char *outbuf)
-{
- int fnum,cnum;
- int outsize = set_message(outbuf,0,0,True);
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- CHECK_FNUM(fnum,cnum);
- CHECK_ERROR(fnum);
-
- if (!CAN_PRINT(cnum))
- return(ERROR(ERRDOS,ERRnoaccess));
-
- close_file(fnum);
-
- DEBUG(3,("%s printclose fd=%d fnum=%d cnum=%d\n",timestring(),Files[fnum].fd_ptr->fd,fnum,cnum));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a printqueue
-****************************************************************************/
-int reply_printqueue(char *inbuf,char *outbuf)
-{
- int cnum;
- int outsize = set_message(outbuf,2,3,True);
- int max_count = SVAL(inbuf,smb_vwv0);
- int start_index = SVAL(inbuf,smb_vwv1);
- uint16 vuid;
-
- cnum = SVAL(inbuf,smb_tid);
- vuid = SVAL(inbuf,smb_uid);
-
-/* allow checking the queue for anyone */
-#if 0
- if (!CAN_PRINT(cnum))
- return(ERROR(ERRDOS,ERRnoaccess));
-#endif
-
- SSVAL(outbuf,smb_vwv0,0);
- SSVAL(outbuf,smb_vwv1,0);
- CVAL(smb_buf(outbuf),0) = 1;
- SSVAL(smb_buf(outbuf),1,0);
-
- DEBUG(3,("%s printqueue cnum=%d start_index=%d max_count=%d\n",
- timestring(),cnum,start_index,max_count));
-
- if (!OPEN_CNUM(cnum) || !Connections[cnum].printer)
- {
- int i;
- cnum = -1;
-
- for (i=0;i<MAX_CONNECTIONS;i++)
- if (CAN_PRINT(i) && Connections[i].printer)
- cnum = i;
-
- if (cnum == -1)
- for (i=0;i<MAX_CONNECTIONS;i++)
- if (OPEN_CNUM(i))
- cnum = i;
-
- if (!OPEN_CNUM(cnum))
- return(ERROR(ERRSRV,ERRinvnid));
-
- DEBUG(5,("connection not open or not a printer, using cnum %d\n",cnum));
- }
-
- if (!become_user(cnum,vuid))
- return(ERROR(ERRSRV,ERRinvnid));
-
- {
- print_queue_struct *queue = NULL;
- char *p = smb_buf(outbuf) + 3;
- int count = get_printqueue(SNUM(cnum),cnum,&queue,NULL);
- int num_to_get = ABS(max_count);
- int first = (max_count>0?start_index:start_index+max_count+1);
- int i;
-
- if (first >= count)
- num_to_get = 0;
- else
- num_to_get = MIN(num_to_get,count-first);
-
-
- for (i=first;i<first+num_to_get;i++)
- {
- put_dos_date2(p,0,queue[i].time);
- CVAL(p,4) = (queue[i].status==LPQ_PRINTING?2:3);
- SSVAL(p,5,printjob_encode(SNUM(cnum), queue[i].job));
- SIVAL(p,7,queue[i].size);
- CVAL(p,11) = 0;
- StrnCpy(p+12,queue[i].user,16);
- p += 28;
- }
-
- if (count > 0)
- {
- outsize = set_message(outbuf,2,28*count+3,False);
- SSVAL(outbuf,smb_vwv0,count);
- SSVAL(outbuf,smb_vwv1,(max_count>0?first+count:first-1));
- CVAL(smb_buf(outbuf),0) = 1;
- SSVAL(smb_buf(outbuf),1,28*count);
- }
-
- if (queue) free(queue);
-
- DEBUG(3,("%d entries returned in queue\n",count));
- }
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a printwrite
-****************************************************************************/
-int reply_printwrite(char *inbuf,char *outbuf)
-{
- int cnum,numtowrite,fnum;
- int outsize = set_message(outbuf,0,0,True);
- char *data;
-
- cnum = SVAL(inbuf,smb_tid);
-
- if (!CAN_PRINT(cnum))
- return(ERROR(ERRDOS,ERRnoaccess));
-
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- CHECK_FNUM(fnum,cnum);
- CHECK_WRITE(fnum);
- CHECK_ERROR(fnum);
-
- numtowrite = SVAL(smb_buf(inbuf),1);
- data = smb_buf(inbuf) + 3;
-
- if (write_file(fnum,data,numtowrite) != numtowrite)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- DEBUG(3,("%s printwrite fnum=%d cnum=%d num=%d\n",timestring(),fnum,cnum,numtowrite));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a mkdir
-****************************************************************************/
-int reply_mkdir(char *inbuf,char *outbuf)
-{
- pstring directory;
- int cnum;
- int outsize,ret= -1;
- BOOL bad_path = False;
-
- pstrcpy(directory,smb_buf(inbuf) + 1);
- cnum = SVAL(inbuf,smb_tid);
- unix_convert(directory,cnum,0,&bad_path);
-
- if (check_name(directory,cnum))
- ret = sys_mkdir(directory,unix_mode(cnum,aDIR));
-
- if (ret < 0)
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- outsize = set_message(outbuf,0,0,True);
-
- DEBUG(3,("%s mkdir %s cnum=%d ret=%d\n",timestring(),directory,cnum,ret));
-
- return(outsize);
-}
-
-/****************************************************************************
-Static function used by reply_rmdir to delete an entire directory
-tree recursively.
-****************************************************************************/
-static BOOL recursive_rmdir(char *directory)
-{
- char *dname = NULL;
- BOOL ret = False;
- void *dirptr = OpenDir(-1, directory, False);
-
- if(dirptr == NULL)
- return True;
-
- while((dname = ReadDirName(dirptr)))
- {
- pstring fullname;
- struct stat st;
-
- if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
- continue;
-
- /* Construct the full name. */
- if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname))
- {
- errno = ENOMEM;
- ret = True;
- break;
- }
- strcpy(fullname, directory);
- strcat(fullname, "/");
- strcat(fullname, dname);
-
- if(sys_lstat(fullname, &st) != 0)
- {
- ret = True;
- break;
- }
-
- if(st.st_mode & S_IFDIR)
- {
- if(recursive_rmdir(fullname)!=0)
- {
- ret = True;
- break;
- }
- if(sys_rmdir(fullname) != 0)
- {
- ret = True;
- break;
- }
- }
- else if(sys_unlink(fullname) != 0)
- {
- ret = True;
- break;
- }
- }
- CloseDir(dirptr);
- return ret;
-}
-
-/****************************************************************************
- reply to a rmdir
-****************************************************************************/
-int reply_rmdir(char *inbuf,char *outbuf)
-{
- pstring directory;
- int cnum;
- int outsize = 0;
- BOOL ok = False;
- BOOL bad_path = False;
-
- cnum = SVAL(inbuf,smb_tid);
- pstrcpy(directory,smb_buf(inbuf) + 1);
- unix_convert(directory,cnum,0,&bad_path);
-
- if (check_name(directory,cnum))
- {
-
- dptr_closepath(directory,SVAL(inbuf,smb_pid));
- ok = (sys_rmdir(directory) == 0);
- if(!ok && (errno == ENOTEMPTY) && lp_veto_files(SNUM(cnum)))
- {
- /* Check to see if the only thing in this directory are
- vetoed files/directories. If so then delete them and
- retry. If we fail to delete any of them (and we *don't*
- do a recursive delete) then fail the rmdir. */
- BOOL all_veto_files = True;
- char *dname;
- void *dirptr = OpenDir(cnum, directory, False);
-
- if(dirptr != NULL)
- {
- int dirpos = TellDir(dirptr);
- while ((dname = ReadDirName(dirptr)))
- {
- if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
- continue;
- if(!IS_VETO_PATH(cnum, dname))
- {
- all_veto_files = False;
- break;
- }
- }
- if(all_veto_files)
- {
- SeekDir(dirptr,dirpos);
- while ((dname = ReadDirName(dirptr)))
- {
- pstring fullname;
- struct stat st;
-
- if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
- continue;
-
- /* Construct the full name. */
- if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname))
- {
- errno = ENOMEM;
- break;
- }
- pstrcpy(fullname, directory);
- strcat(fullname, "/");
- strcat(fullname, dname);
-
- if(sys_lstat(fullname, &st) != 0)
- break;
- if(st.st_mode & S_IFDIR)
- {
- if(lp_recursive_veto_delete(SNUM(cnum)))
- {
- if(recursive_rmdir(fullname) != 0)
- break;
- }
- if(sys_rmdir(fullname) != 0)
- break;
- }
- else if(sys_unlink(fullname) != 0)
- break;
- }
- CloseDir(dirptr);
- /* Retry the rmdir */
- ok = (sys_rmdir(directory) == 0);
- }
- else
- CloseDir(dirptr);
- }
- else
- errno = ENOTEMPTY;
- }
-
- if (!ok)
- DEBUG(3,("couldn't remove directory %s : %s\n",
- directory,strerror(errno)));
- }
-
- if (!ok)
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRbadpath));
- }
-
- outsize = set_message(outbuf,0,0,True);
-
- DEBUG(3,("%s rmdir %s\n",timestring(),directory));
-
- return(outsize);
-}
-
-
-/*******************************************************************
-resolve wildcards in a filename rename
-********************************************************************/
-static BOOL resolve_wildcards(char *name1,char *name2)
-{
- fstring root1,root2;
- fstring ext1,ext2;
- char *p,*p2;
-
- name1 = strrchr(name1,'/');
- name2 = strrchr(name2,'/');
-
- if (!name1 || !name2) return(False);
-
- fstrcpy(root1,name1);
- fstrcpy(root2,name2);
- p = strrchr(root1,'.');
- if (p) {
- *p = 0;
- fstrcpy(ext1,p+1);
- } else {
- fstrcpy(ext1,"");
- }
- p = strrchr(root2,'.');
- if (p) {
- *p = 0;
- fstrcpy(ext2,p+1);
- } else {
- fstrcpy(ext2,"");
- }
-
- p = root1;
- p2 = root2;
- while (*p2) {
- if (*p2 == '?') {
- *p2 = *p;
- p2++;
- } else {
- p2++;
- }
- if (*p) p++;
- }
-
- p = ext1;
- p2 = ext2;
- while (*p2) {
- if (*p2 == '?') {
- *p2 = *p;
- p2++;
- } else {
- p2++;
- }
- if (*p) p++;
- }
-
- strcpy(name2,root2);
- if (ext2[0]) {
- strcat(name2,".");
- strcat(name2,ext2);
- }
-
- return(True);
-}
-
-/*******************************************************************
-check if a user is allowed to rename a file
-********************************************************************/
-static BOOL can_rename(char *fname,int cnum)
-{
- struct stat sbuf;
-
- if (!CAN_WRITE(cnum)) return(False);
-
- if (sys_lstat(fname,&sbuf) != 0) return(False);
- if (!check_file_sharing(cnum,fname)) return(False);
-
- return(True);
-}
-
-/****************************************************************************
- reply to a mv
-****************************************************************************/
-int reply_mv(char *inbuf,char *outbuf)
-{
- int outsize = 0;
- pstring name;
- int cnum;
- pstring directory;
- pstring mask,newname;
- pstring newname_last_component;
- char *p;
- int count=0;
- int error = ERRnoaccess;
- BOOL has_wild;
- BOOL exists=False;
- BOOL bad_path1 = False;
- BOOL bad_path2 = False;
-
- *directory = *mask = 0;
-
- cnum = SVAL(inbuf,smb_tid);
-
- pstrcpy(name,smb_buf(inbuf) + 1);
- pstrcpy(newname,smb_buf(inbuf) + 3 + strlen(name));
-
- DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
-
- unix_convert(name,cnum,0,&bad_path1);
- unix_convert(newname,cnum,newname_last_component,&bad_path2);
-
- /*
- * Split the old name into directory and last component
- * strings. Note that unix_convert may have stripped off a
- * leading ./ from both name and newname if the rename is
- * at the root of the share. We need to make sure either both
- * name and newname contain a / character or neither of them do
- * as this is checked in resolve_wildcards().
- */
-
- p = strrchr(name,'/');
- if (!p) {
- strcpy(directory,".");
- strcpy(mask,name);
- } else {
- *p = 0;
- strcpy(directory,name);
- strcpy(mask,p+1);
- *p = '/'; /* Replace needed for exceptional test below. */
- }
-
- if (is_mangled(mask))
- check_mangled_stack(mask);
-
- has_wild = strchr(mask,'*') || strchr(mask,'?');
-
- if (!has_wild) {
- BOOL is_short_name = is_8_3(name, True);
-
- /* Add a terminating '/' to the directory name. */
- strcat(directory,"/");
- strcat(directory,mask);
-
- /* Ensure newname contains a '/' also */
- if(strrchr(newname,'/') == 0) {
- pstring tmpstr;
-
- strcpy(tmpstr, "./");
- strcat(tmpstr, newname);
- strcpy(newname, tmpstr);
- }
-
- DEBUG(3,("reply_mv : case_sensitive = %d, case_preserve = %d, short case preserve = %d, directory = %s, newname = %s, newname_last_component = %s, is_8_3 = %d\n",
- case_sensitive, case_preserve, short_case_preserve, directory,
- newname, newname_last_component, is_short_name));
-
- /*
- * Check for special case with case preserving and not
- * case sensitive, if directory and newname are identical,
- * and the old last component differs from the original
- * last component only by case, then we should allow
- * the rename (user is trying to change the case of the
- * filename).
- */
- if((case_sensitive == False) && ( ((case_preserve == True) && (is_short_name == False)) ||
- ((short_case_preserve == True) && (is_short_name == True))) &&
- strcsequal(directory, newname)) {
- pstring newname_modified_last_component;
-
- /*
- * Get the last component of the modified name.
- * Note that we guarantee that newname contains a '/'
- * character above.
- */
- p = strrchr(newname,'/');
- strcpy(newname_modified_last_component,p+1);
-
- if(strcsequal(newname_modified_last_component,
- newname_last_component) == False) {
- /*
- * Replace the modified last component with
- * the original.
- */
- strcpy(p+1, newname_last_component);
- }
- }
-
- if (resolve_wildcards(directory,newname) &&
- can_rename(directory,cnum) &&
- !file_exist(newname,NULL) &&
- !sys_rename(directory,newname)) count++;
-
- DEBUG(3,("reply_mv : %s doing rename on %s -> %s\n",(count != 0) ? "succeeded" : "failed",
- directory,newname));
-
- if (!count) exists = file_exist(directory,NULL);
- if (!count && exists && file_exist(newname,NULL)) {
- exists = True;
- error = 183;
- }
- } else {
- void *dirptr = NULL;
- char *dname;
- pstring destname;
-
- if (check_name(directory,cnum))
- dirptr = OpenDir(cnum, directory, True);
-
- if (dirptr)
- {
- error = ERRbadfile;
-
- if (strequal(mask,"????????.???"))
- strcpy(mask,"*");
-
- while ((dname = ReadDirName(dirptr)))
- {
- pstring fname;
- pstrcpy(fname,dname);
-
- if(!mask_match(fname, mask, case_sensitive, False)) continue;
-
- error = ERRnoaccess;
- sprintf(fname,"%s/%s",directory,dname);
- if (!can_rename(fname,cnum)) continue;
- pstrcpy(destname,newname);
-
- if (!resolve_wildcards(fname,destname)) continue;
-
- if (file_exist(destname,NULL)) {
- error = 183;
- continue;
- }
- if (!sys_rename(fname,destname)) count++;
- DEBUG(3,("reply_mv : doing rename on %s -> %s\n",fname,destname));
- }
- CloseDir(dirptr);
- }
- }
-
- if (count == 0) {
- if (exists)
- return(ERROR(ERRDOS,error));
- else
- {
- if((errno == ENOENT) && (bad_path1 || bad_path2))
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,error));
- }
- }
-
- outsize = set_message(outbuf,0,0,True);
-
- return(outsize);
-}
-
-/*******************************************************************
- copy a file as part of a reply_copy
- ******************************************************************/
-static BOOL copy_file(char *src,char *dest1,int cnum,int ofun,
- int count,BOOL target_is_directory)
-{
- int Access,action;
- struct stat st;
- int ret=0;
- int fnum1,fnum2;
- pstring dest;
-
- pstrcpy(dest,dest1);
- if (target_is_directory) {
- char *p = strrchr(src,'/');
- if (p)
- p++;
- else
- p = src;
- strcat(dest,"/");
- strcat(dest,p);
- }
-
- if (!file_exist(src,&st)) return(False);
-
- fnum1 = find_free_file();
- if (fnum1<0) return(False);
- open_file_shared(fnum1,cnum,src,(DENY_NONE<<4),
- 1,0,0,&Access,&action);
-
- if (!Files[fnum1].open) return(False);
-
- if (!target_is_directory && count)
- ofun = 1;
-
- fnum2 = find_free_file();
- if (fnum2<0) {
- close_file(fnum1);
- return(False);
- }
- open_file_shared(fnum2,cnum,dest,(DENY_NONE<<4)|1,
- ofun,st.st_mode,0,&Access,&action);
-
- if (!Files[fnum2].open) {
- close_file(fnum1);
- return(False);
- }
-
- if ((ofun&3) == 1) {
- lseek(Files[fnum2].fd_ptr->fd,0,SEEK_END);
- }
-
- if (st.st_size)
- ret = transfer_file(Files[fnum1].fd_ptr->fd,Files[fnum2].fd_ptr->fd,st.st_size,NULL,0,0);
-
- close_file(fnum1);
- close_file(fnum2);
-
- return(ret == st.st_size);
-}
-
-
-
-/****************************************************************************
- reply to a file copy.
- ****************************************************************************/
-int reply_copy(char *inbuf,char *outbuf)
-{
- int outsize = 0;
- pstring name;
- int cnum;
- pstring directory;
- pstring mask,newname;
- char *p;
- int count=0;
- int error = ERRnoaccess;
- BOOL has_wild;
- BOOL exists=False;
- int tid2 = SVAL(inbuf,smb_vwv0);
- int ofun = SVAL(inbuf,smb_vwv1);
- int flags = SVAL(inbuf,smb_vwv2);
- BOOL target_is_directory=False;
- BOOL bad_path1 = False;
- BOOL bad_path2 = False;
-
- *directory = *mask = 0;
-
- cnum = SVAL(inbuf,smb_tid);
-
- pstrcpy(name,smb_buf(inbuf));
- pstrcpy(newname,smb_buf(inbuf) + 1 + strlen(name));
-
- DEBUG(3,("reply_copy : %s -> %s\n",name,newname));
-
- if (tid2 != cnum) {
- /* can't currently handle inter share copies XXXX */
- DEBUG(3,("Rejecting inter-share copy\n"));
- return(ERROR(ERRSRV,ERRinvdevice));
- }
-
- unix_convert(name,cnum,0,&bad_path1);
- unix_convert(newname,cnum,0,&bad_path2);
-
- target_is_directory = directory_exist(newname,NULL);
-
- if ((flags&1) && target_is_directory) {
- return(ERROR(ERRDOS,ERRbadfile));
- }
-
- if ((flags&2) && !target_is_directory) {
- return(ERROR(ERRDOS,ERRbadpath));
- }
-
- if ((flags&(1<<5)) && directory_exist(name,NULL)) {
- /* wants a tree copy! XXXX */
- DEBUG(3,("Rejecting tree copy\n"));
- return(ERROR(ERRSRV,ERRerror));
- }
-
- p = strrchr(name,'/');
- if (!p) {
- strcpy(directory,"./");
- strcpy(mask,name);
- } else {
- *p = 0;
- strcpy(directory,name);
- strcpy(mask,p+1);
- }
-
- if (is_mangled(mask))
- check_mangled_stack(mask);
-
- has_wild = strchr(mask,'*') || strchr(mask,'?');
-
- if (!has_wild) {
- strcat(directory,"/");
- strcat(directory,mask);
- if (resolve_wildcards(directory,newname) &&
- copy_file(directory,newname,cnum,ofun,
- count,target_is_directory)) count++;
- if (!count) exists = file_exist(directory,NULL);
- } else {
- void *dirptr = NULL;
- char *dname;
- pstring destname;
-
- if (check_name(directory,cnum))
- dirptr = OpenDir(cnum, directory, True);
-
- if (dirptr)
- {
- error = ERRbadfile;
-
- if (strequal(mask,"????????.???"))
- strcpy(mask,"*");
-
- while ((dname = ReadDirName(dirptr)))
- {
- pstring fname;
- pstrcpy(fname,dname);
-
- if(!mask_match(fname, mask, case_sensitive, False)) continue;
-
- error = ERRnoaccess;
- sprintf(fname,"%s/%s",directory,dname);
- strcpy(destname,newname);
- if (resolve_wildcards(fname,destname) &&
- copy_file(directory,newname,cnum,ofun,
- count,target_is_directory)) count++;
- DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname,destname));
- }
- CloseDir(dirptr);
- }
- }
-
- if (count == 0) {
- if (exists)
- return(ERROR(ERRDOS,error));
- else
- {
- if((errno == ENOENT) && (bad_path1 || bad_path2))
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,error));
- }
- }
-
- outsize = set_message(outbuf,1,0,True);
- SSVAL(outbuf,smb_vwv0,count);
-
- return(outsize);
-}
-
-
-
-/****************************************************************************
- reply to a setdir
-****************************************************************************/
-int reply_setdir(char *inbuf,char *outbuf)
-{
- int cnum,snum;
- int outsize = 0;
- BOOL ok = False;
- pstring newdir;
-
- cnum = SVAL(inbuf,smb_tid);
-
- snum = Connections[cnum].service;
- if (!CAN_SETDIR(snum))
- return(ERROR(ERRDOS,ERRnoaccess));
-
- pstrcpy(newdir,smb_buf(inbuf) + 1);
- strlower(newdir);
-
- if (strlen(newdir) == 0)
- ok = True;
- else
- {
- ok = directory_exist(newdir,NULL);
- if (ok)
- string_set(&Connections[cnum].connectpath,newdir);
- }
-
- if (!ok)
- return(ERROR(ERRDOS,ERRbadpath));
-
- outsize = set_message(outbuf,0,0,True);
- CVAL(outbuf,smb_reh) = CVAL(inbuf,smb_reh);
-
- DEBUG(3,("%s setdir %s cnum=%d\n",timestring(),newdir,cnum));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a lockingX request
-****************************************************************************/
-int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize)
-{
- int fnum = GETFNUM(inbuf,smb_vwv2);
- unsigned char locktype = CVAL(inbuf,smb_vwv3);
-#if 0
- unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1);
-#endif
- uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
- uint16 num_locks = SVAL(inbuf,smb_vwv7);
- uint32 count, offset;
-
- int cnum;
- int i;
- char *data;
- uint32 ecode=0, dummy2;
- int eclass=0, dummy1;
-
- cnum = SVAL(inbuf,smb_tid);
-
- CHECK_FNUM(fnum,cnum);
- CHECK_ERROR(fnum);
-
- data = smb_buf(inbuf);
-
- /* Check if this is an oplock break on a file
- we have granted an oplock on.
- */
- if((locktype == LOCKING_ANDX_OPLOCK_RELEASE) &&
- (num_ulocks == 0) && (num_locks == 0) &&
- (CVAL(inbuf,smb_vwv0) == 0xFF))
- {
- share_lock_token token;
- files_struct *fsp = &Files[fnum];
- uint32 dev = fsp->fd_ptr->dev;
- uint32 inode = fsp->fd_ptr->inode;
-
- DEBUG(5,("reply_lockingX: oplock break reply from client for fnum = %d\n",
- fnum));
- /*
- * Make sure we have granted an oplock on this file.
- */
- if(!fsp->granted_oplock)
- {
- DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \
-no oplock granted on this file.\n", fnum));
- return ERROR(ERRDOS,ERRlock);
- }
-
- /* Remove the oplock flag from the sharemode. */
- lock_share_entry(fsp->cnum, dev, inode, &token);
- if(remove_share_oplock( fnum, token)==False)
- {
- DEBUG(0,("reply_lockingX: failed to remove share oplock for fnum %d, \
-dev = %x, inode = %x\n", fnum, dev, inode));
- unlock_share_entry(fsp->cnum, dev, inode, token);
- return -1;
- }
- unlock_share_entry(fsp->cnum, dev, inode, token);
-
- /* Clear the granted flag and return. */
-
- fsp->granted_oplock = False;
- return -1;
- }
-
- /* Data now points at the beginning of the list
- of smb_unlkrng structs */
- for(i = 0; i < (int)num_ulocks; i++) {
- count = IVAL(data,SMB_LKLEN_OFFSET(i));
- offset = IVAL(data,SMB_LKOFF_OFFSET(i));
- if(!do_unlock(fnum,cnum,count,offset,&eclass, &ecode))
- return ERROR(eclass,ecode);
- }
-
- /* Now do any requested locks */
- data += 10*num_ulocks;
- /* Data now points at the beginning of the list
- of smb_lkrng structs */
- for(i = 0; i < (int)num_locks; i++) {
- count = IVAL(data,SMB_LKLEN_OFFSET(i));
- offset = IVAL(data,SMB_LKOFF_OFFSET(i));
- if(!do_lock(fnum,cnum,count,offset, &eclass, &ecode))
- break;
- }
-
- /* If any of the above locks failed, then we must unlock
- all of the previous locks (X/Open spec). */
- if(i != num_locks && num_locks != 0) {
- for(; i >= 0; i--) {
- count = IVAL(data,SMB_LKLEN_OFFSET(i));
- offset = IVAL(data,SMB_LKOFF_OFFSET(i));
- do_unlock(fnum,cnum,count,offset,&dummy1,&dummy2);
- }
- return ERROR(eclass,ecode);
- }
-
- set_message(outbuf,2,0,True);
-
- DEBUG(3,("%s lockingX fnum=%d cnum=%d type=%d num_locks=%d num_ulocks=%d\n",
- timestring(),fnum,cnum,(unsigned int)locktype,num_locks,num_ulocks));
-
- chain_fnum = fnum;
-
- return chain_reply(inbuf,outbuf,length,bufsize);
-}
-
-
-/****************************************************************************
- reply to a SMBreadbmpx (read block multiplex) request
-****************************************************************************/
-int reply_readbmpx(char *inbuf,char *outbuf,int length,int bufsize)
-{
- int cnum,fnum;
- int nread = -1;
- int total_read;
- char *data;
- uint32 startpos;
- int outsize, mincount, maxcount;
- int max_per_packet;
- int tcount;
- int pad;
-
- /* this function doesn't seem to work - disable by default */
- if (!lp_readbmpx())
- return(ERROR(ERRSRV,ERRuseSTD));
-
- outsize = set_message(outbuf,8,0,True);
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- CHECK_FNUM(fnum,cnum);
- CHECK_READ(fnum);
- CHECK_ERROR(fnum);
-
- startpos = IVAL(inbuf,smb_vwv1);
- maxcount = SVAL(inbuf,smb_vwv3);
- mincount = SVAL(inbuf,smb_vwv4);
-
- data = smb_buf(outbuf);
- pad = ((long)data)%4;
- if (pad) pad = 4 - pad;
- data += pad;
-
- max_per_packet = bufsize-(outsize+pad);
- tcount = maxcount;
- total_read = 0;
-
- if (is_locked(fnum,cnum,maxcount,startpos))
- return(ERROR(ERRDOS,ERRlock));
-
- do
- {
- int N = MIN(max_per_packet,tcount-total_read);
-
- nread = read_file(fnum,data,startpos,N);
-
- if (nread <= 0) nread = 0;
-
- if (nread < N)
- tcount = total_read + nread;
-
- set_message(outbuf,8,nread,False);
- SIVAL(outbuf,smb_vwv0,startpos);
- SSVAL(outbuf,smb_vwv2,tcount);
- SSVAL(outbuf,smb_vwv6,nread);
- SSVAL(outbuf,smb_vwv7,smb_offset(data,outbuf));
-
- send_smb(Client,outbuf);
-
- total_read += nread;
- startpos += nread;
- }
- while (total_read < tcount);
-
- return(-1);
-}
-
-
-/****************************************************************************
- reply to a SMBwritebmpx (write block multiplex primary) request
-****************************************************************************/
-int reply_writebmpx(char *inbuf,char *outbuf)
-{
- int cnum,numtowrite,fnum;
- int nwritten = -1;
- int outsize = 0;
- uint32 startpos;
- int tcount, write_through, smb_doff;
- char *data;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- CHECK_FNUM(fnum,cnum);
- CHECK_WRITE(fnum);
- CHECK_ERROR(fnum);
-
- tcount = SVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv3);
- write_through = BITSETW(inbuf+smb_vwv7,0);
- numtowrite = SVAL(inbuf,smb_vwv10);
- smb_doff = SVAL(inbuf,smb_vwv11);
-
- data = smb_base(inbuf) + smb_doff;
-
- /* If this fails we need to send an SMBwriteC response,
- not an SMBwritebmpx - set this up now so we don't forget */
- CVAL(outbuf,smb_com) = SMBwritec;
-
- if (is_locked(fnum,cnum,tcount,startpos))
- return(ERROR(ERRDOS,ERRlock));
-
- seek_file(fnum,startpos);
- nwritten = write_file(fnum,data,numtowrite);
-
- if(lp_syncalways(SNUM(cnum)) || write_through)
- sync_file(fnum);
-
- if(nwritten < numtowrite)
- return(UNIXERROR(ERRHRD,ERRdiskfull));
-
- /* If the maximum to be written to this file
- is greater than what we just wrote then set
- up a secondary struct to be attached to this
- fd, we will use this to cache error messages etc. */
- if(tcount > nwritten)
- {
- write_bmpx_struct *wbms;
- if(Files[fnum].wbmpx_ptr != NULL)
- wbms = Files[fnum].wbmpx_ptr; /* Use an existing struct */
- else
- wbms = (write_bmpx_struct *)malloc(sizeof(write_bmpx_struct));
- if(!wbms)
- {
- DEBUG(0,("Out of memory in reply_readmpx\n"));
- return(ERROR(ERRSRV,ERRnoresource));
- }
- wbms->wr_mode = write_through;
- wbms->wr_discard = False; /* No errors yet */
- wbms->wr_total_written = nwritten;
- wbms->wr_errclass = 0;
- wbms->wr_error = 0;
- Files[fnum].wbmpx_ptr = wbms;
- }
-
- /* We are returning successfully, set the message type back to
- SMBwritebmpx */
- CVAL(outbuf,smb_com) = SMBwriteBmpx;
-
- outsize = set_message(outbuf,1,0,True);
-
- SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */
-
- DEBUG(3,("%s writebmpx fnum=%d cnum=%d num=%d wrote=%d\n",
- timestring(),fnum,cnum,numtowrite,nwritten));
-
- if (write_through && tcount==nwritten) {
- /* we need to send both a primary and a secondary response */
- smb_setlen(outbuf,outsize - 4);
- send_smb(Client,outbuf);
-
- /* now the secondary */
- outsize = set_message(outbuf,1,0,True);
- CVAL(outbuf,smb_com) = SMBwritec;
- SSVAL(outbuf,smb_vwv0,nwritten);
- }
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a SMBwritebs (write block multiplex secondary) request
-****************************************************************************/
-int reply_writebs(char *inbuf,char *outbuf)
-{
- int cnum,numtowrite,fnum;
- int nwritten = -1;
- int outsize = 0;
- int32 startpos;
- int tcount, write_through, smb_doff;
- char *data;
- write_bmpx_struct *wbms;
- BOOL send_response = False;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
- CHECK_FNUM(fnum,cnum);
- CHECK_WRITE(fnum);
-
- tcount = SVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv2);
- numtowrite = SVAL(inbuf,smb_vwv6);
- smb_doff = SVAL(inbuf,smb_vwv7);
-
- data = smb_base(inbuf) + smb_doff;
-
- /* We need to send an SMBwriteC response, not an SMBwritebs */
- CVAL(outbuf,smb_com) = SMBwritec;
-
- /* This fd should have an auxiliary struct attached,
- check that it does */
- wbms = Files[fnum].wbmpx_ptr;
- if(!wbms) return(-1);
-
- /* If write through is set we can return errors, else we must
- cache them */
- write_through = wbms->wr_mode;
-
- /* Check for an earlier error */
- if(wbms->wr_discard)
- return -1; /* Just discard the packet */
-
- seek_file(fnum,startpos);
- nwritten = write_file(fnum,data,numtowrite);
-
- if(lp_syncalways(SNUM(cnum)) || write_through)
- sync_file(fnum);
-
- if (nwritten < numtowrite)
- {
- if(write_through) {
- /* We are returning an error - we can delete the aux struct */
- if (wbms) free((char *)wbms);
- Files[fnum].wbmpx_ptr = NULL;
- return(ERROR(ERRHRD,ERRdiskfull));
- }
- return(CACHE_ERROR(wbms,ERRHRD,ERRdiskfull));
- }
-
- /* Increment the total written, if this matches tcount
- we can discard the auxiliary struct (hurrah !) and return a writeC */
- wbms->wr_total_written += nwritten;
- if(wbms->wr_total_written >= tcount)
- {
- if (write_through) {
- outsize = set_message(outbuf,1,0,True);
- SSVAL(outbuf,smb_vwv0,wbms->wr_total_written);
- send_response = True;
- }
-
- free((char *)wbms);
- Files[fnum].wbmpx_ptr = NULL;
- }
-
- if(send_response)
- return(outsize);
-
- return(-1);
-}
-
-
-/****************************************************************************
- reply to a SMBsetattrE
-****************************************************************************/
-int reply_setattrE(char *inbuf,char *outbuf)
-{
- int cnum,fnum;
- struct utimbuf unix_times;
- int outsize = 0;
-
- outsize = set_message(outbuf,0,0,True);
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- CHECK_FNUM(fnum,cnum);
- CHECK_ERROR(fnum);
-
- /* Convert the DOS times into unix times. Ignore create
- time as UNIX can't set this.
- */
- unix_times.actime = make_unix_date2(inbuf+smb_vwv3);
- unix_times.modtime = make_unix_date2(inbuf+smb_vwv5);
-
- /*
- * Patch from Ray Frush <frush@engr.colostate.edu>
- * Sometimes times are sent as zero - ignore them.
- */
-
- if ((unix_times.actime == 0) && (unix_times.modtime == 0))
- {
- /* Ignore request */
- DEBUG(3,("%s reply_setattrE fnum=%d cnum=%d ignoring zero request - \
-not setting timestamps of 0\n",
- timestring(), fnum,cnum,unix_times.actime,unix_times.modtime));
- return(outsize);
- }
- else if ((unix_times.actime != 0) && (unix_times.modtime == 0))
- {
- /* set modify time = to access time if modify time was 0 */
- unix_times.modtime = unix_times.actime;
- }
-
- /* Set the date on this file */
- if(sys_utime(Files[fnum].name, &unix_times))
- return(ERROR(ERRDOS,ERRnoaccess));
-
- DEBUG(3,("%s reply_setattrE fnum=%d cnum=%d actime=%d modtime=%d\n",
- timestring(), fnum,cnum,unix_times.actime,unix_times.modtime));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a SMBgetattrE
-****************************************************************************/
-int reply_getattrE(char *inbuf,char *outbuf)
-{
- int cnum,fnum;
- struct stat sbuf;
- int outsize = 0;
- int mode;
-
- outsize = set_message(outbuf,11,0,True);
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- CHECK_FNUM(fnum,cnum);
- CHECK_ERROR(fnum);
-
- /* Do an fstat on this file */
- if(fstat(Files[fnum].fd_ptr->fd, &sbuf))
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- mode = dos_mode(cnum,Files[fnum].name,&sbuf);
-
- /* Convert the times into dos times. Set create
- date to be last modify date as UNIX doesn't save
- this */
- put_dos_date2(outbuf,smb_vwv0,sbuf.st_mtime);
- put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime);
- put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime);
- if (mode & aDIR)
- {
- SIVAL(outbuf,smb_vwv6,0);
- SIVAL(outbuf,smb_vwv8,0);
- }
- else
- {
- SIVAL(outbuf,smb_vwv6,sbuf.st_size);
- SIVAL(outbuf,smb_vwv8,ROUNDUP(sbuf.st_size,1024));
- }
- SSVAL(outbuf,smb_vwv10, mode);
-
- DEBUG(3,("%s reply_getattrE fnum=%d cnum=%d\n",timestring(),fnum,cnum));
-
- return(outsize);
-}
diff --git a/source/smbd/server.c b/source/smbd/server.c
deleted file mode 100644
index d387b7375bb..00000000000
--- a/source/smbd/server.c
+++ /dev/null
@@ -1,5024 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Main SMB server routines
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-
-#include "includes.h"
-#include "trans2.h"
-
-pstring servicesf = CONFIGFILE;
-extern pstring debugf;
-extern pstring sesssetup_user;
-extern fstring myworkgroup;
-
-char *InBuffer = NULL;
-char *OutBuffer = NULL;
-char *last_inbuf = NULL;
-
-int am_parent = 1;
-int atexit_set = 0;
-
-/* the last message the was processed */
-int last_message = -1;
-
-/* a useful macro to debug the last message processed */
-#define LAST_MESSAGE() smb_fn_name(last_message)
-
-extern pstring scope;
-extern int DEBUGLEVEL;
-extern int case_default;
-extern BOOL case_sensitive;
-extern BOOL case_preserve;
-extern BOOL use_mangled_map;
-extern BOOL short_case_preserve;
-extern BOOL case_mangle;
-extern time_t smb_last_time;
-
-extern int smb_read_error;
-
-extern pstring user_socket_options;
-
-connection_struct Connections[MAX_CONNECTIONS];
-files_struct Files[MAX_OPEN_FILES];
-
-/*
- * Indirection for file fd's. Needed as POSIX locking
- * is based on file/process, not fd/process.
- */
-file_fd_struct FileFd[MAX_OPEN_FILES];
-int max_file_fd_used = 0;
-
-extern int Protocol;
-
-/*
- * Size of data we can send to client. Set
- * by the client for all protocols above CORE.
- * Set by us for CORE protocol.
- */
-int max_send = BUFFER_SIZE;
-/*
- * Size of the data we can receive. Set by us.
- * Can be modified by the max xmit parameter.
- */
-int max_recv = BUFFER_SIZE;
-
-/* a fnum to use when chaining */
-int chain_fnum = -1;
-
-/* number of open connections */
-static int num_connections_open = 0;
-
-/* Oplock ipc UDP socket. */
-int oplock_sock = -1;
-uint16 oplock_port = 0;
-/* Current number of oplocks we have outstanding. */
-int32 global_oplocks_open = 0;
-
-BOOL global_oplock_break = False;
-
-extern fstring remote_machine;
-
-pstring OriginalDir;
-
-/* these can be set by some functions to override the error codes */
-int unix_ERR_class=SUCCESS;
-int unix_ERR_code=0;
-
-
-extern int extra_time_offset;
-
-extern pstring myhostname;
-
-static int find_free_connection(int hash);
-
-/* for readability... */
-#define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
-#define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
-#define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
-#define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
-#define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
-
-/****************************************************************************
- when exiting, take the whole family
-****************************************************************************/
-void *dflt_sig(void)
-{
- exit_server("caught signal");
- return 0; /* Keep -Wall happy :-) */
-}
-/****************************************************************************
- Send a SIGTERM to our process group.
-*****************************************************************************/
-void killkids(void)
-{
- if(am_parent) kill(0,SIGTERM);
-}
-
-/****************************************************************************
- change a dos mode to a unix mode
- base permission for files:
- everybody gets read bit set
- dos readonly is represented in unix by removing everyone's write bit
- dos archive is represented in unix by the user's execute bit
- dos system is represented in unix by the group's execute bit
- dos hidden is represented in unix by the other's execute bit
- Then apply create mask,
- then add force bits.
- base permission for directories:
- dos directory is represented in unix by unix's dir bit and the exec bit
- Then apply create mask,
- then add force bits.
-****************************************************************************/
-mode_t unix_mode(int cnum,int dosmode)
-{
- mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
-
- if ( !IS_DOS_READONLY(dosmode) )
- result |= (S_IWUSR | S_IWGRP | S_IWOTH);
-
- if (IS_DOS_DIR(dosmode)) {
- /* We never make directories read only for the owner as under DOS a user
- can always create a file in a read-only directory. */
- result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
- /* Apply directory mask */
- result &= lp_dir_mode(SNUM(cnum));
- /* Add in force bits */
- result |= lp_force_dir_mode(SNUM(cnum));
- } else {
- if (MAP_ARCHIVE(cnum) && IS_DOS_ARCHIVE(dosmode))
- result |= S_IXUSR;
-
- if (MAP_SYSTEM(cnum) && IS_DOS_SYSTEM(dosmode))
- result |= S_IXGRP;
-
- if (MAP_HIDDEN(cnum) && IS_DOS_HIDDEN(dosmode))
- result |= S_IXOTH;
-
- /* Apply mode mask */
- result &= lp_create_mode(SNUM(cnum));
- /* Add in force bits */
- result |= lp_force_create_mode(SNUM(cnum));
- }
- return(result);
-}
-
-
-/****************************************************************************
- change a unix mode to a dos mode
-****************************************************************************/
-int dos_mode(int cnum,char *path,struct stat *sbuf)
-{
- int result = 0;
- extern struct current_user current_user;
-
- DEBUG(8,("dos_mode: %d %s\n", cnum, path));
-
- if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) {
- if (!((sbuf->st_mode & S_IWOTH) ||
- Connections[cnum].admin_user ||
- ((sbuf->st_mode & S_IWUSR) && current_user.uid==sbuf->st_uid) ||
- ((sbuf->st_mode & S_IWGRP) &&
- in_group(sbuf->st_gid,current_user.gid,
- current_user.ngroups,current_user.igroups))))
- result |= aRONLY;
- } else {
- if ((sbuf->st_mode & S_IWUSR) == 0)
- result |= aRONLY;
- }
-
- if (MAP_ARCHIVE(cnum) && ((sbuf->st_mode & S_IXUSR) != 0))
- result |= aARCH;
-
- if (MAP_SYSTEM(cnum) && ((sbuf->st_mode & S_IXGRP) != 0))
- result |= aSYSTEM;
-
- if (MAP_HIDDEN(cnum) && ((sbuf->st_mode & S_IXOTH) != 0))
- result |= aHIDDEN;
-
- if (S_ISDIR(sbuf->st_mode))
- result = aDIR | (result & aRONLY);
-
-#ifdef S_ISLNK
-#if LINKS_READ_ONLY
- if (S_ISLNK(sbuf->st_mode) && S_ISDIR(sbuf->st_mode))
- result |= aRONLY;
-#endif
-#endif
-
- /* hide files with a name starting with a . */
- if (lp_hide_dot_files(SNUM(cnum)))
- {
- char *p = strrchr(path,'/');
- if (p)
- p++;
- else
- p = path;
-
- if (p[0] == '.' && p[1] != '.' && p[1] != 0)
- result |= aHIDDEN;
- }
-
- /* Optimization : Only call is_hidden_path if it's not already
- hidden. */
- if (!(result & aHIDDEN) && IS_HIDDEN_PATH(cnum,path))
- {
- result |= aHIDDEN;
- }
-
- DEBUG(8,("dos_mode returning "));
-
- if (result & aHIDDEN) DEBUG(8, ("h"));
- if (result & aRONLY ) DEBUG(8, ("r"));
- if (result & aSYSTEM) DEBUG(8, ("s"));
- if (result & aDIR ) DEBUG(8, ("d"));
- if (result & aARCH ) DEBUG(8, ("a"));
-
- DEBUG(8,("\n"));
-
- return(result);
-}
-
-
-/*******************************************************************
-chmod a file - but preserve some bits
-********************************************************************/
-int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st)
-{
- struct stat st1;
- int mask=0;
- int tmp;
- int unixmode;
-
- if (!st) {
- st = &st1;
- if (sys_stat(fname,st)) return(-1);
- }
-
- if (S_ISDIR(st->st_mode)) dosmode |= aDIR;
-
- if (dos_mode(cnum,fname,st) == dosmode) return(0);
-
- unixmode = unix_mode(cnum,dosmode);
-
- /* preserve the s bits */
- mask |= (S_ISUID | S_ISGID);
-
- /* preserve the t bit */
-#ifdef S_ISVTX
- mask |= S_ISVTX;
-#endif
-
- /* possibly preserve the x bits */
- if (!MAP_ARCHIVE(cnum)) mask |= S_IXUSR;
- if (!MAP_SYSTEM(cnum)) mask |= S_IXGRP;
- if (!MAP_HIDDEN(cnum)) mask |= S_IXOTH;
-
- unixmode |= (st->st_mode & mask);
-
- /* if we previously had any r bits set then leave them alone */
- if ((tmp = st->st_mode & (S_IRUSR|S_IRGRP|S_IROTH))) {
- unixmode &= ~(S_IRUSR|S_IRGRP|S_IROTH);
- unixmode |= tmp;
- }
-
- /* if we previously had any w bits set then leave them alone
- if the new mode is not rdonly */
- if (!IS_DOS_READONLY(dosmode) &&
- (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
- unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
- unixmode |= tmp;
- }
-
- return(sys_chmod(fname,unixmode));
-}
-
-
-/****************************************************************************
-check if two filenames are equal
-
-this needs to be careful about whether we are case sensitive
-****************************************************************************/
-static BOOL fname_equal(char *name1, char *name2)
-{
- int l1 = strlen(name1);
- int l2 = strlen(name2);
-
- /* handle filenames ending in a single dot */
- if (l1-l2 == 1 && name1[l1-1] == '.' && lp_strip_dot())
- {
- BOOL ret;
- name1[l1-1] = 0;
- ret = fname_equal(name1,name2);
- name1[l1-1] = '.';
- return(ret);
- }
-
- if (l2-l1 == 1 && name2[l2-1] == '.' && lp_strip_dot())
- {
- BOOL ret;
- name2[l2-1] = 0;
- ret = fname_equal(name1,name2);
- name2[l2-1] = '.';
- return(ret);
- }
-
- /* now normal filename handling */
- if (case_sensitive)
- return(strcmp(name1,name2) == 0);
-
- return(strequal(name1,name2));
-}
-
-
-/****************************************************************************
-mangle the 2nd name and check if it is then equal to the first name
-****************************************************************************/
-static BOOL mangled_equal(char *name1, char *name2)
-{
- pstring tmpname;
-
- if (is_8_3(name2, True))
- return(False);
-
- strcpy(tmpname,name2);
- mangle_name_83(tmpname);
-
- return(strequal(name1,tmpname));
-}
-
-
-/****************************************************************************
-scan a directory to find a filename, matching without case sensitivity
-
-If the name looks like a mangled name then try via the mangling functions
-****************************************************************************/
-static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache)
-{
- void *cur_dir;
- char *dname;
- BOOL mangled;
- pstring name2;
-
- mangled = is_mangled(name);
-
- /* handle null paths */
- if (*path == 0)
- path = ".";
-
- if (docache && (dname = DirCacheCheck(path,name,SNUM(cnum)))) {
- strcpy(name, dname);
- return(True);
- }
-
- if (mangled)
- check_mangled_stack(name);
-
- /* open the directory */
- if (!(cur_dir = OpenDir(cnum, path, True)))
- {
- DEBUG(3,("scan dir didn't open dir [%s]\n",path));
- return(False);
- }
-
- /* now scan for matching names */
- while ((dname = ReadDirName(cur_dir)))
- {
- if (*dname == '.' &&
- (strequal(dname,".") || strequal(dname,"..")))
- continue;
-
- pstrcpy(name2,dname);
- if (!name_map_mangle(name2,False,SNUM(cnum))) continue;
-
- if ((mangled && mangled_equal(name,name2))
- || fname_equal(name, name2)) /* name2 here was changed to dname - since 1.9.16p2 - not sure of reason (jra) */
- {
- /* we've found the file, change it's name and return */
- if (docache) DirCacheAdd(path,name,dname,SNUM(cnum));
- strcpy(name, dname);
- CloseDir(cur_dir);
- return(True);
- }
- }
-
- CloseDir(cur_dir);
- return(False);
-}
-
-/****************************************************************************
-This routine is called to convert names from the dos namespace to unix
-namespace. It needs to handle any case conversions, mangling, format
-changes etc.
-
-We assume that we have already done a chdir() to the right "root" directory
-for this service.
-
-The function will return False if some part of the name except for the last
-part cannot be resolved
-
-If the saved_last_component != 0, then the unmodified last component
-of the pathname is returned there. This is used in an exceptional
-case in reply_mv (so far). If saved_last_component == 0 then nothing
-is returned there.
-
-The bad_path arg is set to True if the filename walk failed. This is
-used to pick the correct error code to return between ENOENT and ENOTDIR
-as Windows applications depend on ERRbadpath being returned if a component
-of a pathname does not exist.
-****************************************************************************/
-BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_path)
-{
- struct stat st;
- char *start, *end;
- pstring dirpath;
- int saved_errno;
-
- *dirpath = 0;
- *bad_path = False;
-
- if(saved_last_component)
- *saved_last_component = 0;
-
- /* convert to basic unix format - removing \ chars and cleaning it up */
- unix_format(name);
- unix_clean_name(name);
-
- /* names must be relative to the root of the service - trim any leading /.
- also trim trailing /'s */
- trim_string(name,"/","/");
-
- /*
- * Ensure saved_last_component is valid even if file exists.
- */
- if(saved_last_component) {
- end = strrchr(name, '/');
- if(end)
- strcpy(saved_last_component, end + 1);
- else
- strcpy(saved_last_component, name);
- }
-
- if (!case_sensitive &&
- (!case_preserve || (is_8_3(name, False) && !short_case_preserve)))
- strnorm(name);
-
- /* check if it's a printer file */
- if (Connections[cnum].printer)
- {
- if ((! *name) || strchr(name,'/') || !is_8_3(name, True))
- {
- char *s;
- fstring name2;
- sprintf(name2,"%.6s.XXXXXX",remote_machine);
- /* sanitise the name */
- for (s=name2 ; *s ; s++)
- if (!issafe(*s)) *s = '_';
- strcpy(name,(char *)mktemp(name2));
- }
- return(True);
- }
-
- /* stat the name - if it exists then we are all done! */
- if (sys_stat(name,&st) == 0)
- return(True);
-
- saved_errno = errno;
-
- DEBUG(5,("unix_convert(%s,%d)\n",name,cnum));
-
- /* a special case - if we don't have any mangling chars and are case
- sensitive then searching won't help */
- if (case_sensitive && !is_mangled(name) &&
- !lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT))
- return(False);
-
- /* now we need to recursively match the name against the real
- directory structure */
-
- start = name;
- while (strncmp(start,"./",2) == 0)
- start += 2;
-
- /* now match each part of the path name separately, trying the names
- as is first, then trying to scan the directory for matching names */
- for (;start;start = (end?end+1:(char *)NULL))
- {
- /* pinpoint the end of this section of the filename */
- end = strchr(start, '/');
-
- /* chop the name at this point */
- if (end) *end = 0;
-
- if(saved_last_component != 0)
- strcpy(saved_last_component, end ? end + 1 : start);
-
- /* check if the name exists up to this point */
- if (sys_stat(name, &st) == 0)
- {
- /* it exists. it must either be a directory or this must be
- the last part of the path for it to be OK */
- if (end && !(st.st_mode & S_IFDIR))
- {
- /* an intermediate part of the name isn't a directory */
- DEBUG(5,("Not a dir %s\n",start));
- *end = '/';
- return(False);
- }
- }
- else
- {
- pstring rest;
-
- *rest = 0;
-
- /* remember the rest of the pathname so it can be restored
- later */
- if (end) pstrcpy(rest,end+1);
-
- /* try to find this part of the path in the directory */
- if (strchr(start,'?') || strchr(start,'*') ||
- !scan_directory(dirpath, start, cnum, end?True:False))
- {
- if (end)
- {
- /* an intermediate part of the name can't be found */
- DEBUG(5,("Intermediate not found %s\n",start));
- *end = '/';
- /* We need to return the fact that the intermediate
- name resolution failed. This is used to return an
- error of ERRbadpath rather than ERRbadfile. Some
- Windows applications depend on the difference between
- these two errors.
- */
- *bad_path = True;
- return(False);
- }
-
- /* just the last part of the name doesn't exist */
- /* we may need to strupper() or strlower() it in case
- this conversion is being used for file creation
- purposes */
- /* if the filename is of mixed case then don't normalise it */
- if (!case_preserve &&
- (!strhasupper(start) || !strhaslower(start)))
- strnorm(start);
-
- /* check on the mangled stack to see if we can recover the
- base of the filename */
- if (is_mangled(start))
- check_mangled_stack(start);
-
- DEBUG(5,("New file %s\n",start));
- return(True);
- }
-
- /* restore the rest of the string */
- if (end)
- {
- strcpy(start+strlen(start)+1,rest);
- end = start + strlen(start);
- }
- }
-
- /* add to the dirpath that we have resolved so far */
- if (*dirpath) strcat(dirpath,"/");
- strcat(dirpath,start);
-
- /* restore the / that we wiped out earlier */
- if (end) *end = '/';
- }
-
- /* the name has been resolved */
- DEBUG(5,("conversion finished %s\n",name));
- return(True);
-}
-
-
-/****************************************************************************
-normalise for DOS usage
-****************************************************************************/
-static void disk_norm(int *bsize,int *dfree,int *dsize)
-{
- /* check if the disk is beyond the max disk size */
- int maxdisksize = lp_maxdisksize();
- if (maxdisksize) {
- /* convert to blocks - and don't overflow */
- maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
- if (*dsize > maxdisksize) *dsize = maxdisksize;
- if (*dfree > maxdisksize) *dfree = maxdisksize-1; /* the -1 should stop
- applications getting
- div by 0 errors */
- }
-
- while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512)
- {
- *dfree /= 2;
- *dsize /= 2;
- *bsize *= 2;
- if (*bsize > WORDMAX )
- {
- *bsize = WORDMAX;
- if (*dsize > WORDMAX)
- *dsize = WORDMAX;
- if (*dfree > WORDMAX)
- *dfree = WORDMAX;
- break;
- }
- }
-}
-
-/****************************************************************************
- return number of 1K blocks available on a path and total number
-****************************************************************************/
-int disk_free(char *path,int *bsize,int *dfree,int *dsize)
-{
- char *df_command = lp_dfree_command();
- int dfree_retval;
-#ifdef QUOTAS
- int dfreeq_retval;
- int dfreeq = 0;
- int bsizeq = *bsize;
- int dsizeq = *dsize;
-#endif
-
-#ifndef NO_STATFS
-#ifdef USE_STATVFS
- struct statvfs fs;
-#else
-#ifdef ULTRIX
- struct fs_data fs;
-#else
- struct statfs fs;
-#endif
-#endif
-#endif
-
- /* possibly use system() to get the result */
- if (df_command && *df_command)
- {
- int ret;
- pstring syscmd;
- pstring outfile;
-
- sprintf(outfile,"%s/dfree.smb.%d",tmpdir(),(int)getpid());
- sprintf(syscmd,"%s %s",df_command,path);
- standard_sub_basic(syscmd);
-
- ret = smbrun(syscmd,outfile,False);
- DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
-
- {
- FILE *f = fopen(outfile,"r");
- *dsize = 0;
- *dfree = 0;
- *bsize = 1024;
- if (f)
- {
- fscanf(f,"%d %d %d",dsize,dfree,bsize);
- fclose(f);
- }
- else
- DEBUG(0,("Can't open %s\n",outfile));
- }
-
- unlink(outfile);
- disk_norm(bsize,dfree,dsize);
- dfree_retval = ((*bsize)/1024)*(*dfree);
-#ifdef QUOTAS
- /* Ensure we return the min value between the users quota and
- what's free on the disk. Thanks to Albrecht Gebhardt
- <albrecht.gebhardt@uni-klu.ac.at> for this fix.
- */
- if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
- {
- disk_norm(&bsizeq, &dfreeq, &dsizeq);
- dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
- dfree_retval = ( dfree_retval < dfreeq_retval ) ?
- dfree_retval : dfreeq_retval ;
- /* maybe dfree and dfreeq are calculated using different bsizes
- so convert dfree from bsize into bsizeq */
- /* avoid overflows due to multiplication, so do not:
- *dfree = ((*dfree) * (*bsize)) / (bsizeq);
- bsize and bsizeq are powers of 2 so its better to
- to divide them getting a multiplication or division factor
- for dfree. Rene Nieuwenhuizen (07-10-1997) */
- if (*bsize >= bsizeq)
- *dfree = *dfree * (*bsize / bsizeq);
- else
- *dfree = *dfree / (bsizeq / *bsize);
- *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
- *bsize = bsizeq;
- *dsize = dsizeq;
- }
-#endif
- return(dfree_retval);
- }
-
-#ifdef NO_STATFS
- DEBUG(1,("Warning - no statfs function\n"));
- return(1);
-#else
-#ifdef STATFS4
- if (statfs(path,&fs,sizeof(fs),0) != 0)
-#else
-#ifdef USE_STATVFS
- if (statvfs(path, &fs))
-#else
-#ifdef STATFS3
- if (statfs(path,&fs,sizeof(fs)) == -1)
-#else
- if (statfs(path,&fs) == -1)
-#endif /* STATFS3 */
-#endif /* USE_STATVFS */
-#endif /* STATFS4 */
- {
- DEBUG(3,("dfree call failed code errno=%d\n",errno));
- *bsize = 1024;
- *dfree = 1;
- *dsize = 1;
- return(((*bsize)/1024)*(*dfree));
- }
-
-#ifdef ULTRIX
- *bsize = 1024;
- *dfree = fs.fd_req.bfree;
- *dsize = fs.fd_req.btot;
-#else
-#ifdef USE_STATVFS
- *bsize = fs.f_frsize;
-#else
-#ifdef USE_F_FSIZE
- /* eg: osf1 has f_fsize = fundamental filesystem block size,
- f_bsize = optimal transfer block size (MX: 94-04-19) */
- *bsize = fs.f_fsize;
-#else
- *bsize = fs.f_bsize;
-#endif /* STATFS3 */
-#endif /* USE_STATVFS */
-
-#ifdef STATFS4
- *dfree = fs.f_bfree;
-#else
- *dfree = fs.f_bavail;
-#endif /* STATFS4 */
- *dsize = fs.f_blocks;
-#endif /* ULTRIX */
-
-#if defined(SCO) || defined(ISC) || defined(MIPS)
- *bsize = 512;
-#endif
-
-/* handle rediculous bsize values - some OSes are broken */
-if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024;
-
- disk_norm(bsize,dfree,dsize);
-
- if (*bsize < 256)
- *bsize = 512;
- if ((*dsize)<1)
- {
- DEBUG(0,("dfree seems to be broken on your system\n"));
- *dsize = 20*1024*1024/(*bsize);
- *dfree = MAX(1,*dfree);
- }
- dfree_retval = ((*bsize)/1024)*(*dfree);
-#ifdef QUOTAS
- /* Ensure we return the min value between the users quota and
- what's free on the disk. Thanks to Albrecht Gebhardt
- <albrecht.gebhardt@uni-klu.ac.at> for this fix.
- */
- if (disk_quotas(path, &bsizeq, &dfreeq, &dsizeq))
- {
- disk_norm(&bsizeq, &dfreeq, &dsizeq);
- dfreeq_retval = ((bsizeq)/1024)*(dfreeq);
- dfree_retval = ( dfree_retval < dfreeq_retval ) ?
- dfree_retval : dfreeq_retval ;
- /* maybe dfree and dfreeq are calculated using different bsizes
- so convert dfree from bsize into bsizeq */
- /* avoid overflows due to multiplication, so do not:
- *dfree = ((*dfree) * (*bsize)) / (bsizeq);
- bsize and bsizeq are powers of 2 so its better to
- to divide them getting a multiplication or division factor
- for dfree. Rene Nieuwenhuizen (07-10-1997) */
- if (*bsize >= bsizeq)
- *dfree = *dfree * (*bsize / bsizeq);
- else
- *dfree = *dfree / (bsizeq / *bsize);
- *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ;
- *bsize = bsizeq;
- *dsize = dsizeq;
- }
-#endif
- return(dfree_retval);
-#endif
-}
-
-
-/****************************************************************************
-wrap it to get filenames right
-****************************************************************************/
-int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize)
-{
- return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
-}
-
-
-
-/****************************************************************************
-check a filename - possibly caling reducename
-
-This is called by every routine before it allows an operation on a filename.
-It does any final confirmation necessary to ensure that the filename is
-a valid one for the user to access.
-****************************************************************************/
-BOOL check_name(char *name,int cnum)
-{
- BOOL ret;
-
- errno = 0;
-
- if( IS_VETO_PATH(cnum, name))
- {
- DEBUG(5,("file path name %s vetoed\n",name));
- return(0);
- }
-
- ret = reduce_name(name,Connections[cnum].connectpath,lp_widelinks(SNUM(cnum)));
-
- /* Check if we are allowing users to follow symlinks */
- /* Patch from David Clerc <David.Clerc@cui.unige.ch>
- University of Geneva */
-
-#ifdef S_ISLNK
- if (!lp_symlinks(SNUM(cnum)))
- {
- struct stat statbuf;
- if ( (sys_lstat(name,&statbuf) != -1) &&
- (S_ISLNK(statbuf.st_mode)) )
- {
- DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
- ret=0;
- }
- }
-#endif
-
- if (!ret)
- DEBUG(5,("check_name on %s failed\n",name));
-
- return(ret);
-}
-
-/****************************************************************************
-check a filename - possibly caling reducename
-****************************************************************************/
-static void check_for_pipe(char *fname)
-{
- /* special case of pipe opens */
- char s[10];
- StrnCpy(s,fname,9);
- strlower(s);
- if (strstr(s,"pipe/"))
- {
- DEBUG(3,("Rejecting named pipe open for %s\n",fname));
- unix_ERR_class = ERRSRV;
- unix_ERR_code = ERRaccess;
- }
-}
-
-/****************************************************************************
-fd support routines - attempt to do a sys_open
-****************************************************************************/
-static int fd_attempt_open(char *fname, int flags, int mode)
-{
- int fd = sys_open(fname,flags,mode);
-
- /* Fix for files ending in '.' */
- if((fd == -1) && (errno == ENOENT) &&
- (strchr(fname,'.')==NULL))
- {
- strcat(fname,".");
- fd = sys_open(fname,flags,mode);
- }
-
-#if (defined(ENAMETOOLONG) && defined(HAVE_PATHCONF))
- if ((fd == -1) && (errno == ENAMETOOLONG))
- {
- int max_len;
- char *p = strrchr(fname, '/');
-
- if (p == fname) /* name is "/xxx" */
- {
- max_len = pathconf("/", _PC_NAME_MAX);
- p++;
- }
- else if ((p == NULL) || (p == fname))
- {
- p = fname;
- max_len = pathconf(".", _PC_NAME_MAX);
- }
- else
- {
- *p = '\0';
- max_len = pathconf(fname, _PC_NAME_MAX);
- *p = '/';
- p++;
- }
- if (strlen(p) > max_len)
- {
- char tmp = p[max_len];
-
- p[max_len] = '\0';
- if ((fd = sys_open(fname,flags,mode)) == -1)
- p[max_len] = tmp;
- }
- }
-#endif
- return fd;
-}
-
-/****************************************************************************
-fd support routines - attempt to find an already open file by dev
-and inode - increments the ref_count of the returned file_fd_struct *.
-****************************************************************************/
-static file_fd_struct *fd_get_already_open(struct stat *sbuf)
-{
- int i;
- file_fd_struct *fd_ptr;
-
- if(sbuf == 0)
- return 0;
-
- for(i = 0; i <= max_file_fd_used; i++) {
- fd_ptr = &FileFd[i];
- if((fd_ptr->ref_count > 0) &&
- (((uint32)sbuf->st_dev) == fd_ptr->dev) &&
- (((uint32)sbuf->st_ino) == fd_ptr->inode)) {
- fd_ptr->ref_count++;
- DEBUG(3,
- ("Re-used file_fd_struct %d, dev = %x, inode = %x, ref_count = %d\n",
- i, fd_ptr->dev, fd_ptr->inode, fd_ptr->ref_count));
- return fd_ptr;
- }
- }
- return 0;
-}
-
-/****************************************************************************
-fd support routines - attempt to find a empty slot in the FileFd array.
-Increments the ref_count of the returned entry.
-****************************************************************************/
-static file_fd_struct *fd_get_new()
-{
- int i;
- file_fd_struct *fd_ptr;
-
- for(i = 0; i < MAX_OPEN_FILES; i++) {
- fd_ptr = &FileFd[i];
- if(fd_ptr->ref_count == 0) {
- fd_ptr->dev = (uint32)-1;
- fd_ptr->inode = (uint32)-1;
- fd_ptr->fd = -1;
- fd_ptr->fd_readonly = -1;
- fd_ptr->fd_writeonly = -1;
- fd_ptr->real_open_flags = -1;
- fd_ptr->ref_count++;
- /* Increment max used counter if neccessary, cuts down
- on search time when re-using */
- if(i > max_file_fd_used)
- max_file_fd_used = i;
- DEBUG(3,("Allocated new file_fd_struct %d, dev = %x, inode = %x\n",
- i, fd_ptr->dev, fd_ptr->inode));
- return fd_ptr;
- }
- }
- DEBUG(1,("ERROR! Out of file_fd structures - perhaps increase MAX_OPEN_FILES?\
-n"));
- return 0;
-}
-
-/****************************************************************************
-fd support routines - attempt to re-open an already open fd as O_RDWR.
-Save the already open fd (we cannot close due to POSIX file locking braindamage.
-****************************************************************************/
-static void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr)
-{
- int fd = sys_open( fname, O_RDWR, mode);
-
- if(fd == -1)
- return;
-
- if(fd_ptr->real_open_flags == O_RDONLY)
- fd_ptr->fd_readonly = fd_ptr->fd;
- if(fd_ptr->real_open_flags == O_WRONLY)
- fd_ptr->fd_writeonly = fd_ptr->fd;
-
- fd_ptr->fd = fd;
- fd_ptr->real_open_flags = O_RDWR;
-}
-
-/****************************************************************************
-fd support routines - attempt to close the file referenced by this fd.
-Decrements the ref_count and returns it.
-****************************************************************************/
-static int fd_attempt_close(file_fd_struct *fd_ptr)
-{
- DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n",
- fd_ptr - &FileFd[0],
- fd_ptr->fd, fd_ptr->dev, fd_ptr->inode,
- fd_ptr->real_open_flags,
- fd_ptr->ref_count));
- if(fd_ptr->ref_count > 0) {
- fd_ptr->ref_count--;
- if(fd_ptr->ref_count == 0) {
- if(fd_ptr->fd != -1)
- close(fd_ptr->fd);
- if(fd_ptr->fd_readonly != -1)
- close(fd_ptr->fd_readonly);
- if(fd_ptr->fd_writeonly != -1)
- close(fd_ptr->fd_writeonly);
- fd_ptr->fd = -1;
- fd_ptr->fd_readonly = -1;
- fd_ptr->fd_writeonly = -1;
- fd_ptr->real_open_flags = -1;
- fd_ptr->dev = (uint32)-1;
- fd_ptr->inode = (uint32)-1;
- }
- }
- return fd_ptr->ref_count;
-}
-
-/****************************************************************************
-open a file
-****************************************************************************/
-static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct stat *sbuf)
-{
- extern struct current_user current_user;
- pstring fname;
- struct stat statbuf;
- file_fd_struct *fd_ptr;
- files_struct *fsp = &Files[fnum];
-
- fsp->open = False;
- fsp->fd_ptr = 0;
- fsp->granted_oplock = False;
- errno = EPERM;
-
- pstrcpy(fname,fname1);
-
- /* check permissions */
- if ((flags != O_RDONLY) && !CAN_WRITE(cnum) && !Connections[cnum].printer)
- {
- DEBUG(3,("Permission denied opening %s\n",fname));
- check_for_pipe(fname);
- return;
- }
-
- /* this handles a bug in Win95 - it doesn't say to create the file when it
- should */
- if (Connections[cnum].printer)
- flags |= O_CREAT;
-
-/*
- if (flags == O_WRONLY)
- DEBUG(3,("Bug in client? Set O_WRONLY without O_CREAT\n"));
-*/
-
-#if UTIME_WORKAROUND
- /* XXXX - is this OK?? */
- /* this works around a utime bug but can cause other problems */
- if ((flags & (O_WRONLY|O_RDWR)) && (flags & O_CREAT) && !(flags & O_APPEND))
- sys_unlink(fname);
-#endif
-
- /*
- * Ensure we have a valid struct stat so we can search the
- * open fd table.
- */
- if(sbuf == 0) {
- if(stat(fname, &statbuf) < 0) {
- if(errno != ENOENT) {
- DEBUG(3,("Error doing stat on file %s (%s)\n",
- fname,strerror(errno)));
-
- check_for_pipe(fname);
- return;
- }
- sbuf = 0;
- } else {
- sbuf = &statbuf;
- }
- }
-
- /*
- * Check to see if we have this file already
- * open. If we do, just use the already open fd and increment the
- * reference count (fd_get_already_open increments the ref_count).
- */
- if((fd_ptr = fd_get_already_open(sbuf))!= 0) {
-
- int accmode = (flags & (O_RDONLY | O_WRONLY | O_RDWR));
-
- /* File was already open. */
- if((flags & O_CREAT) && (flags & O_EXCL)) {
- fd_ptr->ref_count--;
- errno = EEXIST;
- return;
- }
-
- /*
- * If not opened O_RDWR try
- * and do that here - a chmod may have been done
- * between the last open and now.
- */
- if(fd_ptr->real_open_flags != O_RDWR)
- fd_attempt_reopen(fname, mode, fd_ptr);
-
- /*
- * Ensure that if we wanted write access
- * it has been opened for write, and if we wanted read it
- * was open for read.
- */
- if(((accmode == O_WRONLY) && (fd_ptr->real_open_flags == O_RDONLY)) ||
- ((accmode == O_RDONLY) && (fd_ptr->real_open_flags == O_WRONLY)) ||
- ((accmode == O_RDWR) && (fd_ptr->real_open_flags != O_RDWR))) {
- DEBUG(3,("Error opening (already open for flags=%d) file %s (%s) (flags=%d)\n",
- fd_ptr->real_open_flags, fname,strerror(EACCES),flags));
- check_for_pipe(fname);
- fd_ptr->ref_count--;
- return;
- }
-
- } else {
- int open_flags;
- /* We need to allocate a new file_fd_struct (this increments the
- ref_count). */
- if((fd_ptr = fd_get_new()) == 0)
- return;
- /*
- * Whatever the requested flags, attempt read/write access,
- * as we don't know what flags future file opens may require.
- * If this fails, try again with the required flags.
- * Even if we open read/write when only read access was
- * requested the setting of the can_write flag in
- * the file_struct will protect us from errant
- * write requests. We never need to worry about O_APPEND
- * as this is not set anywhere in Samba.
- */
- fd_ptr->real_open_flags = O_RDWR;
- /* Set the flags as needed without the read/write modes. */
- open_flags = flags & ~(O_RDWR|O_WRONLY|O_RDONLY);
- fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDWR, mode);
- /*
- * On some systems opening a file for R/W access on a read only
- * filesystems sets errno to EROFS.
- */
-#ifdef EROFS
- if((fd_ptr->fd == -1) && ((errno == EACCES) || (errno == EROFS))) {
-#else /* No EROFS */
- if((fd_ptr->fd == -1) && (errno == EACCES)) {
-#endif /* EROFS */
- if(flags & O_WRONLY) {
- fd_ptr->fd = fd_attempt_open(fname, open_flags|O_WRONLY, mode);
- fd_ptr->real_open_flags = O_WRONLY;
- } else {
- fd_ptr->fd = fd_attempt_open(fname, open_flags|O_RDONLY, mode);
- fd_ptr->real_open_flags = O_RDONLY;
- }
- }
- }
-
- if ((fd_ptr->fd >=0) &&
- Connections[cnum].printer && lp_minprintspace(SNUM(cnum))) {
- pstring dname;
- int dum1,dum2,dum3;
- char *p;
- pstrcpy(dname,fname);
- p = strrchr(dname,'/');
- if (p) *p = 0;
- if (sys_disk_free(dname,&dum1,&dum2,&dum3) <
- lp_minprintspace(SNUM(cnum))) {
- fd_attempt_close(fd_ptr);
- fsp->fd_ptr = 0;
- if(fd_ptr->ref_count == 0)
- sys_unlink(fname);
- errno = ENOSPC;
- return;
- }
- }
-
- if (fd_ptr->fd < 0)
- {
- DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
- fname,strerror(errno),flags));
- /* Ensure the ref_count is decremented. */
- fd_attempt_close(fd_ptr);
- check_for_pipe(fname);
- return;
- }
-
- if (fd_ptr->fd >= 0)
- {
- if(sbuf == 0) {
- /* Do the fstat */
- if(fstat(fd_ptr->fd, &statbuf) == -1) {
- /* Error - backout !! */
- DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
- fd_ptr->fd, fname,strerror(errno)));
- /* Ensure the ref_count is decremented. */
- fd_attempt_close(fd_ptr);
- return;
- }
- sbuf = &statbuf;
- }
- /* Set the correct entries in fd_ptr. */
- fd_ptr->dev = (uint32)sbuf->st_dev;
- fd_ptr->inode = (uint32)sbuf->st_ino;
-
- fsp->fd_ptr = fd_ptr;
- Connections[cnum].num_files_open++;
- fsp->mode = sbuf->st_mode;
- GetTimeOfDay(&fsp->open_time);
- fsp->uid = current_user.id;
- fsp->size = 0;
- fsp->pos = -1;
- fsp->open = True;
- fsp->mmap_ptr = NULL;
- fsp->mmap_size = 0;
- fsp->can_lock = True;
- fsp->can_read = ((flags & O_WRONLY)==0);
- fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
- fsp->share_mode = 0;
- fsp->print_file = Connections[cnum].printer;
- fsp->modified = False;
- fsp->granted_oplock = False;
- fsp->cnum = cnum;
- string_set(&fsp->name,dos_to_unix(fname,False));
- fsp->wbmpx_ptr = NULL;
-
- /*
- * If the printer is marked as postscript output a leading
- * file identifier to ensure the file is treated as a raw
- * postscript file.
- * This has a similar effect as CtrlD=0 in WIN.INI file.
- * tim@fsg.com 09/06/94
- */
- if (fsp->print_file && POSTSCRIPT(cnum) &&
- fsp->can_write)
- {
- DEBUG(3,("Writing postscript line\n"));
- write_file(fnum,"%!\n",3);
- }
-
- DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n",
- timestring(),Connections[cnum].user,fname,
- BOOLSTR(fsp->can_read),BOOLSTR(fsp->can_write),
- Connections[cnum].num_files_open,fnum));
-
- }
-
-#if USE_MMAP
- /* mmap it if read-only */
- if (!fsp->can_write)
- {
- fsp->mmap_size = file_size(fname);
- fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size,
- PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0);
-
- if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr)
- {
- DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno)));
- fsp->mmap_ptr = NULL;
- }
- }
-#endif
-}
-
-/*******************************************************************
-sync a file
-********************************************************************/
-void sync_file(int fnum)
-{
-#ifndef NO_FSYNC
- fsync(Files[fnum].fd_ptr->fd);
-#endif
-}
-
-/****************************************************************************
-run a file if it is a magic script
-****************************************************************************/
-static void check_magic(int fnum,int cnum)
-{
- if (!*lp_magicscript(SNUM(cnum)))
- return;
-
- DEBUG(5,("checking magic for %s\n",Files[fnum].name));
-
- {
- char *p;
- if (!(p = strrchr(Files[fnum].name,'/')))
- p = Files[fnum].name;
- else
- p++;
-
- if (!strequal(lp_magicscript(SNUM(cnum)),p))
- return;
- }
-
- {
- int ret;
- pstring magic_output;
- pstring fname;
- pstrcpy(fname,Files[fnum].name);
-
- if (*lp_magicoutput(SNUM(cnum)))
- pstrcpy(magic_output,lp_magicoutput(SNUM(cnum)));
- else
- sprintf(magic_output,"%s.out",fname);
-
- chmod(fname,0755);
- ret = smbrun(fname,magic_output,False);
- DEBUG(3,("Invoking magic command %s gave %d\n",fname,ret));
- unlink(fname);
- }
-}
-
-
-/****************************************************************************
-close a file - possibly invalidating the read prediction
-****************************************************************************/
-void close_file(int fnum)
-{
- files_struct *fs_p = &Files[fnum];
- int cnum = fs_p->cnum;
- uint32 dev = fs_p->fd_ptr->dev;
- uint32 inode = fs_p->fd_ptr->inode;
- share_lock_token token;
-
- invalidate_read_prediction(fs_p->fd_ptr->fd);
- fs_p->open = False;
- Connections[cnum].num_files_open--;
- if(fs_p->wbmpx_ptr)
- {
- free((char *)fs_p->wbmpx_ptr);
- fs_p->wbmpx_ptr = NULL;
- }
-
-#if USE_MMAP
- if(fs_p->mmap_ptr)
- {
- munmap(fs_p->mmap_ptr,fs_p->mmap_size);
- fs_p->mmap_ptr = NULL;
- }
-#endif
-
- if (lp_share_modes(SNUM(cnum)))
- {
- lock_share_entry( cnum, dev, inode, &token);
- del_share_mode(token, fnum);
- }
-
- fd_attempt_close(fs_p->fd_ptr);
-
- if (lp_share_modes(SNUM(cnum)))
- unlock_share_entry( cnum, dev, inode, token);
-
- /* NT uses smbclose to start a print - weird */
- if (fs_p->print_file)
- print_file(fnum);
-
- /* check for magic scripts */
- check_magic(fnum,cnum);
-
- DEBUG(2,("%s %s closed file %s (numopen=%d)\n",
- timestring(),Connections[cnum].user,fs_p->name,
- Connections[cnum].num_files_open));
-}
-
-enum {AFAIL,AREAD,AWRITE,AALL};
-
-/*******************************************************************
-reproduce the share mode access table
-********************************************************************/
-static int access_table(int new_deny,int old_deny,int old_mode,
- int share_pid,char *fname)
-{
- if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
-
- if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
- int pid = getpid();
- if (old_deny == new_deny && share_pid == pid)
- return(AALL);
-
- if (old_mode == 0) return(AREAD);
-
- /* the new smbpub.zip spec says that if the file extension is
- .com, .dll, .exe or .sym then allow the open. I will force
- it to read-only as this seems sensible although the spec is
- a little unclear on this. */
- if ((fname = strrchr(fname,'.'))) {
- if (strequal(fname,".com") ||
- strequal(fname,".dll") ||
- strequal(fname,".exe") ||
- strequal(fname,".sym"))
- return(AREAD);
- }
-
- return(AFAIL);
- }
-
- switch (new_deny)
- {
- case DENY_WRITE:
- if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
- if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
- if (old_deny==DENY_NONE && old_mode==0) return(AALL);
- return(AFAIL);
- case DENY_READ:
- if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
- if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
- if (old_deny==DENY_NONE && old_mode==1) return(AALL);
- return(AFAIL);
- case DENY_NONE:
- if (old_deny==DENY_WRITE) return(AREAD);
- if (old_deny==DENY_READ) return(AWRITE);
- if (old_deny==DENY_NONE) return(AALL);
- return(AFAIL);
- }
- return(AFAIL);
-}
-
-/*******************************************************************
-check if the share mode on a file allows it to be deleted or unlinked
-return True if sharing doesn't prevent the operation
-********************************************************************/
-BOOL check_file_sharing(int cnum,char *fname)
-{
- int i;
- int ret = False;
- min_share_mode_entry *old_shares = 0;
- int num_share_modes;
- struct stat sbuf;
- share_lock_token token;
- int pid = getpid();
- uint32 dev, inode;
-
- if(!lp_share_modes(SNUM(cnum)))
- return True;
-
- if (stat(fname,&sbuf) == -1) return(True);
-
- dev = (uint32)sbuf.st_dev;
- inode = (uint32)sbuf.st_ino;
-
- lock_share_entry(cnum, dev, inode, &token);
- num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
-
- /*
- * Check if the share modes will give us access.
- */
-
- if(num_share_modes != 0)
- {
- BOOL broke_oplock;
-
- do
- {
-
- broke_oplock = False;
- for(i = 0; i < num_share_modes; i++)
- {
- min_share_mode_entry *share_entry = &old_shares[i];
-
- /*
- * Break oplocks before checking share modes. See comment in
- * open_file_shared for details.
- * Check if someone has an oplock on this file. If so we must
- * break it before continuing.
- */
- if(share_entry->op_type & BATCH_OPLOCK)
- {
-
- DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
-dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
-
- /* Oplock break.... */
- unlock_share_entry(cnum, dev, inode, token);
- if(request_oplock_break(share_entry, dev, inode) == False)
- {
- free((char *)old_shares);
- DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \
-dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
- return False;
- }
- lock_share_entry(cnum, dev, inode, &token);
- broke_oplock = True;
- break;
- }
-
- /* someone else has a share lock on it, check to see
- if we can too */
- if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid))
- goto free_and_exit;
-
- } /* end for */
-
- if(broke_oplock)
- {
- free((char *)old_shares);
- num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
- }
- } while(broke_oplock);
- }
-
- /* XXXX exactly what share mode combinations should be allowed for
- deleting/renaming? */
- /* If we got here then either there were no share modes or
- all share modes were DENY_DOS and the pid == getpid() */
- ret = True;
-
-free_and_exit:
-
- unlock_share_entry(cnum, dev, inode, token);
- if(old_shares != NULL)
- free((char *)old_shares);
- return(ret);
-}
-
-/****************************************************************************
- C. Hoch 11/22/95
- Helper for open_file_shared.
- Truncate a file after checking locking; close file if locked.
- **************************************************************************/
-static void truncate_unless_locked(int fnum, int cnum, share_lock_token token,
- BOOL *share_locked)
-{
- if (Files[fnum].can_write){
- if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
- /* If share modes are in force for this connection we
- have the share entry locked. Unlock it before closing. */
- if (*share_locked && lp_share_modes(SNUM(cnum)))
- unlock_share_entry( cnum, Files[fnum].fd_ptr->dev,
- Files[fnum].fd_ptr->inode, token);
- close_file(fnum);
- /* Share mode no longer locked. */
- *share_locked = False;
- errno = EACCES;
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRlock;
- }
- else
- ftruncate(Files[fnum].fd_ptr->fd,0);
- }
-}
-
-/****************************************************************************
-check if we can open a file with a share mode
-****************************************************************************/
-int check_share_mode( min_share_mode_entry *share, int deny_mode, char *fname,
- BOOL fcbopen, int *flags)
-{
- int old_open_mode = share->share_mode &0xF;
- int old_deny_mode = (share->share_mode >>4)&7;
-
- if (old_deny_mode > 4 || old_open_mode > 2)
- {
- DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
- deny_mode,old_deny_mode,old_open_mode,fname));
- return False;
- }
-
- {
- int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
- share->pid,fname);
-
- if ((access_allowed == AFAIL) ||
- (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
- (access_allowed == AREAD && *flags == O_WRONLY) ||
- (access_allowed == AWRITE && *flags == O_RDONLY))
- {
- DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n",
- deny_mode,old_deny_mode,old_open_mode,
- share->pid,fname, access_allowed));
- return False;
- }
-
- if (access_allowed == AREAD)
- *flags = O_RDONLY;
-
- if (access_allowed == AWRITE)
- *flags = O_WRONLY;
-
- }
- return True;
-}
-
-/****************************************************************************
-open a file with a share mode
-****************************************************************************/
-void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun,
- int mode,int oplock_request, int *Access,int *action)
-{
- files_struct *fs_p = &Files[fnum];
- int flags=0;
- int flags2=0;
- int deny_mode = (share_mode>>4)&7;
- struct stat sbuf;
- BOOL file_existed = file_exist(fname,&sbuf);
- BOOL share_locked = False;
- BOOL fcbopen = False;
- share_lock_token token;
- uint32 dev = 0;
- uint32 inode = 0;
- int num_share_modes = 0;
-
- fs_p->open = False;
- fs_p->fd_ptr = 0;
-
- /* this is for OS/2 EAs - try and say we don't support them */
- if (strstr(fname,".+,;=[]."))
- {
- unix_ERR_class = ERRDOS;
- /* OS/2 Workplace shell fix may be main code stream in a later release. */
-#ifdef OS2_WPS_FIX
- unix_ERR_code = ERRcannotopen;
-#else /* OS2_WPS_FIX */
- unix_ERR_code = ERROR_EAS_NOT_SUPPORTED;
-#endif /* OS2_WPS_FIX */
-
- return;
- }
-
- if ((ofun & 0x3) == 0 && file_existed)
- {
- errno = EEXIST;
- return;
- }
-
- if (ofun & 0x10)
- flags2 |= O_CREAT;
- if ((ofun & 0x3) == 2)
- flags2 |= O_TRUNC;
-
- /* note that we ignore the append flag as
- append does not mean the same thing under dos and unix */
-
- switch (share_mode&0xF)
- {
- case 1:
- flags = O_WRONLY;
- break;
- case 0xF:
- fcbopen = True;
- flags = O_RDWR;
- break;
- case 2:
- flags = O_RDWR;
- break;
- default:
- flags = O_RDONLY;
- break;
- }
-
- if (flags != O_RDONLY && file_existed &&
- (!CAN_WRITE(cnum) || IS_DOS_READONLY(dos_mode(cnum,fname,&sbuf))))
- {
- if (!fcbopen)
- {
- errno = EACCES;
- return;
- }
- flags = O_RDONLY;
- }
-
- if (deny_mode > DENY_NONE && deny_mode!=DENY_FCB)
- {
- DEBUG(2,("Invalid deny mode %d on file %s\n",deny_mode,fname));
- errno = EINVAL;
- return;
- }
-
- if (deny_mode == DENY_FCB) deny_mode = DENY_DOS;
-
- if (lp_share_modes(SNUM(cnum)))
- {
- int i;
- min_share_mode_entry *old_shares = 0;
-
- if (file_existed)
- {
- dev = (uint32)sbuf.st_dev;
- inode = (uint32)sbuf.st_ino;
- lock_share_entry(cnum, dev, inode, &token);
- share_locked = True;
- num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
- }
-
- /*
- * Check if the share modes will give us access.
- */
-
- if(share_locked && (num_share_modes != 0))
- {
- BOOL broke_oplock;
-
- do
- {
-
- broke_oplock = False;
- for(i = 0; i < num_share_modes; i++)
- {
- min_share_mode_entry *share_entry = &old_shares[i];
-
- /*
- * By observation of NetBench, oplocks are broken *before* share
- * modes are checked. This allows a file to be closed by the client
- * if the share mode would deny access and the client has an oplock.
- * Check if someone has an oplock on this file. If so we must break
- * it before continuing.
- */
- if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
- {
-
- DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
-dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode));
-
- /* Oplock break.... */
- unlock_share_entry(cnum, dev, inode, token);
- if(request_oplock_break(share_entry, dev, inode) == False)
- {
- free((char *)old_shares);
- DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \
-dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode));
- errno = EACCES;
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadshare;
- return;
- }
- lock_share_entry(cnum, dev, inode, &token);
- broke_oplock = True;
- break;
- }
-
- /* someone else has a share lock on it, check to see
- if we can too */
- if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False)
- {
- free((char *)old_shares);
- unlock_share_entry(cnum, dev, inode, token);
- errno = EACCES;
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadshare;
- return;
- }
-
- } /* end for */
-
- if(broke_oplock)
- {
- free((char *)old_shares);
- num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares);
- }
- } while(broke_oplock);
- }
-
- if(old_shares != 0)
- free((char *)old_shares);
- }
-
- DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
- flags,flags2,mode));
-
- open_file(fnum,cnum,fname,flags|(flags2&~(O_TRUNC)),mode,file_existed ? &sbuf : 0);
- if (!fs_p->open && flags==O_RDWR && errno!=ENOENT && fcbopen)
- {
- flags = O_RDONLY;
- open_file(fnum,cnum,fname,flags,mode,file_existed ? &sbuf : 0 );
- }
-
- if (fs_p->open)
- {
- int open_mode=0;
-
- if((share_locked == False) && lp_share_modes(SNUM(cnum)))
- {
- /* We created the file - thus we must now lock the share entry before creating it. */
- dev = fs_p->fd_ptr->dev;
- inode = fs_p->fd_ptr->inode;
- lock_share_entry(cnum, dev, inode, &token);
- share_locked = True;
- }
-
- switch (flags)
- {
- case O_RDONLY:
- open_mode = 0;
- break;
- case O_RDWR:
- open_mode = 2;
- break;
- case O_WRONLY:
- open_mode = 1;
- break;
- }
-
- fs_p->share_mode = (deny_mode<<4) | open_mode;
-
- if (Access)
- (*Access) = open_mode;
-
- if (action)
- {
- if (file_existed && !(flags2 & O_TRUNC)) *action = 1;
- if (!file_existed) *action = 2;
- if (file_existed && (flags2 & O_TRUNC)) *action = 3;
- }
- /* We must create the share mode entry before truncate as
- truncate can fail due to locking and have to close the
- file (which expects the share_mode_entry to be there).
- */
- if (lp_share_modes(SNUM(cnum)))
- {
- uint16 port = 0;
- /* JRA. Currently this only services Exlcusive and batch
- oplocks (no other opens on this file). This needs to
- be extended to level II oplocks (multiple reader
- oplocks). */
-
- if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum)))
- {
- fs_p->granted_oplock = True;
- global_oplocks_open++;
- port = oplock_port;
-
- DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \
-dev = %x, inode = %x\n", oplock_request, fname, dev, inode));
-
- }
- else
- {
- port = 0;
- oplock_request = 0;
- }
- set_share_mode(token, fnum, port, oplock_request);
- }
-
- if ((flags2&O_TRUNC) && file_existed)
- truncate_unless_locked(fnum,cnum,token,&share_locked);
- }
-
- if (share_locked && lp_share_modes(SNUM(cnum)))
- unlock_share_entry( cnum, dev, inode, token);
-}
-
-/****************************************************************************
-seek a file. Try to avoid the seek if possible
-****************************************************************************/
-int seek_file(int fnum,uint32 pos)
-{
- uint32 offset = 0;
- if (Files[fnum].print_file && POSTSCRIPT(Files[fnum].cnum))
- offset = 3;
-
- Files[fnum].pos = (int)(lseek(Files[fnum].fd_ptr->fd,pos+offset,SEEK_SET)
- - offset);
- return(Files[fnum].pos);
-}
-
-/****************************************************************************
-read from a file
-****************************************************************************/
-int read_file(int fnum,char *data,uint32 pos,int n)
-{
- int ret=0,readret;
-
- if (!Files[fnum].can_write)
- {
- ret = read_predict(Files[fnum].fd_ptr->fd,pos,data,NULL,n);
-
- data += ret;
- n -= ret;
- pos += ret;
- }
-
-#if USE_MMAP
- if (Files[fnum].mmap_ptr)
- {
- int num = MIN(n,(int)(Files[fnum].mmap_size-pos));
- if (num > 0)
- {
- memcpy(data,Files[fnum].mmap_ptr+pos,num);
- data += num;
- pos += num;
- n -= num;
- ret += num;
- }
- }
-#endif
-
- if (n <= 0)
- return(ret);
-
- if (seek_file(fnum,pos) != pos)
- {
- DEBUG(3,("Failed to seek to %d\n",pos));
- return(ret);
- }
-
- if (n > 0) {
- readret = read(Files[fnum].fd_ptr->fd,data,n);
- if (readret > 0) ret += readret;
- }
-
- return(ret);
-}
-
-
-/****************************************************************************
-write to a file
-****************************************************************************/
-int write_file(int fnum,char *data,int n)
-{
- if (!Files[fnum].can_write) {
- errno = EPERM;
- return(0);
- }
-
- if (!Files[fnum].modified) {
- struct stat st;
- Files[fnum].modified = True;
- if (fstat(Files[fnum].fd_ptr->fd,&st) == 0) {
- int dosmode = dos_mode(Files[fnum].cnum,Files[fnum].name,&st);
- if (MAP_ARCHIVE(Files[fnum].cnum) && !IS_DOS_ARCHIVE(dosmode)) {
- dos_chmod(Files[fnum].cnum,Files[fnum].name,dosmode | aARCH,&st);
- }
- }
- }
-
- return(write_data(Files[fnum].fd_ptr->fd,data,n));
-}
-
-
-/****************************************************************************
-load parameters specific to a connection/service
-****************************************************************************/
-BOOL become_service(int cnum,BOOL do_chdir)
-{
- extern char magic_char;
- static int last_cnum = -1;
- int snum;
-
- if (!OPEN_CNUM(cnum))
- {
- last_cnum = -1;
- return(False);
- }
-
- Connections[cnum].lastused = smb_last_time;
-
- snum = SNUM(cnum);
-
- if (do_chdir &&
- ChDir(Connections[cnum].connectpath) != 0 &&
- ChDir(Connections[cnum].origpath) != 0)
- {
- DEBUG(0,("%s chdir (%s) failed cnum=%d\n",timestring(),
- Connections[cnum].connectpath,cnum));
- return(False);
- }
-
- if (cnum == last_cnum)
- return(True);
-
- last_cnum = cnum;
-
- case_default = lp_defaultcase(snum);
- case_preserve = lp_preservecase(snum);
- short_case_preserve = lp_shortpreservecase(snum);
- case_mangle = lp_casemangle(snum);
- case_sensitive = lp_casesensitive(snum);
- magic_char = lp_magicchar(snum);
- use_mangled_map = (*lp_mangled_map(snum) ? True:False);
- return(True);
-}
-
-
-/****************************************************************************
- find a service entry
-****************************************************************************/
-int find_service(char *service)
-{
- int iService;
-
- string_sub(service,"\\","/");
-
- iService = lp_servicenumber(service);
-
- /* now handle the special case of a home directory */
- if (iService < 0)
- {
- char *phome_dir = get_home_dir(service);
- DEBUG(3,("checking for home directory %s gave %s\n",service,
- phome_dir?phome_dir:"(NULL)"));
- if (phome_dir)
- {
- int iHomeService;
- if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
- {
- lp_add_home(service,iHomeService,phome_dir);
- iService = lp_servicenumber(service);
- }
- }
- }
-
- /* If we still don't have a service, attempt to add it as a printer. */
- if (iService < 0)
- {
- int iPrinterService;
-
- if ((iPrinterService = lp_servicenumber(PRINTERS_NAME)) >= 0)
- {
- char *pszTemp;
-
- DEBUG(3,("checking whether %s is a valid printer name...\n", service));
- pszTemp = PRINTCAP;
- if ((pszTemp != NULL) && pcap_printername_ok(service, pszTemp))
- {
- DEBUG(3,("%s is a valid printer name\n", service));
- DEBUG(3,("adding %s as a printer service\n", service));
- lp_add_printer(service,iPrinterService);
- iService = lp_servicenumber(service);
- if (iService < 0)
- DEBUG(0,("failed to add %s as a printer service!\n", service));
- }
- else
- DEBUG(3,("%s is not a valid printer name\n", service));
- }
- }
-
- /* just possibly it's a default service? */
- if (iService < 0)
- {
- char *defservice = lp_defaultservice();
- if (defservice && *defservice && !strequal(defservice,service)) {
- iService = find_service(defservice);
- if (iService >= 0) {
- string_sub(service,"_","/");
- iService = lp_add_service(service,iService);
- }
- }
- }
-
- if (iService >= 0)
- if (!VALID_SNUM(iService))
- {
- DEBUG(0,("Invalid snum %d for %s\n",iService,service));
- iService = -1;
- }
-
- if (iService < 0)
- DEBUG(3,("find_service() failed to find service %s\n", service));
-
- return (iService);
-}
-
-
-/****************************************************************************
- create an error packet from a cached error.
-****************************************************************************/
-int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line)
-{
- write_bmpx_struct *wbmpx = Files[fnum].wbmpx_ptr;
-
- int32 eclass = wbmpx->wr_errclass;
- int32 err = wbmpx->wr_error;
-
- /* We can now delete the auxiliary struct */
- free((char *)wbmpx);
- Files[fnum].wbmpx_ptr = NULL;
- return error_packet(inbuf,outbuf,eclass,err,line);
-}
-
-
-struct
-{
- int unixerror;
- int smbclass;
- int smbcode;
-} unix_smb_errmap[] =
-{
- {EPERM,ERRDOS,ERRnoaccess},
- {EACCES,ERRDOS,ERRnoaccess},
- {ENOENT,ERRDOS,ERRbadfile},
- {ENOTDIR,ERRDOS,ERRbadpath},
- {EIO,ERRHRD,ERRgeneral},
- {EBADF,ERRSRV,ERRsrverror},
- {EINVAL,ERRSRV,ERRsrverror},
- {EEXIST,ERRDOS,ERRfilexists},
- {ENFILE,ERRDOS,ERRnofids},
- {EMFILE,ERRDOS,ERRnofids},
- {ENOSPC,ERRHRD,ERRdiskfull},
-#ifdef EDQUOT
- {EDQUOT,ERRHRD,ERRdiskfull},
-#endif
-#ifdef ENOTEMPTY
- {ENOTEMPTY,ERRDOS,ERRnoaccess},
-#endif
-#ifdef EXDEV
- {EXDEV,ERRDOS,ERRdiffdevice},
-#endif
- {EROFS,ERRHRD,ERRnowrite},
- {0,0,0}
-};
-
-/****************************************************************************
- create an error packet from errno
-****************************************************************************/
-int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line)
-{
- int eclass=def_class;
- int ecode=def_code;
- int i=0;
-
- if (unix_ERR_class != SUCCESS)
- {
- eclass = unix_ERR_class;
- ecode = unix_ERR_code;
- unix_ERR_class = SUCCESS;
- unix_ERR_code = 0;
- }
- else
- {
- while (unix_smb_errmap[i].smbclass != 0)
- {
- if (unix_smb_errmap[i].unixerror == errno)
- {
- eclass = unix_smb_errmap[i].smbclass;
- ecode = unix_smb_errmap[i].smbcode;
- break;
- }
- i++;
- }
- }
-
- return(error_packet(inbuf,outbuf,eclass,ecode,line));
-}
-
-
-/****************************************************************************
- create an error packet. Normally called using the ERROR() macro
-****************************************************************************/
-int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line)
-{
- int outsize = set_message(outbuf,0,0,True);
- int cmd;
- cmd = CVAL(inbuf,smb_com);
-
- CVAL(outbuf,smb_rcls) = error_class;
- SSVAL(outbuf,smb_err,error_code);
-
- DEBUG(3,("%s error packet at line %d cmd=%d (%s) eclass=%d ecode=%d\n",
- timestring(),
- line,
- (int)CVAL(inbuf,smb_com),
- smb_fn_name(CVAL(inbuf,smb_com)),
- error_class,
- error_code));
-
- if (errno != 0)
- DEBUG(3,("error string = %s\n",strerror(errno)));
-
- return(outsize);
-}
-
-
-#ifndef SIGCLD_IGNORE
-/****************************************************************************
-this prevents zombie child processes
-****************************************************************************/
-static int sig_cld()
-{
- static int depth = 0;
- if (depth != 0)
- {
- DEBUG(0,("ERROR: Recursion in sig_cld? Perhaps you need `#define USE_WAITPID'?\n"));
- depth=0;
- return(0);
- }
- depth++;
-
- BlockSignals(True,SIGCLD);
- DEBUG(5,("got SIGCLD\n"));
-
-#ifdef USE_WAITPID
- while (sys_waitpid((pid_t)-1,(int *)NULL, WNOHANG) > 0);
-#endif
-
- /* Stop zombies */
- /* Stevens, Adv. Unix Prog. says that on system V you must call
- wait before reinstalling the signal handler, because the kernel
- calls the handler from within the signal-call when there is a
- child that has exited. This would lead to an infinite recursion
- if done vice versa. */
-
-#ifndef DONT_REINSTALL_SIG
-#ifdef SIGCLD_IGNORE
- signal(SIGCLD, SIG_IGN);
-#else
- signal(SIGCLD, SIGNAL_CAST sig_cld);
-#endif
-#endif
-
-#ifndef USE_WAITPID
- while (wait3(WAIT3_CAST1 NULL, WNOHANG, WAIT3_CAST2 NULL) > 0);
-#endif
- depth--;
- BlockSignals(False,SIGCLD);
- return 0;
-}
-#endif
-
-/****************************************************************************
- this is called when the client exits abruptly
- **************************************************************************/
-static int sig_pipe()
-{
- extern int password_client;
- BlockSignals(True,SIGPIPE);
-
- if (password_client != -1) {
- DEBUG(3,("lost connection to password server\n"));
- close(password_client);
- password_client = -1;
-#ifndef DONT_REINSTALL_SIG
- signal(SIGPIPE, SIGNAL_CAST sig_pipe);
-#endif
- BlockSignals(False,SIGPIPE);
- return 0;
- }
-
- exit_server("Got sigpipe\n");
- return(0);
-}
-
-/****************************************************************************
- open the socket communication
-****************************************************************************/
-static BOOL open_sockets(BOOL is_daemon,int port)
-{
- extern int Client;
-
- if (is_daemon)
- {
- int s;
- struct sockaddr addr;
- int in_addrlen = sizeof(addr);
-
- /* Stop zombies */
-#ifdef SIGCLD_IGNORE
- signal(SIGCLD, SIG_IGN);
-#else
- signal(SIGCLD, SIGNAL_CAST sig_cld);
-#endif
-
- /* open an incoming socket */
- s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
- if (s == -1)
- return(False);
-
- /* ready to listen */
- if (listen(s, 5) == -1)
- {
- DEBUG(0,("listen: %s\n",strerror(errno)));
- close(s);
- return False;
- }
-
- if(atexit_set == 0)
- atexit(killkids);
-
- /* now accept incoming connections - forking a new process
- for each incoming connection */
- DEBUG(2,("waiting for a connection\n"));
- while (1)
- {
- Client = accept(s,&addr,&in_addrlen);
-
- if (Client == -1 && errno == EINTR)
- continue;
-
- if (Client == -1)
- {
- DEBUG(0,("accept: %s\n",strerror(errno)));
- continue;
- }
-
-#ifdef NO_FORK_DEBUG
-#ifndef NO_SIGNAL_TEST
- signal(SIGPIPE, SIGNAL_CAST sig_pipe);
- signal(SIGCLD, SIGNAL_CAST SIG_DFL);
-#endif
- return True;
-#else
- if (Client != -1 && fork()==0)
- {
- /* Child code ... */
-#ifndef NO_SIGNAL_TEST
- signal(SIGPIPE, SIGNAL_CAST sig_pipe);
- signal(SIGCLD, SIGNAL_CAST SIG_DFL);
-#endif
- /* close the listening socket */
- close(s);
-
- /* close our standard file descriptors */
- close_low_fds();
- am_parent = 0;
-
- set_socket_options(Client,"SO_KEEPALIVE");
- set_socket_options(Client,user_socket_options);
-
- /* Reset global variables in util.c so that
- client substitutions will be done correctly
- in the process.
- */
- reset_globals_after_fork();
- return True;
- }
- close(Client); /* The parent doesn't need this socket */
-#endif
- }
- }
- else
- {
- /* We will abort gracefully when the client or remote system
- goes away */
-#ifndef NO_SIGNAL_TEST
- signal(SIGPIPE, SIGNAL_CAST sig_pipe);
-#endif
- Client = dup(0);
-
- /* close our standard file descriptors */
- close_low_fds();
-
- set_socket_options(Client,"SO_KEEPALIVE");
- set_socket_options(Client,user_socket_options);
- }
-
- return True;
-}
-
-/****************************************************************************
- process an smb from the client - split out from the process() code so
- it can be used by the oplock break code.
-****************************************************************************/
-
-static void process_smb(char *inbuf, char *outbuf)
-{
- extern int Client;
- static int trans_num;
- int msg_type = CVAL(inbuf,0);
- int32 len = smb_len(inbuf);
- int nread = len + 4;
-
- if (trans_num == 0) {
- /* on the first packet, check the global hosts allow/ hosts
- deny parameters before doing any parsing of the packet
- passed to us by the client. This prevents attacks on our
- parsing code from hosts not in the hosts allow list */
- if (!check_access(-1)) {
- /* send a negative session response "not listining on calling
- name" */
- static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
- DEBUG(1,("%s Connection denied from %s\n",
- timestring(),client_addr()));
- send_smb(Client,(char *)buf);
- exit_server("connection denied");
- }
- }
-
- DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
- DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
-
-#ifdef WITH_VTP
- if(trans_num == 1 && VT_Check(inbuf))
- {
- VT_Process();
- return;
- }
-#endif
-
- if (msg_type == 0)
- show_msg(inbuf);
-
- nread = construct_reply(inbuf,outbuf,nread,max_send);
-
- if(nread > 0)
- {
- if (CVAL(outbuf,0) == 0)
- show_msg(outbuf);
-
- if (nread != smb_len(outbuf) + 4)
- {
- DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
- nread, smb_len(outbuf)));
- }
- else
- send_smb(Client,outbuf);
- }
- trans_num++;
-}
-
-/****************************************************************************
- open the oplock IPC socket communication
-****************************************************************************/
-static BOOL open_oplock_ipc()
-{
- struct sockaddr_in sock_name;
- int len = sizeof(sock_name);
-
- DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
-
- /* Open a lookback UDP socket on a random port. */
- oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
- if (oplock_sock == -1)
- {
- DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
-address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
- oplock_port = 0;
- return(False);
- }
-
- /* Find out the transient UDP port we have been allocated. */
- if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
- {
- DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
- strerror(errno)));
- close(oplock_sock);
- oplock_sock = -1;
- oplock_port = 0;
- return False;
- }
- oplock_port = ntohs(sock_name.sin_port);
-
- DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n",
- getpid(), oplock_port));
-
- return True;
-}
-
-/****************************************************************************
- process an oplock break message.
-****************************************************************************/
-static BOOL process_local_message(int sock, char *buffer, int buf_size)
-{
- int32 msg_len;
- int16 from_port;
- char *msg_start;
-
- msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
- from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
-
- msg_start = &buffer[UDP_CMD_HEADER_LEN];
-
- DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
- msg_len, from_port));
-
- /* Switch on message command - currently OPLOCK_BREAK_CMD is the
- only valid request. */
-
- switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
- {
- case OPLOCK_BREAK_CMD:
- /* Ensure that the msg length is correct. */
- if(msg_len != OPLOCK_BREAK_MSG_LEN)
- {
- DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
-should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
- return False;
- }
- {
- uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
- uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
- uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
- struct timeval tval;
- struct sockaddr_in toaddr;
-
- tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
- tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
-
- DEBUG(5,("process_local_message: oplock break request from \
-pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
-
- /*
- * If we have no record of any currently open oplocks,
- * it's not an error, as a close command may have
- * just been issued on the file that was oplocked.
- * Just return success in this case.
- */
-
- if(global_oplocks_open != 0)
- {
- if(oplock_break(dev, inode, &tval) == False)
- {
- DEBUG(0,("process_local_message: oplock break failed - \
-not returning udp message.\n"));
- return False;
- }
- }
- else
- {
- DEBUG(3,("process_local_message: oplock break requested with no outstanding \
-oplocks. Returning success.\n"));
- }
-
- /* Send the message back after OR'ing in the 'REPLY' bit. */
- SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
-
- bzero((char *)&toaddr,sizeof(toaddr));
- toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- toaddr.sin_port = htons(from_port);
- toaddr.sin_family = AF_INET;
-
- if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
- (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
- {
- DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
- remotepid, strerror(errno)));
- return False;
- }
-
- DEBUG(5,("process_local_message: oplock break reply sent to \
-pid %d, port %d, for file dev = %x, inode = %x\n", remotepid,
- from_port, dev, inode));
-
- }
- break;
- /*
- * Keep this as a debug case - eventually we can remove it.
- */
- case 0x8001:
- DEBUG(0,("process_local_message: Received unsolicited break \
-reply - dumping info.\n"));
-
- if(msg_len != OPLOCK_BREAK_MSG_LEN)
- {
- DEBUG(0,("process_local_message: ubr: incorrect length for reply \
-(was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
- return False;
- }
-
- {
- uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
- uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
- uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
-
- DEBUG(0,("process_local_message: unsolicited oplock break reply from \
-pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode));
-
- }
- return False;
-
- default:
- DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
- (unsigned int)SVAL(msg_start,0)));
- return False;
- }
- return True;
-}
-
-/****************************************************************************
- Process an oplock break directly.
-****************************************************************************/
-BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval)
-{
- extern int Client;
- static char *inbuf = NULL;
- static char *outbuf = NULL;
- files_struct *fsp = NULL;
- int fnum;
- time_t start_time;
- BOOL shutdown_server = False;
-
- DEBUG(5,("oplock_break: called for dev = %x, inode = %x. Current \
-global_oplocks_open = %d\n", dev, inode, global_oplocks_open));
-
- if(inbuf == NULL)
- {
- inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- if(inbuf == NULL) {
- DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
- return False;
- }
- outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- if(outbuf == NULL) {
- DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
- free(inbuf);
- inbuf = NULL;
- return False;
- }
- }
-
- /* We need to search the file open table for the
- entry containing this dev and inode, and ensure
- we have an oplock on it. */
- for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++)
- {
- if(OPEN_FNUM(fnum))
- {
- fsp = &Files[fnum];
- if((fsp->fd_ptr->dev == dev) && (fsp->fd_ptr->inode == inode) &&
- (fsp->open_time.tv_sec == tval->tv_sec) &&
- (fsp->open_time.tv_usec == tval->tv_usec))
- break;
- }
- }
-
- if(fsp == NULL)
- {
- /* The file could have been closed in the meantime - return success. */
- DEBUG(3,("oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \
-allowing break to succeed.\n", dev, inode, fnum));
- return True;
- }
-
- /* Ensure we have an oplock on the file */
-
- /* There is a potential race condition in that an oplock could
- have been broken due to another udp request, and yet there are
- still oplock break messages being sent in the udp message
- queue for this file. So return true if we don't have an oplock,
- as we may have just freed it.
- */
-
- if(!fsp->granted_oplock)
- {
- DEBUG(3,("oplock_break: file %s (fnum = %d, dev = %x, inode = %x) has no oplock. \
-Allowing break to succeed regardless.\n", fsp->name, fnum, dev, inode));
- return True;
- }
-
- /* Now comes the horrid part. We must send an oplock break to the client,
- and then process incoming messages until we get a close or oplock release.
- */
-
- /* Prepare the SMBlockingX message. */
- bzero(outbuf,smb_size);
- set_message(outbuf,8,0,True);
-
- SCVAL(outbuf,smb_com,SMBlockingX);
- SSVAL(outbuf,smb_tid,fsp->cnum);
- SSVAL(outbuf,smb_pid,0xFFFF);
- SSVAL(outbuf,smb_uid,0);
- SSVAL(outbuf,smb_mid,0xFFFF);
- SCVAL(outbuf,smb_vwv0,0xFF);
- SSVAL(outbuf,smb_vwv2,fnum);
- SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
- /* Change this when we have level II oplocks. */
- SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
-
- send_smb(Client, outbuf);
-
- global_oplock_break = True;
-
- /* Process incoming messages. */
-
- /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
- seconds we should just die.... */
-
- start_time = time(NULL);
-
- while(OPEN_FNUM(fnum) && fsp->granted_oplock)
- {
- if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
- {
- /*
- * Die if we got an error.
- */
-
- if (smb_read_error == READ_EOF)
- DEBUG(0,("oplock_break: end of file from client\n"));
-
- if (smb_read_error == READ_ERROR)
- DEBUG(0,("oplock_break: receive_smb error (%s)\n",
- strerror(errno)));
-
- if (smb_read_error == READ_TIMEOUT)
- DEBUG(0,("oplock_break: receive_smb timed out after %d seconds.\n",
- OPLOCK_BREAK_TIMEOUT));
-
- DEBUG(0,("oplock_break failed for file %s (fnum = %d, dev = %x, \
-inode = %x).\n", fsp->name, fnum, dev, inode));
- shutdown_server = True;
- break;
- }
- process_smb(inbuf, outbuf);
-
- /* We only need this in case a readraw crossed on the wire. */
- if(global_oplock_break)
- global_oplock_break = False;
-
- /*
- * Die if we go over the time limit.
- */
-
- if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
- {
- DEBUG(0,("oplock_break: no break received from client within \
-%d seconds.\n", OPLOCK_BREAK_TIMEOUT));
- DEBUG(0,("oplock_break failed for file %s (fnum = %d, dev = %x, \
-inode = %x).\n", fsp->name, fnum, dev, inode));
- shutdown_server = True;
- break;
- }
- }
-
- /*
- * If the client did not respond we must die.
- */
-
- if(shutdown_server)
- {
- DEBUG(0,("oplock_break: client failure in break - shutting down this smbd.\n"));
- close_sockets();
- close(oplock_sock);
- exit_server("oplock break failure");
- }
-
- if(OPEN_FNUM(fnum))
- {
- /* The lockingX reply will have removed the oplock flag
- from the sharemode. */
- /* Paranoia.... */
- fsp->granted_oplock = False;
- }
-
- global_oplocks_open--;
-
- /* Santity check - remove this later. JRA */
- if(global_oplocks_open < 0)
- {
- DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
- global_oplocks_open));
- exit_server("oplock_break: global_oplocks_open < 0");
- }
-
- DEBUG(5,("oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \
-global_oplocks_open = %d\n", fnum, dev, inode, global_oplocks_open));
-
- return True;
-}
-
-/****************************************************************************
-Send an oplock break message to another smbd process. If the oplock is held
-by the local smbd then call the oplock break function directly.
-****************************************************************************/
-
-BOOL request_oplock_break(min_share_mode_entry *share_entry,
- uint32 dev, uint32 inode)
-{
- char op_break_msg[OPLOCK_BREAK_MSG_LEN];
- struct sockaddr_in addr_out;
- int pid = getpid();
-
- if(pid == share_entry->pid)
- {
- /* We are breaking our own oplock, make sure it's us. */
- if(share_entry->op_port != oplock_port)
- {
- DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
-should be %d\n", pid, share_entry->op_port, oplock_port));
- return False;
- }
-
- DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
-
- /* Call oplock break direct. */
- return oplock_break(dev, inode, &share_entry->time);
- }
-
- /* We need to send a OPLOCK_BREAK_CMD message to the
- port in the share mode entry. */
-
- SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
- SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
- SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
- SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
- SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
- SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
-
- /* set the address and port */
- bzero((char *)&addr_out,sizeof(addr_out));
- addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- addr_out.sin_port = htons( share_entry->op_port );
- addr_out.sin_family = AF_INET;
-
- DEBUG(3,("request_oplock_break: sending a oplock break message to pid %d on port %d \
-for dev = %x, inode = %x\n", share_entry->pid, share_entry->op_port, dev, inode));
-
- if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
- (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
- {
- DEBUG(0,("request_oplock_break: failed when sending a oplock break message \
-to pid %d on port %d for dev = %x, inode = %x. Error was %s\n",
- share_entry->pid, share_entry->op_port, dev, inode,
- strerror(errno)));
- return False;
- }
-
- /*
- * Now we must await the oplock broken message coming back
- * from the target smbd process. Timeout if it fails to
- * return in OPLOCK_BREAK_TIMEOUT seconds.
- * While we get messages that aren't ours, loop.
- */
-
- while(1)
- {
- char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
- int32 reply_msg_len;
- int16 reply_from_port;
- char *reply_msg_start;
-
- if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
- OPLOCK_BREAK_TIMEOUT * 1000) == False)
- {
- if(smb_read_error == READ_TIMEOUT)
- DEBUG(0,("request_oplock_break: no response received to oplock break request to \
-pid %d on port %d for dev = %x, inode = %x\n", share_entry->pid,
- share_entry->op_port, dev, inode));
- else
- DEBUG(0,("request_oplock_break: error in response received to oplock break request to \
-pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", share_entry->pid,
- share_entry->op_port, dev, inode, strerror(errno)));
- return False;
- }
-
- /*
- * If the response we got was not an answer to our message, but
- * was a completely different request, push it onto the pending
- * udp message stack so that we can deal with it in the main loop.
- * It may be another oplock break request to us.
- */
-
- /*
- * Local note from JRA. There exists the possibility of a denial
- * of service attack here by allowing non-root processes running
- * on a local machine sending many of these pending messages to
- * a smbd port. Currently I'm not sure how to restrict the messages
- * I will queue (although I could add a limit to the queue) to
- * those received by root processes only. There should be a
- * way to make this bulletproof....
- */
-
- reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
- reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
-
- reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
-
- if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
- {
- /* Ignore it. */
- DEBUG(0,("request_oplock_break: invalid message length received. Ignoring\n"));
- continue;
- }
-
- if(((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) == 0) ||
- (reply_from_port != share_entry->op_port) ||
- (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
- &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
- OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) != 0))
- {
- DEBUG(3,("request_oplock_break: received other message whilst awaiting \
-oplock break response from pid %d on port %d for dev = %x, inode = %x.\n",
- share_entry->pid, share_entry->op_port, dev, inode));
- if(push_local_message(op_break_reply, sizeof(op_break_reply)) == False)
- return False;
- continue;
- }
-
- break;
- }
-
- DEBUG(3,("request_oplock_break: broke oplock.\n"));
-
- return True;
-}
-
-/****************************************************************************
-check if a snum is in use
-****************************************************************************/
-BOOL snum_used(int snum)
-{
- int i;
- for (i=0;i<MAX_CONNECTIONS;i++)
- if (OPEN_CNUM(i) && (SNUM(i) == snum))
- return(True);
- return(False);
-}
-
-/****************************************************************************
- reload the services file
- **************************************************************************/
-BOOL reload_services(BOOL test)
-{
- BOOL ret;
-
- if (lp_loaded())
- {
- pstring fname;
- pstrcpy(fname,lp_configfile());
- if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
- {
- pstrcpy(servicesf,fname);
- test = False;
- }
- }
-
- reopen_logs();
-
- if (test && !lp_file_list_changed())
- return(True);
-
- lp_killunused(snum_used);
-
- ret = lp_load(servicesf,False);
-
- /* perhaps the config filename is now set */
- if (!test)
- reload_services(True);
-
- reopen_logs();
-
- load_interfaces();
-
- {
- extern int Client;
- if (Client != -1) {
- set_socket_options(Client,"SO_KEEPALIVE");
- set_socket_options(Client,user_socket_options);
- }
- }
-
- create_mangled_stack(lp_mangledstack());
-
- /* this forces service parameters to be flushed */
- become_service(-1,True);
-
- return(ret);
-}
-
-
-
-/****************************************************************************
-this prevents zombie child processes
-****************************************************************************/
-static int sig_hup()
-{
- BlockSignals(True,SIGHUP);
- DEBUG(0,("Got SIGHUP\n"));
- reload_services(False);
-#ifndef DONT_REINSTALL_SIG
- signal(SIGHUP,SIGNAL_CAST sig_hup);
-#endif
- BlockSignals(False,SIGHUP);
- return(0);
-}
-
-/****************************************************************************
-Setup the groups a user belongs to.
-****************************************************************************/
-int setup_groups(char *user, int uid, int gid, int *p_ngroups,
- int **p_igroups, gid_t **p_groups)
-{
- if (-1 == initgroups(user,gid))
- {
- if (getuid() == 0)
- {
- DEBUG(0,("Unable to initgroups!\n"));
- if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
- DEBUG(0,("This is probably a problem with the account %s\n",user));
- }
- }
- else
- {
- int i,ngroups;
- int *igroups;
- gid_t grp = 0;
- ngroups = getgroups(0,&grp);
- if (ngroups <= 0)
- ngroups = 32;
- igroups = (int *)malloc(sizeof(int)*ngroups);
- for (i=0;i<ngroups;i++)
- igroups[i] = 0x42424242;
- ngroups = getgroups(ngroups,(gid_t *)igroups);
-
- if (igroups[0] == 0x42424242)
- ngroups = 0;
-
- *p_ngroups = ngroups;
-
- /* The following bit of code is very strange. It is due to the
- fact that some OSes use int* and some use gid_t* for
- getgroups, and some (like SunOS) use both, one in prototypes,
- and one in man pages and the actual code. Thus we detect it
- dynamically using some very ugly code */
- if (ngroups > 0)
- {
- /* does getgroups return ints or gid_t ?? */
- static BOOL groups_use_ints = True;
-
- if (groups_use_ints &&
- ngroups == 1 &&
- SVAL(igroups,2) == 0x4242)
- groups_use_ints = False;
-
- for (i=0;groups_use_ints && i<ngroups;i++)
- if (igroups[i] == 0x42424242)
- groups_use_ints = False;
-
- if (groups_use_ints)
- {
- *p_igroups = igroups;
- *p_groups = (gid_t *)igroups;
- }
- else
- {
- gid_t *groups = (gid_t *)igroups;
- igroups = (int *)malloc(sizeof(int)*ngroups);
- for (i=0;i<ngroups;i++)
- igroups[i] = groups[i];
- *p_igroups = igroups;
- *p_groups = (gid_t *)groups;
- }
- }
- DEBUG(3,("%s is in %d groups\n",user,ngroups));
- for (i=0;i<ngroups;i++)
- DEBUG(3,("%d ",igroups[i]));
- DEBUG(3,("\n"));
- }
- return 0;
-}
-
-/****************************************************************************
- make a connection to a service
-****************************************************************************/
-int make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid)
-{
- int cnum;
- int snum;
- struct passwd *pass = NULL;
- connection_struct *pcon;
- BOOL guest = False;
- BOOL force = False;
- static BOOL first_connection = True;
-
- strlower(service);
-
- snum = find_service(service);
- if (snum < 0)
- {
- if (strequal(service,"IPC$"))
- {
- DEBUG(3,("%s refusing IPC connection\n",timestring()));
- return(-3);
- }
-
- DEBUG(0,("%s couldn't find service %s\n",timestring(),service));
- return(-2);
- }
-
- if (strequal(service,HOMES_NAME))
- {
- if (*user && Get_Pwnam(user,True))
- return(make_connection(user,user,password,pwlen,dev,vuid));
-
- if (validated_username(vuid))
- {
- strcpy(user,validated_username(vuid));
- return(make_connection(user,user,password,pwlen,dev,vuid));
- }
- }
-
- if (!lp_snum_ok(snum) || !check_access(snum)) {
- return(-4);
- }
-
- /* you can only connect to the IPC$ service as an ipc device */
- if (strequal(service,"IPC$"))
- strcpy(dev,"IPC");
-
- if (*dev == '?' || !*dev)
- {
- if (lp_print_ok(snum))
- strcpy(dev,"LPT1:");
- else
- strcpy(dev,"A:");
- }
-
- /* if the request is as a printer and you can't print then refuse */
- strupper(dev);
- if (!lp_print_ok(snum) && (strncmp(dev,"LPT",3) == 0)) {
- DEBUG(1,("Attempt to connect to non-printer as a printer\n"));
- return(-6);
- }
-
- /* lowercase the user name */
- strlower(user);
-
- /* add it as a possible user name */
- add_session_user(service);
-
- /* shall we let them in? */
- if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid))
- {
- DEBUG(2,("%s invalid username/password for %s\n",timestring(),service));
- return(-1);
- }
-
- cnum = find_free_connection(str_checksum(service) + str_checksum(user));
- if (cnum < 0)
- {
- DEBUG(0,("%s couldn't find free connection\n",timestring()));
- return(-1);
- }
-
- pcon = &Connections[cnum];
- bzero((char *)pcon,sizeof(*pcon));
-
- /* find out some info about the user */
- pass = Get_Pwnam(user,True);
-
- if (pass == NULL)
- {
- DEBUG(0,("%s couldn't find account %s\n",timestring(),user));
- return(-7);
- }
-
- pcon->read_only = lp_readonly(snum);
-
- {
- pstring list;
- StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
- string_sub(list,"%S",service);
-
- if (user_in_list(user,list))
- pcon->read_only = True;
-
- StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
- string_sub(list,"%S",service);
-
- if (user_in_list(user,list))
- pcon->read_only = False;
- }
-
- /* admin user check */
-
- /* JRA - original code denied admin user if the share was
- marked read_only. Changed as I don't think this is needed,
- but old code left in case there is a problem here.
- */
- if (user_in_list(user,lp_admin_users(snum))
-#if 0
- && !pcon->read_only)
-#else
- )
-#endif
- {
- pcon->admin_user = True;
- DEBUG(0,("%s logged in as admin user (root privileges)\n",user));
- }
- else
- pcon->admin_user = False;
-
- pcon->force_user = force;
- pcon->vuid = vuid;
- pcon->uid = pass->pw_uid;
- pcon->gid = pass->pw_gid;
- pcon->num_files_open = 0;
- pcon->lastused = time(NULL);
- pcon->service = snum;
- pcon->used = True;
- pcon->printer = (strncmp(dev,"LPT",3) == 0);
- pcon->ipc = (strncmp(dev,"IPC",3) == 0);
- pcon->dirptr = NULL;
- pcon->veto_list = NULL;
- pcon->hide_list = NULL;
- string_set(&pcon->dirpath,"");
- string_set(&pcon->user,user);
-
-#if HAVE_GETGRNAM
- if (*lp_force_group(snum))
- {
- struct group *gptr;
- pstring gname;
-
- StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
- /* default service may be a group name */
- string_sub(gname,"%S",service);
- gptr = (struct group *)getgrnam(gname);
-
- if (gptr)
- {
- pcon->gid = gptr->gr_gid;
- DEBUG(3,("Forced group %s\n",gname));
- }
- else
- DEBUG(1,("Couldn't find group %s\n",gname));
- }
-#endif
-
- if (*lp_force_user(snum))
- {
- struct passwd *pass2;
- fstring fuser;
- fstrcpy(fuser,lp_force_user(snum));
- pass2 = (struct passwd *)Get_Pwnam(fuser,True);
- if (pass2)
- {
- pcon->uid = pass2->pw_uid;
- string_set(&pcon->user,fuser);
- fstrcpy(user,fuser);
- pcon->force_user = True;
- DEBUG(3,("Forced user %s\n",fuser));
- }
- else
- DEBUG(1,("Couldn't find user %s\n",fuser));
- }
-
- {
- pstring s;
- pstrcpy(s,lp_pathname(snum));
- standard_sub(cnum,s);
- string_set(&pcon->connectpath,s);
- DEBUG(3,("Connect path is %s\n",s));
- }
-
- /* groups stuff added by ih */
- pcon->ngroups = 0;
- pcon->groups = NULL;
-
- if (!IS_IPC(cnum))
- {
- /* Find all the groups this uid is in and store them. Used by become_user() */
- setup_groups(pcon->user,pcon->uid,pcon->gid,&pcon->ngroups,&pcon->igroups,&pcon->groups);
-
- /* check number of connections */
- if (!claim_connection(cnum,
- lp_servicename(SNUM(cnum)),
- lp_max_connections(SNUM(cnum)),False))
- {
- DEBUG(1,("too many connections - rejected\n"));
- return(-8);
- }
-
- if (lp_status(SNUM(cnum)))
- claim_connection(cnum,"STATUS.",MAXSTATUS,first_connection);
-
- first_connection = False;
- } /* IS_IPC */
-
- pcon->open = True;
-
- /* execute any "root preexec = " line */
- if (*lp_rootpreexec(SNUM(cnum)))
- {
- pstring cmd;
- pstrcpy(cmd,lp_rootpreexec(SNUM(cnum)));
- standard_sub(cnum,cmd);
- DEBUG(5,("cmd=%s\n",cmd));
- smbrun(cmd,NULL,False);
- }
-
- if (!become_user(cnum,pcon->vuid))
- {
- DEBUG(0,("Can't become connected user!\n"));
- pcon->open = False;
- if (!IS_IPC(cnum)) {
- yield_connection(cnum,
- lp_servicename(SNUM(cnum)),
- lp_max_connections(SNUM(cnum)));
- if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
- }
- return(-1);
- }
-
- if (ChDir(pcon->connectpath) != 0)
- {
- DEBUG(0,("Can't change directory to %s (%s)\n",
- pcon->connectpath,strerror(errno)));
- pcon->open = False;
- unbecome_user();
- if (!IS_IPC(cnum)) {
- yield_connection(cnum,
- lp_servicename(SNUM(cnum)),
- lp_max_connections(SNUM(cnum)));
- if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS);
- }
- return(-5);
- }
-
- string_set(&pcon->origpath,pcon->connectpath);
-
-#if SOFTLINK_OPTIMISATION
- /* resolve any soft links early */
- {
- pstring s;
- pstrcpy(s,pcon->connectpath);
- GetWd(s);
- string_set(&pcon->connectpath,s);
- ChDir(pcon->connectpath);
- }
-#endif
-
- num_connections_open++;
- add_session_user(user);
-
- /* execute any "preexec = " line */
- if (*lp_preexec(SNUM(cnum)))
- {
- pstring cmd;
- pstrcpy(cmd,lp_preexec(SNUM(cnum)));
- standard_sub(cnum,cmd);
- smbrun(cmd,NULL,False);
- }
-
- /* we've finished with the sensitive stuff */
- unbecome_user();
-
- /* Add veto/hide lists */
- if (!IS_IPC(cnum) && !IS_PRINT(cnum))
- {
- set_namearray( &pcon->veto_list, lp_veto_files(SNUM(cnum)));
- set_namearray( &pcon->hide_list, lp_hide_files(SNUM(cnum)));
- }
-
- {
- DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) connect to service %s as user %s (uid=%d,gid=%d) (pid %d)\n",
- timestring(),
- remote_machine,
- client_addr(),
- lp_servicename(SNUM(cnum)),user,
- pcon->uid,
- pcon->gid,
- (int)getpid()));
- }
-
- return(cnum);
-}
-
-
-/****************************************************************************
- find first available file slot
-****************************************************************************/
-int find_free_file(void )
-{
- int i;
- /* we start at 1 here for an obscure reason I can't now remember,
- but I think is important :-) */
- for (i=1;i<MAX_OPEN_FILES;i++)
- if (!Files[i].open)
- return(i);
- DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n"));
- return(-1);
-}
-
-/****************************************************************************
- find first available connection slot, starting from a random position.
-The randomisation stops problems with the server dieing and clients
-thinking the server is still available.
-****************************************************************************/
-static int find_free_connection(int hash )
-{
- int i;
- BOOL used=False;
- hash = (hash % (MAX_CONNECTIONS-2))+1;
-
- again:
-
- for (i=hash+1;i!=hash;)
- {
- if (!Connections[i].open && Connections[i].used == used)
- {
- DEBUG(3,("found free connection number %d\n",i));
- return(i);
- }
- i++;
- if (i == MAX_CONNECTIONS)
- i = 1;
- }
-
- if (!used)
- {
- used = !used;
- goto again;
- }
-
- DEBUG(1,("ERROR! Out of connection structures\n"));
- return(-1);
-}
-
-
-/****************************************************************************
-reply for the core protocol
-****************************************************************************/
-int reply_corep(char *outbuf)
-{
- int outsize = set_message(outbuf,1,0,True);
-
- Protocol = PROTOCOL_CORE;
-
- return outsize;
-}
-
-
-/****************************************************************************
-reply for the coreplus protocol
-****************************************************************************/
-int reply_coreplus(char *outbuf)
-{
- int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
- int outsize = set_message(outbuf,13,0,True);
- SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
- readbraw and writebraw (possibly) */
- CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
- SSVAL(outbuf,smb_vwv1,0x1); /* user level security, don't encrypt */
-
- Protocol = PROTOCOL_COREPLUS;
-
- return outsize;
-}
-
-
-/****************************************************************************
-reply for the lanman 1.0 protocol
-****************************************************************************/
-int reply_lanman1(char *outbuf)
-{
- int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
- int secword=0;
- BOOL doencrypt = SMBENCRYPT();
- time_t t = time(NULL);
- /* We need to save and restore this as it can be destroyed
- if we call another server if security=server
- Thanks to Paul Nelson @ Thursby for pointing this out.
- */
- uint16 mid = SVAL(outbuf, smb_mid);
-
- if (lp_security()>=SEC_USER) secword |= 1;
- if (doencrypt) secword |= 2;
-
- set_message(outbuf,13,doencrypt?8:0,True);
- SSVAL(outbuf,smb_vwv1,secword);
- /* Create a token value and add it to the outgoing packet. */
- if (doencrypt)
- generate_next_challenge(smb_buf(outbuf));
-
- Protocol = PROTOCOL_LANMAN1;
-
- if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
- DEBUG(3,("using password server validation\n"));
- if (doencrypt) set_challenge(smb_buf(outbuf));
- }
-
- CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
- SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
- SSVAL(outbuf,smb_vwv2,max_recv);
- SSVAL(outbuf,smb_vwv3,lp_maxmux()); /* maxmux */
- SSVAL(outbuf,smb_vwv4,1);
- SSVAL(outbuf,smb_vwv5,raw); /* tell redirector we support
- readbraw writebraw (possibly) */
- SIVAL(outbuf,smb_vwv6,getpid());
- SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
-
- put_dos_date(outbuf,smb_vwv8,t);
-
- return (smb_len(outbuf)+4);
-}
-
-
-/****************************************************************************
-reply for the lanman 2.0 protocol
-****************************************************************************/
-int reply_lanman2(char *outbuf)
-{
- int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
- int secword=0;
- BOOL doencrypt = SMBENCRYPT();
- time_t t = time(NULL);
- /* We need to save and restore this as it can be destroyed
- if we call another server if security=server
- Thanks to Paul Nelson @ Thursby for pointing this out.
- */
- uint16 mid = SVAL(outbuf, smb_mid);
-
- if (lp_security()>=SEC_USER) secword |= 1;
- if (doencrypt) secword |= 2;
-
- set_message(outbuf,13,doencrypt?8:0,True);
- SSVAL(outbuf,smb_vwv1,secword);
- /* Create a token value and add it to the outgoing packet. */
- if (doencrypt)
- generate_next_challenge(smb_buf(outbuf));
-
- SIVAL(outbuf,smb_vwv6,getpid());
-
- Protocol = PROTOCOL_LANMAN2;
-
- if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
- DEBUG(3,("using password server validation\n"));
- if (doencrypt) set_challenge(smb_buf(outbuf));
- }
-
- CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */
- SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
- SSVAL(outbuf,smb_vwv2,max_recv);
- SSVAL(outbuf,smb_vwv3,lp_maxmux());
- SSVAL(outbuf,smb_vwv4,1);
- SSVAL(outbuf,smb_vwv5,raw); /* readbraw and/or writebraw */
- SSVAL(outbuf,smb_vwv10, TimeDiff(t)/60);
- put_dos_date(outbuf,smb_vwv8,t);
-
- return (smb_len(outbuf)+4);
-}
-
-
-/****************************************************************************
-reply for the nt protocol
-****************************************************************************/
-int reply_nt1(char *outbuf)
-{
- /* dual names + lock_and_read + nt SMBs + remote API calls */
- int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
-/*
- other valid capabilities which we may support at some time...
- CAP_LARGE_FILES|CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
- CAP_LARGE_FILES|CAP_LARGE_READX|
- CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
- */
-
- int secword=0;
- BOOL doencrypt = SMBENCRYPT();
- time_t t = time(NULL);
- int data_len;
- int encrypt_len;
- char challenge_len = 8;
- /* We need to save and restore this as it can be destroyed
- if we call another server if security=server
- Thanks to Paul Nelson @ Thursby for pointing this out.
- */
- uint16 mid = SVAL(outbuf, smb_mid);
-
- if (lp_readraw() && lp_writeraw())
- {
- capabilities |= CAP_RAW_MODE;
- }
-
- if (lp_security()>=SEC_USER) secword |= 1;
- if (doencrypt) secword |= 2;
-
- /* decide where (if) to put the encryption challenge, and
- follow it with the OEM'd domain name
- */
- encrypt_len = doencrypt?challenge_len:0;
-#if UNICODE
- data_len = encrypt_len + 2*(strlen(myworkgroup)+1);
-#else
- data_len = encrypt_len + strlen(myworkgroup) + 1;
-#endif
-
- set_message(outbuf,17,data_len,True);
-
-#if UNICODE
- /* put the OEM'd domain name */
- PutUniCode(smb_buf(outbuf)+encrypt_len,myworkgroup);
-#else
- strcpy(smb_buf(outbuf)+encrypt_len, myworkgroup);
-#endif
-
- CVAL(outbuf,smb_vwv1) = secword;
- /* Create a token value and add it to the outgoing packet. */
- if (doencrypt)
- {
- generate_next_challenge(smb_buf(outbuf));
-
- /* Tell the nt machine how long the challenge is. */
- SSVALS(outbuf,smb_vwv16+1,challenge_len);
- }
-
- Protocol = PROTOCOL_NT1;
-
- if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) {
- DEBUG(3,("using password server validation\n"));
- if (doencrypt) set_challenge(smb_buf(outbuf));
- }
-
- SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */
- SSVAL(outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
- SSVAL(outbuf,smb_vwv2+1,1); /* num vcs */
- SIVAL(outbuf,smb_vwv3+1,0xffff); /* max buffer. LOTS! */
- SIVAL(outbuf,smb_vwv5+1,0xffff); /* raw size. LOTS! */
- SIVAL(outbuf,smb_vwv7+1,getpid()); /* session key */
- SIVAL(outbuf,smb_vwv9+1,capabilities); /* capabilities */
- put_long_date(outbuf+smb_vwv11+1,t);
- SSVALS(outbuf,smb_vwv15+1,TimeDiff(t)/60);
- SSVAL(outbuf,smb_vwv17,data_len); /* length of challenge+domain strings */
-
- return (smb_len(outbuf)+4);
-}
-
-/* these are the protocol lists used for auto architecture detection:
-
-WinNT 3.51:
-protocol [PC NETWORK PROGRAM 1.0]
-protocol [XENIX CORE]
-protocol [MICROSOFT NETWORKS 1.03]
-protocol [LANMAN1.0]
-protocol [Windows for Workgroups 3.1a]
-protocol [LM1.2X002]
-protocol [LANMAN2.1]
-protocol [NT LM 0.12]
-
-Win95:
-protocol [PC NETWORK PROGRAM 1.0]
-protocol [XENIX CORE]
-protocol [MICROSOFT NETWORKS 1.03]
-protocol [LANMAN1.0]
-protocol [Windows for Workgroups 3.1a]
-protocol [LM1.2X002]
-protocol [LANMAN2.1]
-protocol [NT LM 0.12]
-
-OS/2:
-protocol [PC NETWORK PROGRAM 1.0]
-protocol [XENIX CORE]
-protocol [LANMAN1.0]
-protocol [LM1.2X002]
-protocol [LANMAN2.1]
-*/
-
-/*
- * Modified to recognize the architecture of the remote machine better.
- *
- * This appears to be the matrix of which protocol is used by which
- * MS product.
- Protocol WfWg Win95 WinNT OS/2
- PC NETWORK PROGRAM 1.0 1 1 1 1
- XENIX CORE 2 2
- MICROSOFT NETWORKS 3.0 2 2
- DOS LM1.2X002 3 3
- MICROSOFT NETWORKS 1.03 3
- DOS LANMAN2.1 4 4
- LANMAN1.0 4 3
- Windows for Workgroups 3.1a 5 5 5
- LM1.2X002 6 4
- LANMAN2.1 7 5
- NT LM 0.12 6 8
- *
- * tim@fsg.com 09/29/95
- */
-
-#define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
-#define ARCH_WIN95 0x2
-#define ARCH_OS2 0xC /* Again OS/2 is like NT */
-#define ARCH_WINNT 0x8
-#define ARCH_SAMBA 0x10
-
-#define ARCH_ALL 0x1F
-
-/* List of supported protocols, most desired first */
-struct {
- char *proto_name;
- char *short_name;
- int (*proto_reply_fn)(char *);
- int protocol_level;
-} supported_protocols[] = {
- {"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
- {"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
- {"LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
- {"Samba", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
- {"DOS LM1.2X002", "LANMAN2", reply_lanman2, PROTOCOL_LANMAN2},
- {"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
- {"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
- {"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
- {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
- {NULL,NULL},
-};
-
-
-/****************************************************************************
- reply to a negprot
-****************************************************************************/
-static int reply_negprot(char *inbuf,char *outbuf)
-{
- int outsize = set_message(outbuf,1,0,True);
- int Index=0;
- int choice= -1;
- int protocol;
- char *p;
- int bcc = SVAL(smb_buf(inbuf),-2);
- int arch = ARCH_ALL;
-
- p = smb_buf(inbuf)+1;
- while (p < (smb_buf(inbuf) + bcc))
- {
- Index++;
- DEBUG(3,("Requested protocol [%s]\n",p));
- if (strcsequal(p,"Windows for Workgroups 3.1a"))
- arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
- else if (strcsequal(p,"DOS LM1.2X002"))
- arch &= ( ARCH_WFWG | ARCH_WIN95 );
- else if (strcsequal(p,"DOS LANMAN2.1"))
- arch &= ( ARCH_WFWG | ARCH_WIN95 );
- else if (strcsequal(p,"NT LM 0.12"))
- arch &= ( ARCH_WIN95 | ARCH_WINNT );
- else if (strcsequal(p,"LANMAN2.1"))
- arch &= ( ARCH_WINNT | ARCH_OS2 );
- else if (strcsequal(p,"LM1.2X002"))
- arch &= ( ARCH_WINNT | ARCH_OS2 );
- else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
- arch &= ARCH_WINNT;
- else if (strcsequal(p,"XENIX CORE"))
- arch &= ( ARCH_WINNT | ARCH_OS2 );
- else if (strcsequal(p,"Samba")) {
- arch = ARCH_SAMBA;
- break;
- }
-
- p += strlen(p) + 2;
- }
-
- switch ( arch ) {
- case ARCH_SAMBA:
- set_remote_arch(RA_SAMBA);
- break;
- case ARCH_WFWG:
- set_remote_arch(RA_WFWG);
- break;
- case ARCH_WIN95:
- set_remote_arch(RA_WIN95);
- break;
- case ARCH_WINNT:
- set_remote_arch(RA_WINNT);
- break;
- case ARCH_OS2:
- set_remote_arch(RA_OS2);
- break;
- default:
- set_remote_arch(RA_UNKNOWN);
- break;
- }
-
- /* possibly reload - change of architecture */
- reload_services(True);
-
- /* a special case to stop password server loops */
- if (Index == 1 && strequal(remote_machine,myhostname) &&
- lp_security()==SEC_SERVER)
- exit_server("Password server loop!");
-
- /* Check for protocols, most desirable first */
- for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
- {
- p = smb_buf(inbuf)+1;
- Index = 0;
- if (lp_maxprotocol() >= supported_protocols[protocol].protocol_level)
- while (p < (smb_buf(inbuf) + bcc))
- {
- if (strequal(p,supported_protocols[protocol].proto_name))
- choice = Index;
- Index++;
- p += strlen(p) + 2;
- }
- if(choice != -1)
- break;
- }
-
- SSVAL(outbuf,smb_vwv0,choice);
- if(choice != -1) {
- extern fstring remote_proto;
- fstrcpy(remote_proto,supported_protocols[protocol].short_name);
- reload_services(True);
- outsize = supported_protocols[protocol].proto_reply_fn(outbuf);
- DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
- }
- else {
- DEBUG(0,("No protocol supported !\n"));
- }
- SSVAL(outbuf,smb_vwv0,choice);
-
- DEBUG(5,("%s negprot index=%d\n",timestring(),choice));
-
- return(outsize);
-}
-
-
-/****************************************************************************
-close all open files for a connection
-****************************************************************************/
-static void close_open_files(int cnum)
-{
- int i;
- for (i=0;i<MAX_OPEN_FILES;i++)
- if( Files[i].cnum == cnum && Files[i].open) {
- close_file(i);
- }
-}
-
-
-
-/****************************************************************************
-close a cnum
-****************************************************************************/
-void close_cnum(int cnum, uint16 vuid)
-{
- DirCacheFlush(SNUM(cnum));
-
- unbecome_user();
-
- if (!OPEN_CNUM(cnum))
- {
- DEBUG(0,("Can't close cnum %d\n",cnum));
- return;
- }
-
- DEBUG(IS_IPC(cnum)?3:1,("%s %s (%s) closed connection to service %s\n",
- timestring(),
- remote_machine,client_addr(),
- lp_servicename(SNUM(cnum))));
-
- yield_connection(cnum,
- lp_servicename(SNUM(cnum)),
- lp_max_connections(SNUM(cnum)));
-
- if (lp_status(SNUM(cnum)))
- yield_connection(cnum,"STATUS.",MAXSTATUS);
-
- close_open_files(cnum);
- dptr_closecnum(cnum);
-
- /* execute any "postexec = " line */
- if (*lp_postexec(SNUM(cnum)) && become_user(cnum,vuid))
- {
- pstring cmd;
- strcpy(cmd,lp_postexec(SNUM(cnum)));
- standard_sub(cnum,cmd);
- smbrun(cmd,NULL,False);
- unbecome_user();
- }
-
- unbecome_user();
- /* execute any "root postexec = " line */
- if (*lp_rootpostexec(SNUM(cnum)))
- {
- pstring cmd;
- strcpy(cmd,lp_rootpostexec(SNUM(cnum)));
- standard_sub(cnum,cmd);
- smbrun(cmd,NULL,False);
- }
-
- Connections[cnum].open = False;
- num_connections_open--;
- if (Connections[cnum].ngroups && Connections[cnum].groups)
- {
- if (Connections[cnum].igroups != (int *)Connections[cnum].groups)
- free(Connections[cnum].groups);
- free(Connections[cnum].igroups);
- Connections[cnum].groups = NULL;
- Connections[cnum].igroups = NULL;
- Connections[cnum].ngroups = 0;
- }
-
- free_namearray(Connections[cnum].veto_list);
- free_namearray(Connections[cnum].hide_list);
-
- string_set(&Connections[cnum].user,"");
- string_set(&Connections[cnum].dirpath,"");
- string_set(&Connections[cnum].connectpath,"");
-}
-
-
-/****************************************************************************
-simple routines to do connection counting
-****************************************************************************/
-BOOL yield_connection(int cnum,char *name,int max_connections)
-{
- struct connect_record crec;
- pstring fname;
- FILE *f;
- int mypid = getpid();
- int i;
-
- DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
-
- if (max_connections <= 0)
- return(True);
-
- bzero(&crec,sizeof(crec));
-
- pstrcpy(fname,lp_lockdir());
- standard_sub(cnum,fname);
- trim_string(fname,"","/");
-
- strcat(fname,"/");
- strcat(fname,name);
- strcat(fname,".LCK");
-
- f = fopen(fname,"r+");
- if (!f)
- {
- DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
- return(False);
- }
-
- fseek(f,0,SEEK_SET);
-
- /* find a free spot */
- for (i=0;i<max_connections;i++)
- {
- if (fread(&crec,sizeof(crec),1,f) != 1)
- {
- DEBUG(2,("Entry not found in lock file %s\n",fname));
- fclose(f);
- return(False);
- }
- if (crec.pid == mypid && crec.cnum == cnum)
- break;
- }
-
- if (crec.pid != mypid || crec.cnum != cnum)
- {
- fclose(f);
- DEBUG(2,("Entry not found in lock file %s\n",fname));
- return(False);
- }
-
- bzero((void *)&crec,sizeof(crec));
-
- /* remove our mark */
- if (fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
- fwrite(&crec,sizeof(crec),1,f) != 1)
- {
- DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
- fclose(f);
- return(False);
- }
-
- DEBUG(3,("Yield successful\n"));
-
- fclose(f);
- return(True);
-}
-
-
-/****************************************************************************
-simple routines to do connection counting
-****************************************************************************/
-BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear)
-{
- struct connect_record crec;
- pstring fname;
- FILE *f;
- int snum = SNUM(cnum);
- int i,foundi= -1;
- int total_recs;
-
- if (max_connections <= 0)
- return(True);
-
- DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
-
- pstrcpy(fname,lp_lockdir());
- standard_sub(cnum,fname);
- trim_string(fname,"","/");
-
- if (!directory_exist(fname,NULL))
- mkdir(fname,0755);
-
- strcat(fname,"/");
- strcat(fname,name);
- strcat(fname,".LCK");
-
- if (!file_exist(fname,NULL))
- {
- int oldmask = umask(022);
- f = fopen(fname,"w");
- if (f) fclose(f);
- umask(oldmask);
- }
-
- total_recs = file_size(fname) / sizeof(crec);
-
- f = fopen(fname,"r+");
-
- if (!f)
- {
- DEBUG(1,("couldn't open lock file %s\n",fname));
- return(False);
- }
-
- /* find a free spot */
- for (i=0;i<max_connections;i++)
- {
-
- if (i>=total_recs ||
- fseek(f,i*sizeof(crec),SEEK_SET) != 0 ||
- fread(&crec,sizeof(crec),1,f) != 1)
- {
- if (foundi < 0) foundi = i;
- break;
- }
-
- if (Clear && crec.pid && !process_exists(crec.pid))
- {
- fseek(f,i*sizeof(crec),SEEK_SET);
- bzero((void *)&crec,sizeof(crec));
- fwrite(&crec,sizeof(crec),1,f);
- if (foundi < 0) foundi = i;
- continue;
- }
- if (foundi < 0 && (!crec.pid || !process_exists(crec.pid)))
- {
- foundi=i;
- if (!Clear) break;
- }
- }
-
- if (foundi < 0)
- {
- DEBUG(3,("no free locks in %s\n",fname));
- fclose(f);
- return(False);
- }
-
- /* fill in the crec */
- bzero((void *)&crec,sizeof(crec));
- crec.magic = 0x280267;
- crec.pid = getpid();
- crec.cnum = cnum;
- crec.uid = Connections[cnum].uid;
- crec.gid = Connections[cnum].gid;
- StrnCpy(crec.name,lp_servicename(snum),sizeof(crec.name)-1);
- crec.start = time(NULL);
-
- StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
- StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
-
- /* make our mark */
- if (fseek(f,foundi*sizeof(crec),SEEK_SET) != 0 ||
- fwrite(&crec,sizeof(crec),1,f) != 1)
- {
- fclose(f);
- return(False);
- }
-
- fclose(f);
- return(True);
-}
-
-#if DUMP_CORE
-/*******************************************************************
-prepare to dump a core file - carefully!
-********************************************************************/
-static BOOL dump_core(void)
-{
- char *p;
- pstring dname;
- pstrcpy(dname,debugf);
- if ((p=strrchr(dname,'/'))) *p=0;
- strcat(dname,"/corefiles");
- mkdir(dname,0700);
- sys_chown(dname,getuid(),getgid());
- chmod(dname,0700);
- if (chdir(dname)) return(False);
- umask(~(0700));
-
-#ifndef NO_GETRLIMIT
-#ifdef RLIMIT_CORE
- {
- struct rlimit rlp;
- getrlimit(RLIMIT_CORE, &rlp);
- rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
- setrlimit(RLIMIT_CORE, &rlp);
- getrlimit(RLIMIT_CORE, &rlp);
- DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
- }
-#endif
-#endif
-
-
- DEBUG(0,("Dumping core in %s\n",dname));
- return(True);
-}
-#endif
-
-/****************************************************************************
-exit the server
-****************************************************************************/
-void exit_server(char *reason)
-{
- static int firsttime=1;
- int i;
-
- if (!firsttime) exit(0);
- firsttime = 0;
-
- unbecome_user();
- DEBUG(2,("Closing connections\n"));
- for (i=0;i<MAX_CONNECTIONS;i++)
- if (Connections[i].open)
- close_cnum(i,(uint16)-1);
-#ifdef DFS_AUTH
- if (dcelogin_atmost_once)
- dfs_unlogin();
-#endif
- if (!reason) {
- int oldlevel = DEBUGLEVEL;
- DEBUGLEVEL = 10;
- DEBUG(0,("Last message was %s\n",smb_fn_name(last_message)));
- if (last_inbuf)
- show_msg(last_inbuf);
- DEBUGLEVEL = oldlevel;
- DEBUG(0,("===============================================================\n"));
-#if DUMP_CORE
- if (dump_core()) return;
-#endif
- }
-
-#ifdef FAST_SHARE_MODES
- stop_share_mode_mgmt();
-#endif /* FAST_SHARE_MODES */
-
- DEBUG(3,("%s Server exit (%s)\n",timestring(),reason?reason:""));
- exit(0);
-}
-
-/****************************************************************************
-do some standard substitutions in a string
-****************************************************************************/
-void standard_sub(int cnum,char *str)
-{
- if (VALID_CNUM(cnum)) {
- char *p, *s, *home;
-
- for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) {
- switch (*(p+1)) {
- case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL)
- string_sub(p,"%H",home);
- else
- p += 2;
- break;
- case 'P' : string_sub(p,"%P",Connections[cnum].connectpath); break;
- case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break;
- case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break;
- case 'u' : string_sub(p,"%u",Connections[cnum].user); break;
- case '\0' : p++; break; /* don't run off the end of the string */
- default : p+=2; break;
- }
- }
- }
- standard_sub_basic(str);
-}
-
-/*
-These flags determine some of the permissions required to do an operation
-
-Note that I don't set NEED_WRITE on some write operations because they
-are used by some brain-dead clients when printing, and I don't want to
-force write permissions on print services.
-*/
-#define AS_USER (1<<0)
-#define NEED_WRITE (1<<1)
-#define TIME_INIT (1<<2)
-#define CAN_IPC (1<<3)
-#define AS_GUEST (1<<5)
-
-
-/*
- define a list of possible SMB messages and their corresponding
- functions. Any message that has a NULL function is unimplemented -
- please feel free to contribute implementations!
-*/
-struct smb_message_struct
-{
- int code;
- char *name;
- int (*fn)();
- int flags;
-#if PROFILING
- unsigned long time;
-#endif
-}
- smb_messages[] = {
-
- /* CORE PROTOCOL */
-
- {SMBnegprot,"SMBnegprot",reply_negprot,0},
- {SMBtcon,"SMBtcon",reply_tcon,0},
- {SMBtdis,"SMBtdis",reply_tdis,0},
- {SMBexit,"SMBexit",reply_exit,0},
- {SMBioctl,"SMBioctl",reply_ioctl,0},
- {SMBecho,"SMBecho",reply_echo,0},
- {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0},
- {SMBtconX,"SMBtconX",reply_tcon_and_X,0},
- {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
- {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER},
- {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
- {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER},
- {SMBsearch,"SMBsearch",reply_search,AS_USER},
- {SMBopen,"SMBopen",reply_open,AS_USER},
-
- /* note that SMBmknew and SMBcreate are deliberately overloaded */
- {SMBcreate,"SMBcreate",reply_mknew,AS_USER},
- {SMBmknew,"SMBmknew",reply_mknew,AS_USER},
-
- {SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE},
- {SMBread,"SMBread",reply_read,AS_USER},
- {SMBwrite,"SMBwrite",reply_write,AS_USER},
- {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
- {SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
- {SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
- {SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
- {SMBmv,"SMBmv",reply_mv,AS_USER | NEED_WRITE},
-
- /* this is a Pathworks specific call, allowing the
- changing of the root path */
- {pSETDIR,"pSETDIR",reply_setdir,AS_USER},
-
- {SMBlseek,"SMBlseek",reply_lseek,AS_USER},
- {SMBflush,"SMBflush",reply_flush,AS_USER},
- {SMBctemp,"SMBctemp",reply_ctemp,AS_USER},
- {SMBsplopen,"SMBsplopen",reply_printopen,AS_USER},
- {SMBsplclose,"SMBsplclose",reply_printclose,AS_USER},
- {SMBsplretq,"SMBsplretq",reply_printqueue,AS_USER|AS_GUEST},
- {SMBsplwr,"SMBsplwr",reply_printwrite,AS_USER},
- {SMBlock,"SMBlock",reply_lock,AS_USER},
- {SMBunlock,"SMBunlock",reply_unlock,AS_USER},
-
- /* CORE+ PROTOCOL FOLLOWS */
-
- {SMBreadbraw,"SMBreadbraw",reply_readbraw,AS_USER},
- {SMBwritebraw,"SMBwritebraw",reply_writebraw,AS_USER},
- {SMBwriteclose,"SMBwriteclose",reply_writeclose,AS_USER},
- {SMBlockread,"SMBlockread",reply_lockread,AS_USER},
- {SMBwriteunlock,"SMBwriteunlock",reply_writeunlock,AS_USER},
-
- /* LANMAN1.0 PROTOCOL FOLLOWS */
-
- {SMBreadBmpx,"SMBreadBmpx",reply_readbmpx,AS_USER},
- {SMBreadBs,"SMBreadBs",NULL,AS_USER},
- {SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
- {SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
- {SMBwritec,"SMBwritec",NULL,AS_USER},
- {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
- {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
- {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
- {SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
- {SMBioctls,"SMBioctls",NULL,AS_USER},
- {SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE},
- {SMBmove,"SMBmove",NULL,AS_USER | NEED_WRITE},
-
- {SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC},
- {SMBreadX,"SMBreadX",reply_read_and_X,AS_USER},
- {SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER},
- {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
-
- {SMBffirst,"SMBffirst",reply_search,AS_USER},
- {SMBfunique,"SMBfunique",reply_search,AS_USER},
- {SMBfclose,"SMBfclose",reply_fclose,AS_USER},
-
- /* LANMAN2.0 PROTOCOL FOLLOWS */
- {SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
- {SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
- {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER},
- {SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
-
- /* messaging routines */
- {SMBsends,"SMBsends",reply_sends,AS_GUEST},
- {SMBsendstrt,"SMBsendstrt",reply_sendstrt,AS_GUEST},
- {SMBsendend,"SMBsendend",reply_sendend,AS_GUEST},
- {SMBsendtxt,"SMBsendtxt",reply_sendtxt,AS_GUEST},
-
- /* NON-IMPLEMENTED PARTS OF THE CORE PROTOCOL */
-
- {SMBsendb,"SMBsendb",NULL,AS_GUEST},
- {SMBfwdname,"SMBfwdname",NULL,AS_GUEST},
- {SMBcancelf,"SMBcancelf",NULL,AS_GUEST},
- {SMBgetmac,"SMBgetmac",NULL,AS_GUEST}
- };
-
-/****************************************************************************
-return a string containing the function name of a SMB command
-****************************************************************************/
-char *smb_fn_name(int type)
-{
- static char *unknown_name = "SMBunknown";
- static int num_smb_messages =
- sizeof(smb_messages) / sizeof(struct smb_message_struct);
- int match;
-
- for (match=0;match<num_smb_messages;match++)
- if (smb_messages[match].code == type)
- break;
-
- if (match == num_smb_messages)
- return(unknown_name);
-
- return(smb_messages[match].name);
-}
-
-
-/****************************************************************************
-do a switch on the message type, and return the response size
-****************************************************************************/
-static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
-{
- static int pid= -1;
- int outsize = 0;
- static int num_smb_messages =
- sizeof(smb_messages) / sizeof(struct smb_message_struct);
- int match;
-
-#if PROFILING
- struct timeval msg_start_time;
- struct timeval msg_end_time;
- static unsigned long total_time = 0;
-
- GetTimeOfDay(&msg_start_time);
-#endif
-
- if (pid == -1)
- pid = getpid();
-
- errno = 0;
- last_message = type;
-
- /* make sure this is an SMB packet */
- if (strncmp(smb_base(inbuf),"\377SMB",4) != 0)
- {
- DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf)));
- return(-1);
- }
-
- for (match=0;match<num_smb_messages;match++)
- if (smb_messages[match].code == type)
- break;
-
- if (match == num_smb_messages)
- {
- DEBUG(0,("Unknown message type %d!\n",type));
- outsize = reply_unknown(inbuf,outbuf);
- }
- else
- {
- DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
- if (smb_messages[match].fn)
- {
- int cnum = SVAL(inbuf,smb_tid);
- int flags = smb_messages[match].flags;
- uint16 session_tag = SVAL(inbuf,smb_uid);
-
- /* does this protocol need to be run as root? */
- if (!(flags & AS_USER))
- unbecome_user();
-
- /* does this protocol need to be run as the connected user? */
- if ((flags & AS_USER) && !become_user(cnum,session_tag)) {
- if (flags & AS_GUEST)
- flags &= ~AS_USER;
- else
- return(ERROR(ERRSRV,ERRinvnid));
- }
- /* this code is to work around a bug is MS client 3 without
- introducing a security hole - it needs to be able to do
- print queue checks as guest if it isn't logged in properly */
- if (flags & AS_USER)
- flags &= ~AS_GUEST;
-
- /* does it need write permission? */
- if ((flags & NEED_WRITE) && !CAN_WRITE(cnum))
- return(ERROR(ERRSRV,ERRaccess));
-
- /* ipc services are limited */
- if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC))
- return(ERROR(ERRSRV,ERRaccess));
-
- /* load service specific parameters */
- if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False))
- return(ERROR(ERRSRV,ERRaccess));
-
- /* does this protocol need to be run as guest? */
- if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1)))
- return(ERROR(ERRSRV,ERRaccess));
-
- last_inbuf = inbuf;
-
- outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize);
- }
- else
- {
- outsize = reply_unknown(inbuf,outbuf);
- }
- }
-
-#if PROFILING
- GetTimeOfDay(&msg_end_time);
- if (!(smb_messages[match].flags & TIME_INIT))
- {
- smb_messages[match].time = 0;
- smb_messages[match].flags |= TIME_INIT;
- }
- {
- unsigned long this_time =
- (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 +
- (msg_end_time.tv_usec - msg_start_time.tv_usec);
- smb_messages[match].time += this_time;
- total_time += this_time;
- }
- DEBUG(2,("TIME %s %d usecs %g pct\n",
- smb_fn_name(type),smb_messages[match].time,
- (100.0*smb_messages[match].time) / total_time));
-#endif
-
- return(outsize);
-}
-
-
-/****************************************************************************
- construct a chained reply and add it to the already made reply
- **************************************************************************/
-int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
-{
- static char *orig_inbuf;
- static char *orig_outbuf;
- int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
- unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
- char *inbuf2, *outbuf2;
- int outsize2;
- char inbuf_saved[smb_wct];
- char outbuf_saved[smb_wct];
- extern int chain_size;
- int wct = CVAL(outbuf,smb_wct);
- int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
-
- /* maybe its not chained */
- if (smb_com2 == 0xFF) {
- CVAL(outbuf,smb_vwv0) = 0xFF;
- return outsize;
- }
-
- if (chain_size == 0) {
- /* this is the first part of the chain */
- orig_inbuf = inbuf;
- orig_outbuf = outbuf;
- }
-
- /* we need to tell the client where the next part of the reply will be */
- SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
- CVAL(outbuf,smb_vwv0) = smb_com2;
-
- /* remember how much the caller added to the chain, only counting stuff
- after the parameter words */
- chain_size += outsize - smb_wct;
-
- /* work out pointers into the original packets. The
- headers on these need to be filled in */
- inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
- outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
-
- /* remember the original command type */
- smb_com1 = CVAL(orig_inbuf,smb_com);
-
- /* save the data which will be overwritten by the new headers */
- memcpy(inbuf_saved,inbuf2,smb_wct);
- memcpy(outbuf_saved,outbuf2,smb_wct);
-
- /* give the new packet the same header as the last part of the SMB */
- memmove(inbuf2,inbuf,smb_wct);
-
- /* create the in buffer */
- CVAL(inbuf2,smb_com) = smb_com2;
-
- /* create the out buffer */
- bzero(outbuf2,smb_size);
- set_message(outbuf2,0,0,True);
- CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
-
- memcpy(outbuf2+4,inbuf2+4,4);
- CVAL(outbuf2,smb_rcls) = SUCCESS;
- CVAL(outbuf2,smb_reh) = 0;
- CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set
- means a reply */
- SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
- SSVAL(outbuf2,smb_err,SUCCESS);
- SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
- SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
- SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
- SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
-
- DEBUG(3,("Chained message\n"));
- show_msg(inbuf2);
-
- /* process the request */
- outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
- bufsize-chain_size);
-
- /* copy the new reply and request headers over the old ones, but
- preserve the smb_com field */
- memmove(orig_outbuf,outbuf2,smb_wct);
- CVAL(orig_outbuf,smb_com) = smb_com1;
-
- /* restore the saved data, being careful not to overwrite any
- data from the reply header */
- memcpy(inbuf2,inbuf_saved,smb_wct);
- {
- int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
- if (ofs < 0) ofs = 0;
- memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
- }
-
- return outsize2;
-}
-
-
-
-/****************************************************************************
- construct a reply to the incoming packet
-****************************************************************************/
-int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
-{
- int type = CVAL(inbuf,smb_com);
- int outsize = 0;
- int msg_type = CVAL(inbuf,0);
- extern int chain_size;
-
- smb_last_time = time(NULL);
-
- chain_size = 0;
- chain_fnum = -1;
-
- bzero(outbuf,smb_size);
-
- if (msg_type != 0)
- return(reply_special(inbuf,outbuf));
-
- CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
- set_message(outbuf,0,0,True);
-
- memcpy(outbuf+4,inbuf+4,4);
- CVAL(outbuf,smb_rcls) = SUCCESS;
- CVAL(outbuf,smb_reh) = 0;
- CVAL(outbuf,smb_flg) = 0x80 | (CVAL(inbuf,smb_flg) & 0x8); /* bit 7 set
- means a reply */
- SSVAL(outbuf,smb_flg2,1); /* say we support long filenames */
- SSVAL(outbuf,smb_err,SUCCESS);
- SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
- SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
- SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
- SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
-
- outsize = switch_message(type,inbuf,outbuf,size,bufsize);
-
- outsize += chain_size;
-
- if(outsize > 4)
- smb_setlen(outbuf,outsize - 4);
- return(outsize);
-}
-
-/****************************************************************************
- process commands from the client
-****************************************************************************/
-static void process(void)
-{
- extern int Client;
-
- InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- if ((InBuffer == NULL) || (OutBuffer == NULL))
- return;
-
- InBuffer += SMB_ALIGNMENT;
- OutBuffer += SMB_ALIGNMENT;
-
-#if PRIME_NMBD
- DEBUG(3,("priming nmbd\n"));
- {
- struct in_addr ip;
- ip = *interpret_addr2("localhost");
- if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
- *OutBuffer = 0;
- send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
- }
-#endif
-
- while (True)
- {
- int deadtime = lp_deadtime()*60;
- int counter;
- int last_keepalive=0;
- int service_load_counter = 0;
- BOOL got_smb = False;
-
- if (deadtime <= 0)
- deadtime = DEFAULT_SMBD_TIMEOUT;
-
- if (lp_readprediction())
- do_read_prediction();
-
- errno = 0;
-
- for (counter=SMBD_SELECT_LOOP;
- !receive_message_or_smb(Client,oplock_sock,
- InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb);
- counter += SMBD_SELECT_LOOP)
- {
- int i;
- time_t t;
- BOOL allidle = True;
- extern int keepalive;
-
- if (counter > 365 * 3600) /* big number of seconds. */
- {
- counter = 0;
- service_load_counter = 0;
- }
-
- if (smb_read_error == READ_EOF)
- {
- DEBUG(3,("end of file from client\n"));
- return;
- }
-
- if (smb_read_error == READ_ERROR)
- {
- DEBUG(3,("receive_smb error (%s) exiting\n",
- strerror(errno)));
- return;
- }
-
- t = time(NULL);
-
- /* become root again if waiting */
- unbecome_user();
-
- /* check for smb.conf reload */
- if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
- {
- service_load_counter = counter;
-
- /* reload services, if files have changed. */
- reload_services(True);
- }
-
- /* automatic timeout if all connections are closed */
- if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT)
- {
- DEBUG(2,("%s Closing idle connection\n",timestring()));
- return;
- }
-
- if (keepalive && (counter-last_keepalive)>keepalive)
- {
- extern int password_client;
- if (!send_keepalive(Client))
- {
- DEBUG(2,("%s Keepalive failed - exiting\n",timestring()));
- return;
- }
- /* also send a keepalive to the password server if its still
- connected */
- if (password_client != -1)
- send_keepalive(password_client);
- last_keepalive = counter;
- }
-
- /* check for connection timeouts */
- for (i=0;i<MAX_CONNECTIONS;i++)
- if (Connections[i].open)
- {
- /* close dirptrs on connections that are idle */
- if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT)
- dptr_idlecnum(i);
-
- if (Connections[i].num_files_open > 0 ||
- (t-Connections[i].lastused)<deadtime)
- allidle = False;
- }
-
- if (allidle && num_connections_open>0)
- {
- DEBUG(2,("%s Closing idle connection 2\n",timestring()));
- return;
- }
- }
-
- if(got_smb)
- process_smb(InBuffer, OutBuffer);
- else
- process_local_message(oplock_sock, InBuffer, BUFFER_SIZE);
- }
-}
-
-
-/****************************************************************************
- initialise connect, service and file structs
-****************************************************************************/
-static void init_structs(void )
-{
- int i;
- get_myname(myhostname,NULL);
-
- for (i=0;i<MAX_CONNECTIONS;i++)
- {
- Connections[i].open = False;
- Connections[i].num_files_open=0;
- Connections[i].lastused=0;
- Connections[i].used=False;
- string_init(&Connections[i].user,"");
- string_init(&Connections[i].dirpath,"");
- string_init(&Connections[i].connectpath,"");
- string_init(&Connections[i].origpath,"");
- }
-
- for (i=0;i<MAX_OPEN_FILES;i++)
- {
- Files[i].open = False;
- string_init(&Files[i].name,"");
-
- }
-
- for (i=0;i<MAX_OPEN_FILES;i++)
- {
- file_fd_struct *fd_ptr = &FileFd[i];
- fd_ptr->ref_count = 0;
- fd_ptr->dev = (int32)-1;
- fd_ptr->inode = (int32)-1;
- fd_ptr->fd = -1;
- fd_ptr->fd_readonly = -1;
- fd_ptr->fd_writeonly = -1;
- fd_ptr->real_open_flags = -1;
- }
-
- init_dptrs();
-}
-
-/****************************************************************************
-usage on the program
-****************************************************************************/
-static void usage(char *pname)
-{
- DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
-
- printf("Usage: %s [-D] [-p port] [-d debuglevel] [-l log basename] [-s services file]\n",pname);
- printf("Version %s\n",VERSION);
- printf("\t-D become a daemon\n");
- printf("\t-p port listen on the specified port\n");
- printf("\t-d debuglevel set the debuglevel\n");
- printf("\t-l log basename. Basename for log/debug files\n");
- printf("\t-s services file. Filename of services file\n");
- printf("\t-P passive only\n");
- printf("\t-a overwrite log file, don't append\n");
- printf("\n");
-}
-
-
-/****************************************************************************
- main program
-****************************************************************************/
- int main(int argc,char *argv[])
-{
- extern BOOL append_log;
- /* shall I run as a daemon */
- BOOL is_daemon = False;
- int port = SMB_PORT;
- int opt;
- extern char *optarg;
- char pidFile[100] = { 0 };
-
-#ifdef NEED_AUTH_PARAMETERS
- set_auth_parameters(argc,argv);
-#endif
-
-#ifdef SecureWare
- setluid(0);
-#endif
-
- append_log = True;
-
- TimeInit();
-
- strcpy(debugf,SMBLOGFILE);
-
- setup_logging(argv[0],False);
-
- charset_initialise();
-
- /* make absolutely sure we run as root - to handle cases whre people
- are crazy enough to have it setuid */
-#ifdef USE_SETRES
- setresuid(0,0,0);
-#else
- setuid(0);
- seteuid(0);
- setuid(0);
- seteuid(0);
-#endif
-
- fault_setup(exit_server);
- signal(SIGTERM , SIGNAL_CAST dflt_sig);
-
- /* we want total control over the permissions on created files,
- so set our umask to 0 */
- umask(0);
-
- GetWd(OriginalDir);
-
- init_uid();
-
- /* this is for people who can't start the program correctly */
- while (argc > 1 && (*argv[1] != '-'))
- {
- argv++;
- argc--;
- }
-
- while ((opt = getopt(argc, argv, "O:i:l:s:d:Dp:hPaf:")) != EOF)
- switch (opt)
- {
- case 'f':
- strncpy(pidFile, optarg, sizeof(pidFile));
- break;
- case 'O':
- strcpy(user_socket_options,optarg);
- break;
- case 'i':
- strcpy(scope,optarg);
- break;
- case 'P':
- {
- extern BOOL passive;
- passive = True;
- }
- break;
- case 's':
- strcpy(servicesf,optarg);
- break;
- case 'l':
- strcpy(debugf,optarg);
- break;
- case 'a':
- {
- extern BOOL append_log;
- append_log = !append_log;
- }
- break;
- case 'D':
- is_daemon = True;
- break;
- case 'd':
- if (*optarg == 'A')
- DEBUGLEVEL = 10000;
- else
- DEBUGLEVEL = atoi(optarg);
- break;
- case 'p':
- port = atoi(optarg);
- break;
- case 'h':
- usage(argv[0]);
- exit(0);
- break;
- default:
- usage(argv[0]);
- exit(1);
- }
-
- reopen_logs();
-
- DEBUG(2,("%s smbd version %s started\n",timestring(),VERSION));
- DEBUG(2,("Copyright Andrew Tridgell 1992-1997\n"));
-
-#ifndef NO_GETRLIMIT
-#ifdef RLIMIT_NOFILE
- {
- struct rlimit rlp;
- getrlimit(RLIMIT_NOFILE, &rlp);
- rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES;
- setrlimit(RLIMIT_NOFILE, &rlp);
- getrlimit(RLIMIT_NOFILE, &rlp);
- DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur));
- }
-#endif
-#endif
-
-
- DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
- getuid(),getgid(),geteuid(),getegid()));
-
- if (sizeof(uint16) < 2 || sizeof(uint32) < 4)
- {
- DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
- exit(1);
- }
-
- init_structs();
-
- if (!reload_services(False))
- return(-1);
-
- codepage_initialise(lp_client_code_page());
-
- strcpy(myworkgroup, lp_workgroup());
-
-#ifndef NO_SIGNAL_TEST
- signal(SIGHUP,SIGNAL_CAST sig_hup);
-#endif
-
- DEBUG(3,("%s loaded services\n",timestring()));
-
- if (!is_daemon && !is_a_socket(0))
- {
- DEBUG(0,("standard input is not a socket, assuming -D option\n"));
- is_daemon = True;
- }
-
- if (is_daemon)
- {
- DEBUG(3,("%s becoming a daemon\n",timestring()));
- become_daemon();
- }
-
- if (*pidFile)
- {
- int fd;
- char buf[20];
-
- if ((fd = open(pidFile,
-#ifdef O_NONBLOCK
- O_NONBLOCK |
-#endif
- O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
- {
- DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
- exit(1);
- }
- if(fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
- {
- DEBUG(0,("ERROR: smbd is already running\n"));
- exit(1);
- }
- sprintf(buf, "%u\n", (unsigned int) getpid());
- if (write(fd, buf, strlen(buf)) < 0)
- {
- DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
- exit(1);
- }
- /* Leave pid file open & locked for the duration... */
- }
-
- if (!open_sockets(is_daemon,port))
- exit(1);
-
-#ifdef FAST_SHARE_MODES
- if (!start_share_mode_mgmt())
- exit(1);
-#endif /* FAST_SHARE_MODES */
-
- /* possibly reload the services file. */
- reload_services(True);
-
- max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
-
- if (*lp_rootdir())
- {
- if (sys_chroot(lp_rootdir()) == 0)
- DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir()));
- }
-
- /* Setup the oplock IPC socket. */
- if(!open_oplock_ipc())
- exit(1);
-
- process();
- close_sockets();
-
- exit_server("normal exit");
- return(0);
-}
-
-
diff --git a/source/smbd/smbrun.c b/source/smbd/smbrun.c
deleted file mode 100644
index 42ce7f60ad0..00000000000
--- a/source/smbd/smbrun.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- external program running routine
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-
-#include "includes.h"
-
-
-/*******************************************************************
-close the low 3 fd's and open dev/null in their place
-********************************************************************/
-static void close_fds(void)
-{
- int fd;
- int i;
- close(0); close(1); close(2);
- /* try and use up these file descriptors, so silly
- library routines writing to stdout etc won't cause havoc */
- for (i=0;i<3;i++) {
- fd = open("/dev/null",O_RDWR,0);
- if (fd < 0) fd = open("/dev/null",O_WRONLY,0);
- if (fd != i) return;
- }
-}
-
-
-/*
-This is a wrapper around the system() call to allow commands to run correctly
-as non root from a program which is switching between root and non-root
-
-It takes 3 arguments as uid,gid,command and runs command after
-becoming a non-root user */
- int main(int argc,char *argv[])
-{
- int uid,gid;
-
- close_fds();
-
- if (argc != 4) exit(2);
-
- uid = atoi(argv[1]);
- gid = atoi(argv[2]);
-
- /* first become root - we may need to do this in order to lose
- our privilages! */
-#ifdef USE_SETRES
- setresgid(0,0,0);
- setresuid(0,0,0);
-#else
- setuid(0);
- seteuid(0);
-#endif
-
-#ifdef USE_SETFS
- setfsuid(uid);
- setfsgid(gid);
-#endif
-
-#ifdef USE_SETRES
- setresgid(gid,gid,gid);
- setresuid(uid,uid,uid);
-#else
- setgid(gid);
- setegid(gid);
- setuid(uid);
- seteuid(uid);
-#endif
-
-
- /* paranoia :-) */
- if (getuid() != uid)
- return(3);
-
- if (geteuid() != getuid())
- return(4);
-
- /* this is to make sure that the system() call doesn't run forever */
- alarm(30);
-
- return(system(argv[3]));
-}
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
deleted file mode 100644
index a56df9cb9cc..00000000000
--- a/source/smbd/trans2.c
+++ /dev/null
@@ -1,1794 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- SMB transaction2 handling
- Copyright (C) Jeremy Allison 1994-1997
-
- Extensively modified by Andrew Tridgell, 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 "includes.h"
-#include "trans2.h"
-
-extern int DEBUGLEVEL;
-extern int Protocol;
-extern connection_struct Connections[];
-extern files_struct Files[];
-extern BOOL case_sensitive;
-extern int Client;
-
-/****************************************************************************
- Send the required number of replies back.
- We assume all fields other than the data fields are
- set correctly for the type of call.
- HACK ! Always assumes smb_setup field is zero.
-****************************************************************************/
-static int send_trans2_replies(char *outbuf, int bufsize, char *params,
- int paramsize, char *pdata, int datasize)
-{
- /* As we are using a protocol > LANMAN1 then the max_send
- variable must have been set in the sessetupX call.
- This takes precedence over the max_xmit field in the
- global struct. These different max_xmit variables should
- be merged as this is now too confusing */
-
- extern int max_send;
- int data_to_send = datasize;
- int params_to_send = paramsize;
- int useable_space;
- char *pp = params;
- char *pd = pdata;
- int params_sent_thistime, data_sent_thistime, total_sent_thistime;
- int alignment_offset = 1;
-
- /* Initially set the wcnt area to be 10 - this is true for all
- trans2 replies */
- set_message(outbuf,10,0,True);
-
- /* If there genuinely are no parameters or data to send just send
- the empty packet */
- if(params_to_send == 0 && data_to_send == 0)
- {
- send_smb(Client,outbuf);
- return 0;
- }
-
- /* Space is bufsize minus Netbios over TCP header minus SMB header */
- /* The alignment_offset is to align the param and data bytes on an even byte
- boundary. NT 4.0 Beta needs this to work correctly. */
- useable_space = bufsize - ((smb_buf(outbuf)+alignment_offset) - outbuf);
- /* useable_space can never be more than max_send minus the
- alignment offset. */
- useable_space = MIN(useable_space, max_send - alignment_offset);
-
- while( params_to_send || data_to_send)
- {
- /* Calculate whether we will totally or partially fill this packet */
- total_sent_thistime = params_to_send + data_to_send + alignment_offset;
- /* We can never send more than useable_space */
- total_sent_thistime = MIN(total_sent_thistime, useable_space);
-
- set_message(outbuf, 10, total_sent_thistime, True);
-
- /* Set total params and data to be sent */
- SSVAL(outbuf,smb_tprcnt,paramsize);
- SSVAL(outbuf,smb_tdrcnt,datasize);
-
- /* Calculate how many parameters and data we can fit into
- this packet. Parameters get precedence */
-
- params_sent_thistime = MIN(params_to_send,useable_space);
- data_sent_thistime = useable_space - params_sent_thistime;
- data_sent_thistime = MIN(data_sent_thistime,data_to_send);
-
- SSVAL(outbuf,smb_prcnt, params_sent_thistime);
- if(params_sent_thistime == 0)
- {
- SSVAL(outbuf,smb_proff,0);
- SSVAL(outbuf,smb_prdisp,0);
- } else {
- /* smb_proff is the offset from the start of the SMB header to the
- parameter bytes, however the first 4 bytes of outbuf are
- the Netbios over TCP header. Thus use smb_base() to subtract
- them from the calculation */
- SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
- /* Absolute displacement of param bytes sent in this packet */
- SSVAL(outbuf,smb_prdisp,pp - params);
- }
-
- SSVAL(outbuf,smb_drcnt, data_sent_thistime);
- if(data_sent_thistime == 0)
- {
- SSVAL(outbuf,smb_droff,0);
- SSVAL(outbuf,smb_drdisp, 0);
- } else {
- /* The offset of the data bytes is the offset of the
- parameter bytes plus the number of parameters being sent this time */
- SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
- smb_base(outbuf)) + params_sent_thistime);
- SSVAL(outbuf,smb_drdisp, pd - pdata);
- }
-
- /* Copy the param bytes into the packet */
- if(params_sent_thistime)
- memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
- /* Copy in the data bytes */
- if(data_sent_thistime)
- memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime,pd,data_sent_thistime);
-
- DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
- params_sent_thistime, data_sent_thistime, useable_space));
- DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
- params_to_send, data_to_send, paramsize, datasize));
-
- /* Send the packet */
- send_smb(Client,outbuf);
-
- pp += params_sent_thistime;
- pd += data_sent_thistime;
-
- params_to_send -= params_sent_thistime;
- data_to_send -= data_sent_thistime;
-
- /* Sanity check */
- if(params_to_send < 0 || data_to_send < 0)
- {
- DEBUG(2,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
- params_to_send, data_to_send));
- return -1;
- }
- }
-
- return 0;
-}
-
-
-/****************************************************************************
- reply to a TRANSACT2_OPEN
-****************************************************************************/
-static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
- char **pparams, char **ppdata)
-{
- char *params = *pparams;
- int16 open_mode = SVAL(params, 2);
- int16 open_attr = SVAL(params,6);
- BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1));
-#if 0
- BOOL return_additional_info = BITSETW(params,0);
- int16 open_sattr = SVAL(params, 4);
- time_t open_time = make_unix_date3(params+8);
-#endif
- int16 open_ofun = SVAL(params,12);
- int32 open_size = IVAL(params,14);
- char *pname = &params[28];
- int16 namelen = strlen(pname)+1;
-
- pstring fname;
- int fnum = -1;
- int unixmode;
- int size=0,fmode=0,mtime=0,rmode;
- int32 inode = 0;
- struct stat sbuf;
- int smb_action = 0;
- BOOL bad_path = False;
-
- StrnCpy(fname,pname,namelen);
-
- DEBUG(3,("trans2open %s cnum=%d mode=%d attr=%d ofun=%d size=%d\n",
- fname,cnum,open_mode, open_attr, open_ofun, open_size));
-
- /* XXXX we need to handle passed times, sattr and flags */
-
- unix_convert(fname,cnum,0,&bad_path);
-
- fnum = find_free_file();
- if (fnum < 0)
- return(ERROR(ERRSRV,ERRnofids));
-
- if (!check_name(fname,cnum))
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- unixmode = unix_mode(cnum,open_attr | aARCH);
-
-
- open_file_shared(fnum,cnum,fname,open_mode,open_ofun,unixmode,
- oplock_request, &rmode,&smb_action);
-
- if (!Files[fnum].open)
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
- close_file(fnum);
- return(ERROR(ERRDOS,ERRnoaccess));
- }
-
- size = sbuf.st_size;
- fmode = dos_mode(cnum,fname,&sbuf);
- mtime = sbuf.st_mtime;
- inode = sbuf.st_ino;
- if (fmode & aDIR) {
- close_file(fnum);
- return(ERROR(ERRDOS,ERRnoaccess));
- }
-
- /* Realloc the size of parameters and data we will return */
- params = *pparams = Realloc(*pparams, 28);
- if(params == NULL)
- return(ERROR(ERRDOS,ERRnomem));
-
- bzero(params,28);
- SSVAL(params,0,fnum);
- SSVAL(params,2,fmode);
- put_dos_date2(params,4, mtime);
- SIVAL(params,8, size);
- SSVAL(params,12,rmode);
-
- if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
- smb_action |= EXTENDED_OPLOCK_GRANTED;
- }
-
- SSVAL(params,18,smb_action);
- SIVAL(params,20,inode);
-
- /* Send the required number of replies */
- send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
-
- return -1;
-}
-
-/****************************************************************************
- get a level dependent lanman2 dir entry.
-****************************************************************************/
-static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_level,
- int requires_resume_key,
- BOOL dont_descend,char **ppdata,
- char *base_data, int space_remaining,
- BOOL *out_of_space,
- int *last_name_off)
-{
- char *dname;
- BOOL found = False;
- struct stat sbuf;
- pstring mask;
- pstring pathreal;
- pstring fname;
- BOOL matched;
- char *p, *pdata = *ppdata;
- int reskey=0, prev_dirpos=0;
- int mode=0;
- uint32 size=0,len;
- uint32 mdate=0, adate=0, cdate=0;
- char *nameptr;
- BOOL isrootdir = (strequal(Connections[cnum].dirpath,"./") ||
- strequal(Connections[cnum].dirpath,".") ||
- strequal(Connections[cnum].dirpath,"/"));
- BOOL was_8_3;
- int nt_extmode; /* Used for NT connections instead of mode */
- BOOL needslash = ( Connections[cnum].dirpath[strlen(Connections[cnum].dirpath) -1] != '/');
-
- *fname = 0;
- *out_of_space = False;
-
- if (!Connections[cnum].dirptr)
- return(False);
-
- p = strrchr(path_mask,'/');
- if(p != NULL)
- {
- if(p[1] == '\0')
- strcpy(mask,"*.*");
- else
- pstrcpy(mask, p+1);
- }
- else
- pstrcpy(mask, path_mask);
-
- while (!found)
- {
- /* Needed if we run out of space */
- prev_dirpos = TellDir(Connections[cnum].dirptr);
- dname = ReadDirName(Connections[cnum].dirptr);
-
- reskey = TellDir(Connections[cnum].dirptr);
-
- DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%x now at offset %d\n",
- Connections[cnum].dirptr,TellDir(Connections[cnum].dirptr)));
-
- if (!dname)
- return(False);
-
- matched = False;
-
- pstrcpy(fname,dname);
-
- if(mask_match(fname, mask, case_sensitive, True))
- {
- BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
- if (dont_descend && !isdots)
- continue;
-
- if (isrootdir && isdots)
- continue;
-
- pstrcpy(pathreal,Connections[cnum].dirpath);
- if(needslash)
- strcat(pathreal,"/");
- strcat(pathreal,dname);
- if (sys_stat(pathreal,&sbuf) != 0)
- {
- DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",pathreal,strerror(errno)));
- continue;
- }
-
- mode = dos_mode(cnum,pathreal,&sbuf);
-
- if (!dir_check_ftype(cnum,mode,&sbuf,dirtype)) {
- DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
- continue;
- }
-
- size = sbuf.st_size;
- mdate = sbuf.st_mtime;
- adate = sbuf.st_atime;
- cdate = sbuf.st_ctime;
- if(mode & aDIR)
- size = 0;
-
- DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
-
- found = True;
- }
- }
-
- name_map_mangle(fname,False,SNUM(cnum));
-
- p = pdata;
- nameptr = p;
-
- nt_extmode = mode ? mode : NT_FILE_ATTRIBUTE_NORMAL;
-
- switch (info_level)
- {
- case 1:
- if(requires_resume_key) {
- SIVAL(p,0,reskey);
- p += 4;
- }
- put_dos_date2(p,l1_fdateCreation,cdate);
- put_dos_date2(p,l1_fdateLastAccess,adate);
- put_dos_date2(p,l1_fdateLastWrite,mdate);
- SIVAL(p,l1_cbFile,size);
- SIVAL(p,l1_cbFileAlloc,ROUNDUP(size,1024));
- SSVAL(p,l1_attrFile,mode);
- SCVAL(p,l1_cchName,strlen(fname));
- strcpy(p + l1_achName, fname);
- nameptr = p + l1_achName;
- p += l1_achName + strlen(fname) + 1;
- break;
-
- case 2:
- /* info_level 2 */
- if(requires_resume_key) {
- SIVAL(p,0,reskey);
- p += 4;
- }
- put_dos_date2(p,l2_fdateCreation,cdate);
- put_dos_date2(p,l2_fdateLastAccess,adate);
- put_dos_date2(p,l2_fdateLastWrite,mdate);
- SIVAL(p,l2_cbFile,size);
- SIVAL(p,l2_cbFileAlloc,ROUNDUP(size,1024));
- SSVAL(p,l2_attrFile,mode);
- SIVAL(p,l2_cbList,0); /* No extended attributes */
- SCVAL(p,l2_cchName,strlen(fname));
- strcpy(p + l2_achName, fname);
- nameptr = p + l2_achName;
- p += l2_achName + strlen(fname) + 1;
- break;
-
- case 3:
- SIVAL(p,0,reskey);
- put_dos_date2(p,4,cdate);
- put_dos_date2(p,8,adate);
- put_dos_date2(p,12,mdate);
- SIVAL(p,16,size);
- SIVAL(p,20,ROUNDUP(size,1024));
- SSVAL(p,24,mode);
- SIVAL(p,26,4);
- CVAL(p,30) = strlen(fname);
- strcpy(p+31, fname);
- nameptr = p+31;
- p += 31 + strlen(fname) + 1;
- break;
-
- case 4:
- if(requires_resume_key) {
- SIVAL(p,0,reskey);
- p += 4;
- }
- SIVAL(p,0,33+strlen(fname)+1);
- put_dos_date2(p,4,cdate);
- put_dos_date2(p,8,adate);
- put_dos_date2(p,12,mdate);
- SIVAL(p,16,size);
- SIVAL(p,20,ROUNDUP(size,1024));
- SSVAL(p,24,mode);
- CVAL(p,32) = strlen(fname);
- strcpy(p + 33, fname);
- nameptr = p+33;
- p += 33 + strlen(fname) + 1;
- break;
-
- case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
- was_8_3 = is_8_3(fname, True);
- len = 94+strlen(fname);
- len = (len + 3) & ~3;
- SIVAL(p,0,len); p += 4;
- SIVAL(p,0,reskey); p += 4;
- put_long_date(p,cdate); p += 8;
- put_long_date(p,adate); p += 8;
- put_long_date(p,mdate); p += 8;
- put_long_date(p,mdate); p += 8;
- SIVAL(p,0,size); p += 8;
- SIVAL(p,0,size); p += 8;
- SIVAL(p,0,nt_extmode); p += 4;
- SIVAL(p,0,strlen(fname)); p += 4;
- SIVAL(p,0,0); p += 4;
- if (!was_8_3) {
- strcpy(p+2,fname);
- if (!name_map_mangle(p+2,True,SNUM(cnum)))
- (p+2)[12] = 0;
- } else
- *(p+2) = 0;
- strupper(p+2);
- SSVAL(p,0,strlen(p+2));
- p += 2 + 24;
- /* nameptr = p; */
- strcpy(p,fname); p += strlen(p);
- p = pdata + len;
- break;
-
- case SMB_FIND_FILE_DIRECTORY_INFO:
- len = 64+strlen(fname);
- len = (len + 3) & ~3;
- SIVAL(p,0,len); p += 4;
- SIVAL(p,0,reskey); p += 4;
- put_long_date(p,cdate); p += 8;
- put_long_date(p,adate); p += 8;
- put_long_date(p,mdate); p += 8;
- put_long_date(p,mdate); p += 8;
- SIVAL(p,0,size); p += 8;
- SIVAL(p,0,size); p += 8;
- SIVAL(p,0,nt_extmode); p += 4;
- SIVAL(p,0,strlen(fname)); p += 4;
- strcpy(p,fname);
- p = pdata + len;
- break;
-
-
- case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
- len = 68+strlen(fname);
- len = (len + 3) & ~3;
- SIVAL(p,0,len); p += 4;
- SIVAL(p,0,reskey); p += 4;
- put_long_date(p,cdate); p += 8;
- put_long_date(p,adate); p += 8;
- put_long_date(p,mdate); p += 8;
- put_long_date(p,mdate); p += 8;
- SIVAL(p,0,size); p += 8;
- SIVAL(p,0,size); p += 8;
- SIVAL(p,0,nt_extmode); p += 4;
- SIVAL(p,0,strlen(fname)); p += 4;
- SIVAL(p,0,0); p += 4;
- strcpy(p,fname);
- p = pdata + len;
- break;
-
- case SMB_FIND_FILE_NAMES_INFO:
- len = 12+strlen(fname);
- len = (len + 3) & ~3;
- SIVAL(p,0,len); p += 4;
- SIVAL(p,0,reskey); p += 4;
- SIVAL(p,0,strlen(fname)); p += 4;
- strcpy(p,fname);
- p = pdata + len;
- break;
-
- default:
- return(False);
- }
-
-
- if (PTR_DIFF(p,pdata) > space_remaining) {
- /* Move the dirptr back to prev_dirpos */
- SeekDir(Connections[cnum].dirptr, prev_dirpos);
- *out_of_space = True;
- DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
- return False; /* Not finished - just out of space */
- }
-
- /* Setup the last_filename pointer, as an offset from base_data */
- *last_name_off = PTR_DIFF(nameptr,base_data);
- /* Advance the data pointer to the next slot */
- *ppdata = p;
- return(found);
-}
-
-/****************************************************************************
- reply to a TRANS2_FINDFIRST
-****************************************************************************/
-static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum,
- char **pparams, char **ppdata)
-{
- /* We must be careful here that we don't return more than the
- allowed number of data bytes. If this means returning fewer than
- maxentries then so be it. We assume that the redirector has
- enough room for the fixed number of parameter bytes it has
- requested. */
- uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
- char *params = *pparams;
- char *pdata = *ppdata;
- int dirtype = SVAL(params,0);
- int maxentries = SVAL(params,2);
- BOOL close_after_first = BITSETW(params+4,0);
- BOOL close_if_end = BITSETW(params+4,1);
- BOOL requires_resume_key = BITSETW(params+4,2);
- int info_level = SVAL(params,6);
- pstring directory;
- pstring mask;
- char *p, *wcard;
- int last_name_off=0;
- int dptr_num = -1;
- int numentries = 0;
- int i;
- BOOL finished = False;
- BOOL dont_descend = False;
- BOOL out_of_space = False;
- int space_remaining;
- BOOL bad_path = False;
-
- *directory = *mask = 0;
-
- DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
- dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
- info_level, max_data_bytes));
-
- switch (info_level)
- {
- case 1:
- case 2:
- case 3:
- case 4:
- case SMB_FIND_FILE_DIRECTORY_INFO:
- case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
- case SMB_FIND_FILE_NAMES_INFO:
- case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
- break;
- default:
- return(ERROR(ERRDOS,ERRunknownlevel));
- }
-
- pstrcpy(directory, params + 12); /* Complete directory path with
- wildcard mask appended */
-
- DEBUG(5,("path=%s\n",directory));
-
- unix_convert(directory,cnum,0,&bad_path);
- if(!check_name(directory,cnum)) {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
-
-#if 0
- /* Ugly - NT specific hack - maybe not needed ? (JRA) */
- if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
- (get_remote_arch() == RA_WINNT))
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbaddirectory;
- }
-#endif
-
- return(ERROR(ERRDOS,ERRbadpath));
- }
-
- p = strrchr(directory,'/');
- if(p == NULL) {
- strcpy(mask,directory);
- strcpy(directory,"./");
- } else {
- strcpy(mask,p+1);
- *p = 0;
- }
-
- DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
-
- pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
- if(!*ppdata)
- return(ERROR(ERRDOS,ERRnomem));
- bzero(pdata,max_data_bytes);
-
- /* Realloc the params space */
- params = *pparams = Realloc(*pparams, 10);
- if(params == NULL)
- return(ERROR(ERRDOS,ERRnomem));
-
- dptr_num = dptr_create(cnum,directory, True ,SVAL(inbuf,smb_pid));
- if (dptr_num < 0)
- {
- if(dptr_num == -2)
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
-
-#if 0
- /* Ugly - NT specific hack - maybe not needed ? (JRA) */
- if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) &&
- (get_remote_arch() == RA_WINNT))
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbaddirectory;
- }
-#endif
-
- return (UNIXERROR(ERRDOS,ERRbadpath));
- }
- return(ERROR(ERRDOS,ERRbadpath));
- }
-
- /* convert the formatted masks */
- {
- p = mask;
- while (*p) {
- if (*p == '<') *p = '*';
- if (*p == '>') *p = '?';
- if (*p == '"') *p = '.';
- p++;
- }
- }
-
- /* a special case for 16 bit apps */
- if (strequal(mask,"????????.???")) strcpy(mask,"*");
-
- /* handle broken clients that send us old 8.3 format */
- string_sub(mask,"????????","*");
- string_sub(mask,".???",".*");
-
- /* Save the wildcard match and attribs we are using on this directory -
- needed as lanman2 assumes these are being saved between calls */
-
- if(!(wcard = strdup(mask))) {
- dptr_close(dptr_num);
- return(ERROR(ERRDOS,ERRnomem));
- }
-
- dptr_set_wcard(dptr_num, wcard);
- dptr_set_attr(dptr_num, dirtype);
-
- DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
-
- /* We don't need to check for VOL here as this is returned by
- a different TRANS2 call. */
-
- DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
- Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum))));
- if (in_list(Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum)),case_sensitive))
- dont_descend = True;
-
- p = pdata;
- space_remaining = max_data_bytes;
- out_of_space = False;
-
- for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
- {
-
- /* this is a heuristic to avoid seeking the dirptr except when
- absolutely necessary. It allows for a filename of about 40 chars */
- if (space_remaining < DIRLEN_GUESS && numentries > 0)
- {
- out_of_space = True;
- finished = False;
- }
- else
- {
- finished =
- !get_lanman2_dir_entry(cnum,mask,dirtype,info_level,
- requires_resume_key,dont_descend,
- &p,pdata,space_remaining, &out_of_space,
- &last_name_off);
- }
-
- if (finished && out_of_space)
- finished = False;
-
- if (!finished && !out_of_space)
- numentries++;
- space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
- }
-
- /* Check if we can close the dirptr */
- if(close_after_first || (finished && close_if_end))
- {
- dptr_close(dptr_num);
- DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
- dptr_num = -1;
- }
-
- /* At this point pdata points to numentries directory entries. */
-
- /* Set up the return parameter block */
- SSVAL(params,0,dptr_num);
- SSVAL(params,2,numentries);
- SSVAL(params,4,finished);
- SSVAL(params,6,0); /* Never an EA error */
- SSVAL(params,8,last_name_off);
-
- send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
-
- if ((! *directory) && dptr_path(dptr_num))
- sprintf(directory,"(%s)",dptr_path(dptr_num));
-
- DEBUG(4,("%s %s mask=%s directory=%s cnum=%d dirtype=%d numentries=%d\n",
- timestring(),
- smb_fn_name(CVAL(inbuf,smb_com)),
- mask,directory,cnum,dirtype,numentries));
-
- return(-1);
-}
-
-
-/****************************************************************************
- reply to a TRANS2_FINDNEXT
-****************************************************************************/
-static int call_trans2findnext(char *inbuf, char *outbuf, int length, int bufsize,
- int cnum, char **pparams, char **ppdata)
-{
- /* We must be careful here that we don't return more than the
- allowed number of data bytes. If this means returning fewer than
- maxentries then so be it. We assume that the redirector has
- enough room for the fixed number of parameter bytes it has
- requested. */
- int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
- char *params = *pparams;
- char *pdata = *ppdata;
- int16 dptr_num = SVAL(params,0);
- int maxentries = SVAL(params,2);
- uint16 info_level = SVAL(params,4);
- uint32 resume_key = IVAL(params,6);
- BOOL close_after_request = BITSETW(params+10,0);
- BOOL close_if_end = BITSETW(params+10,1);
- BOOL requires_resume_key = BITSETW(params+10,2);
- BOOL continue_bit = BITSETW(params+10,3);
- pstring mask;
- pstring directory;
- char *p;
- uint16 dirtype;
- int numentries = 0;
- int i, last_name_off=0;
- BOOL finished = False;
- BOOL dont_descend = False;
- BOOL out_of_space = False;
- int space_remaining;
-
- *mask = *directory = 0;
-
- DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, close_after_request=%d, close_if_end = %d requires_resume_key = %d resume_key = %d continue=%d level = %d\n",
- dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
- requires_resume_key, resume_key, continue_bit, info_level));
-
- switch (info_level)
- {
- case 1:
- case 2:
- case 3:
- case 4:
- case SMB_FIND_FILE_DIRECTORY_INFO:
- case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
- case SMB_FIND_FILE_NAMES_INFO:
- case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
- break;
- default:
- return(ERROR(ERRDOS,ERRunknownlevel));
- }
-
- pdata = *ppdata = Realloc( *ppdata, max_data_bytes + 1024);
- if(!*ppdata)
- return(ERROR(ERRDOS,ERRnomem));
- bzero(pdata,max_data_bytes);
-
- /* Realloc the params space */
- params = *pparams = Realloc(*pparams, 6*SIZEOFWORD);
- if(!params)
- return(ERROR(ERRDOS,ERRnomem));
-
- /* Check that the dptr is valid */
- if(!(Connections[cnum].dirptr = dptr_fetch_lanman2(params, dptr_num)))
- return(ERROR(ERRDOS,ERRnofiles));
-
- string_set(&Connections[cnum].dirpath,dptr_path(dptr_num));
-
- /* Get the wildcard mask from the dptr */
- if((p = dptr_wcard(dptr_num))== NULL) {
- DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
- return (ERROR(ERRDOS,ERRnofiles));
- }
- strcpy(mask, p);
- strcpy(directory,Connections[cnum].dirpath);
-
- /* Get the attr mask from the dptr */
- dirtype = dptr_attr(dptr_num);
-
- DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%X,%d)\n",
- dptr_num, mask, dirtype,
- Connections[cnum].dirptr,
- TellDir(Connections[cnum].dirptr)));
-
- /* We don't need to check for VOL here as this is returned by
- a different TRANS2 call. */
-
- DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum))));
- if (in_list(Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum)),case_sensitive))
- dont_descend = True;
-
- p = pdata;
- space_remaining = max_data_bytes;
- out_of_space = False;
-
- /* If we have a resume key - seek to the correct position. */
- if(requires_resume_key && !continue_bit)
- SeekDir(Connections[cnum].dirptr, resume_key);
-
- for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
- {
- /* this is a heuristic to avoid seeking the dirptr except when
- absolutely necessary. It allows for a filename of about 40 chars */
- if (space_remaining < DIRLEN_GUESS && numentries > 0)
- {
- out_of_space = True;
- finished = False;
- }
- else
- {
- finished =
- !get_lanman2_dir_entry(cnum,mask,dirtype,info_level,
- requires_resume_key,dont_descend,
- &p,pdata,space_remaining, &out_of_space,
- &last_name_off);
- }
-
- if (finished && out_of_space)
- finished = False;
-
- if (!finished && !out_of_space)
- numentries++;
- space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
- }
-
- /* Check if we can close the dirptr */
- if(close_after_request || (finished && close_if_end))
- {
- dptr_close(dptr_num); /* This frees up the saved mask */
- DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
- dptr_num = -1;
- }
-
-
- /* Set up the return parameter block */
- SSVAL(params,0,numentries);
- SSVAL(params,2,finished);
- SSVAL(params,4,0); /* Never an EA error */
- SSVAL(params,6,last_name_off);
-
- send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
-
- if ((! *directory) && dptr_path(dptr_num))
- sprintf(directory,"(%s)",dptr_path(dptr_num));
-
- DEBUG(3,("%s %s mask=%s directory=%s cnum=%d dirtype=%d numentries=%d\n",
- timestring(),
- smb_fn_name(CVAL(inbuf,smb_com)),
- mask,directory,cnum,dirtype,numentries));
-
- return(-1);
-}
-
-/****************************************************************************
- reply to a TRANS2_QFSINFO (query filesystem info)
-****************************************************************************/
-static int call_trans2qfsinfo(char *inbuf, char *outbuf, int length, int bufsize,
- int cnum, char **pparams, char **ppdata)
-{
- char *pdata = *ppdata;
- char *params = *pparams;
- uint16 info_level = SVAL(params,0);
- int data_len;
- struct stat st;
- char *vname = volume_label(SNUM(cnum));
-
- DEBUG(3,("call_trans2qfsinfo: cnum = %d, level = %d\n", cnum, info_level));
-
- if(sys_stat(".",&st)!=0) {
- DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
- return (ERROR(ERRSRV,ERRinvdevice));
- }
-
- pdata = *ppdata = Realloc(*ppdata, 1024); bzero(pdata,1024);
-
- switch (info_level)
- {
- case 1:
- {
- int dfree,dsize,bsize;
- data_len = 18;
- sys_disk_free(".",&bsize,&dfree,&dsize);
- SIVAL(pdata,l1_idFileSystem,st.st_dev);
- SIVAL(pdata,l1_cSectorUnit,bsize/512);
- SIVAL(pdata,l1_cUnit,dsize);
- SIVAL(pdata,l1_cUnitAvail,dfree);
- SSVAL(pdata,l1_cbSector,512);
- DEBUG(5,("call_trans2qfsinfo : bsize=%d, id=%x, cSectorUnit=%d, cUnit=%d, cUnitAvail=%d, cbSector=%d\n",
- bsize, st.st_dev, bsize/512, dsize, dfree, 512));
- break;
- }
- case 2:
- {
- /* Return volume name */
- int volname_len = MIN(strlen(vname),11);
- data_len = l2_vol_szVolLabel + volname_len + 1;
- put_dos_date2(pdata,l2_vol_fdateCreation,st.st_ctime);
- SCVAL(pdata,l2_vol_cch,volname_len);
- StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
- DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",st.st_ctime, volname_len,
- pdata+l2_vol_szVolLabel));
- break;
- }
- case SMB_QUERY_FS_ATTRIBUTE_INFO:
- data_len = 12 + 2*strlen(FSTYPE_STRING);
- SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
- SIVAL(pdata,4,128); /* Max filename component length */
- SIVAL(pdata,8,2*strlen(FSTYPE_STRING));
- PutUniCode(pdata+12,FSTYPE_STRING);
- break;
- case SMB_QUERY_FS_LABEL_INFO:
- data_len = 4 + strlen(vname);
- SIVAL(pdata,0,strlen(vname));
- strcpy(pdata+4,vname);
- break;
- case SMB_QUERY_FS_VOLUME_INFO:
- data_len = 18 + 2*strlen(vname);
- SIVAL(pdata,12,2*strlen(vname));
- PutUniCode(pdata+18,vname);
- DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n", strlen(vname),
- vname));
- break;
- case SMB_QUERY_FS_SIZE_INFO:
- {
- int dfree,dsize,bsize;
- data_len = 24;
- sys_disk_free(".",&bsize,&dfree,&dsize);
- SIVAL(pdata,0,dsize);
- SIVAL(pdata,8,dfree);
- SIVAL(pdata,16,bsize/512);
- SIVAL(pdata,20,512);
- }
- break;
- case SMB_QUERY_FS_DEVICE_INFO:
- data_len = 8;
- SIVAL(pdata,0,0); /* dev type */
- SIVAL(pdata,4,0); /* characteristics */
- break;
- default:
- return(ERROR(ERRDOS,ERRunknownlevel));
- }
-
-
- send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
-
- DEBUG(4,("%s %s info_level =%d\n",timestring(),smb_fn_name(CVAL(inbuf,smb_com)), info_level));
-
- return -1;
-}
-
-/****************************************************************************
- reply to a TRANS2_SETFSINFO (set filesystem info)
-****************************************************************************/
-static int call_trans2setfsinfo(char *inbuf, char *outbuf, int length, int bufsize,
- int cnum, char **pparams, char **ppdata)
-{
- /* Just say yes we did it - there is nothing that
- can be set here so it doesn't matter. */
- int outsize;
- DEBUG(3,("call_trans2setfsinfo\n"));
-
- if (!CAN_WRITE(cnum))
- return(ERROR(ERRSRV,ERRaccess));
-
- outsize = set_message(outbuf,10,0,True);
-
- return outsize;
-}
-
-/****************************************************************************
- reply to a TRANS2_QFILEINFO (query file info by fileid)
-****************************************************************************/
-static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length,
- int bufsize,int cnum,
- char **pparams,char **ppdata,
- int total_data)
-{
- char *params = *pparams;
- char *pdata = *ppdata;
- uint16 tran_call = SVAL(inbuf, smb_setup0);
- uint16 info_level;
- int mode=0;
- int size=0;
- unsigned int data_size;
- struct stat sbuf;
- pstring fname1;
- char *fname;
- char *p;
- int l,pos;
- BOOL bad_path = False;
-
- if (tran_call == TRANSACT2_QFILEINFO) {
- int16 fnum = SVALS(params,0);
- info_level = SVAL(params,2);
-
- CHECK_FNUM(fnum,cnum);
- CHECK_ERROR(fnum);
-
- fname = Files[fnum].name;
- if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
- DEBUG(3,("fstat of fnum %d failed (%s)\n",fnum, strerror(errno)));
- return(UNIXERROR(ERRDOS,ERRbadfid));
- }
- pos = lseek(Files[fnum].fd_ptr->fd,0,SEEK_CUR);
- } else {
- /* qpathinfo */
- info_level = SVAL(params,0);
- fname = &fname1[0];
- pstrcpy(fname,&params[6]);
- unix_convert(fname,cnum,0,&bad_path);
- if (!check_name(fname,cnum) || sys_stat(fname,&sbuf)) {
- DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRbadpath));
- }
- pos = 0;
- }
-
-
- DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
- fname,info_level,tran_call,total_data));
-
- p = strrchr(fname,'/');
- if (!p)
- p = fname;
- else
- p++;
- l = strlen(p);
- mode = dos_mode(cnum,fname,&sbuf);
- size = sbuf.st_size;
- if (mode & aDIR) size = 0;
-
- params = *pparams = Realloc(*pparams,2); bzero(params,2);
- data_size = 1024;
- pdata = *ppdata = Realloc(*ppdata, data_size);
-
- if (total_data > 0 && IVAL(pdata,0) == total_data) {
- /* uggh, EAs for OS2 */
- DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
- return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
- }
-
- bzero(pdata,data_size);
-
- switch (info_level)
- {
- case SMB_INFO_STANDARD:
- case SMB_INFO_QUERY_EA_SIZE:
- data_size = (info_level==1?22:26);
- put_dos_date2(pdata,l1_fdateCreation,sbuf.st_ctime); /* create = inode mod */
- put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime); /* access time */
- put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
- SIVAL(pdata,l1_cbFile,size);
- SIVAL(pdata,l1_cbFileAlloc,ROUNDUP(size,1024));
- SSVAL(pdata,l1_attrFile,mode);
- SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
- break;
-
- case SMB_INFO_QUERY_EAS_FROM_LIST:
- data_size = 24;
- put_dos_date2(pdata,0,sbuf.st_ctime); /* create time = inode mod time */
- put_dos_date2(pdata,4,sbuf.st_atime);
- put_dos_date2(pdata,8,sbuf.st_mtime);
- SIVAL(pdata,12,size);
- SIVAL(pdata,16,ROUNDUP(size,1024));
- SIVAL(pdata,20,mode);
- break;
-
- case SMB_INFO_QUERY_ALL_EAS:
- data_size = 4;
- SIVAL(pdata,0,data_size);
- break;
-
- case 6:
- return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
-
- case SMB_QUERY_FILE_BASIC_INFO:
- data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
- put_long_date(pdata,sbuf.st_ctime); /* create time = inode mod time */
- put_long_date(pdata+8,sbuf.st_atime); /* access time */
- put_long_date(pdata+16,sbuf.st_mtime); /* write time */
- put_long_date(pdata+24,sbuf.st_mtime); /* change time */
- SIVAL(pdata,32,mode);
-
- DEBUG(5,("SMB_QFBI - "));
- DEBUG(5,("create: %s ", ctime(&sbuf.st_ctime)));
- DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
- DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
- DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
- DEBUG(5,("mode: %x\n", mode));
-
- break;
-
- case SMB_QUERY_FILE_STANDARD_INFO:
- data_size = 22;
- SIVAL(pdata,0,size);
- SIVAL(pdata,8,size);
- SIVAL(pdata,16,sbuf.st_nlink);
- CVAL(pdata,20) = 0;
- CVAL(pdata,21) = (mode&aDIR)?1:0;
- break;
-
- case SMB_QUERY_FILE_EA_INFO:
- data_size = 4;
- break;
-
- /* Get the 8.3 name - used if NT SMB was negotiated. */
- case SMB_QUERY_FILE_ALT_NAME_INFO:
- {
- pstring short_name;
- pstrcpy(short_name,fname);
- /* Mangle if not already 8.3 */
- if(!is_8_3(short_name, True))
- {
- if(!name_map_mangle(short_name,True,SNUM(cnum)))
- *short_name = '\0';
- }
- strncpy(pdata + 4,short_name,12);
- (pdata + 4)[12] = 0;
- strupper(pdata + 4);
- l = strlen(pdata + 4);
- data_size = 4 + l;
- SIVAL(pdata,0,l);
- }
- break;
-
- case SMB_QUERY_FILE_NAME_INFO:
- data_size = 4 + l;
- SIVAL(pdata,0,l);
- pstrcpy(pdata+4,fname);
- break;
-
- case SMB_QUERY_FILE_ALLOCATION_INFO:
- case SMB_QUERY_FILE_END_OF_FILEINFO:
- data_size = 8;
- SIVAL(pdata,0,size);
- break;
-
- case SMB_QUERY_FILE_ALL_INFO:
- put_long_date(pdata,sbuf.st_ctime); /* create time = inode mod time */
- put_long_date(pdata+8,sbuf.st_atime); /* access time */
- put_long_date(pdata+16,sbuf.st_mtime); /* write time */
- put_long_date(pdata+24,sbuf.st_mtime); /* change time */
- SIVAL(pdata,32,mode);
- pdata += 40;
- SIVAL(pdata,0,size);
- SIVAL(pdata,8,size);
- SIVAL(pdata,16,sbuf.st_nlink);
- CVAL(pdata,20) = 0;
- CVAL(pdata,21) = (mode&aDIR)?1:0;
- pdata += 24;
- pdata += 8; /* index number */
- pdata += 4; /* EA info */
- if (mode & aRONLY)
- SIVAL(pdata,0,0xA9);
- else
- SIVAL(pdata,0,0xd01BF);
- pdata += 4;
- SIVAL(pdata,0,pos); /* current offset */
- pdata += 8;
- SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
- pdata += 4;
- pdata += 4; /* alignment */
- SIVAL(pdata,0,l);
- pstrcpy(pdata+4,fname);
- pdata += 4 + l;
- data_size = PTR_DIFF(pdata,(*ppdata));
- break;
-
- case SMB_QUERY_FILE_STREAM_INFO:
- data_size = 24 + l;
- SIVAL(pdata,0,pos);
- SIVAL(pdata,4,size);
- SIVAL(pdata,12,size);
- SIVAL(pdata,20,l);
- pstrcpy(pdata+24,fname);
- break;
- default:
- return(ERROR(ERRDOS,ERRunknownlevel));
- }
-
- send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
-
- return(-1);
-}
-
-/****************************************************************************
- reply to a TRANS2_SETFILEINFO (set file info by fileid)
-****************************************************************************/
-static int call_trans2setfilepathinfo(char *inbuf, char *outbuf, int length,
- int bufsize, int cnum, char **pparams,
- char **ppdata, int total_data)
-{
- char *params = *pparams;
- char *pdata = *ppdata;
- uint16 tran_call = SVAL(inbuf, smb_setup0);
- uint16 info_level;
- int mode=0;
- int size=0;
- struct utimbuf tvs;
- struct stat st;
- pstring fname1;
- char *fname;
- int fd = -1;
- BOOL bad_path = False;
-
- if (!CAN_WRITE(cnum))
- return(ERROR(ERRSRV,ERRaccess));
-
- if (tran_call == TRANSACT2_SETFILEINFO) {
- int16 fnum = SVALS(params,0);
- info_level = SVAL(params,2);
-
- CHECK_FNUM(fnum,cnum);
- CHECK_ERROR(fnum);
-
- fname = Files[fnum].name;
- fd = Files[fnum].fd_ptr->fd;
-
- if(fstat(fd,&st)!=0) {
- DEBUG(3,("fstat of %s failed (%s)\n", fname, strerror(errno)));
- return(ERROR(ERRDOS,ERRbadpath));
- }
- } else {
- /* set path info */
- info_level = SVAL(params,0);
- fname = fname1;
- pstrcpy(fname,&params[6]);
- unix_convert(fname,cnum,0,&bad_path);
- if(!check_name(fname, cnum))
- {
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRbadpath));
- }
-
- if(sys_stat(fname,&st)!=0) {
- DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRbadpath));
- }
- }
-
- DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
- tran_call,fname,info_level,total_data));
-
- /* Realloc the parameter and data sizes */
- params = *pparams = Realloc(*pparams,2); SSVAL(params,0,0);
- if(params == NULL)
- return(ERROR(ERRDOS,ERRnomem));
-
- size = st.st_size;
- tvs.modtime = st.st_mtime;
- tvs.actime = st.st_atime;
- mode = dos_mode(cnum,fname,&st);
-
- if (total_data > 0 && IVAL(pdata,0) == total_data) {
- /* uggh, EAs for OS2 */
- DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
- return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
- }
-
- switch (info_level)
- {
- case SMB_INFO_STANDARD:
- case SMB_INFO_QUERY_EA_SIZE:
- {
- /* access time */
- tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
-
- /* write time */
- tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
-
- mode = SVAL(pdata,l1_attrFile);
- size = IVAL(pdata,l1_cbFile);
- break;
- }
-
- /* XXXX um, i don't think this is right.
- it's also not in the cifs6.txt spec.
- */
- case SMB_INFO_QUERY_EAS_FROM_LIST:
- tvs.actime = make_unix_date2(pdata+8);
- tvs.modtime = make_unix_date2(pdata+12);
- size = IVAL(pdata,16);
- mode = IVAL(pdata,24);
- break;
-
- /* XXXX nor this. not in cifs6.txt, either. */
- case SMB_INFO_QUERY_ALL_EAS:
- tvs.actime = make_unix_date2(pdata+8);
- tvs.modtime = make_unix_date2(pdata+12);
- size = IVAL(pdata,16);
- mode = IVAL(pdata,24);
- break;
-
- case SMB_SET_FILE_BASIC_INFO:
- {
- /* Ignore create time at offset pdata. */
-
- /* access time */
- tvs.actime = interpret_long_date(pdata+8);
-
- /* write time + changed time, combined. */
- tvs.modtime=MAX(interpret_long_date(pdata+16),
- interpret_long_date(pdata+24));
-
-#if 0 /* Needs more testing... */
- /* Test from Luke to prevent Win95 from
- setting incorrect values here.
- */
- if (tvs.actime < tvs.modtime)
- return(ERROR(ERRDOS,ERRnoaccess));
-#endif /* Needs more testing... */
-
- /* attributes */
- mode = IVAL(pdata,32);
- break;
- }
-
- case SMB_SET_FILE_END_OF_FILE_INFO:
- {
- if (IVAL(pdata,4) != 0) /* more than 32 bits? */
- return(ERROR(ERRDOS,ERRunknownlevel));
- size = IVAL(pdata,0);
- break;
- }
-
- case SMB_SET_FILE_DISPOSITION_INFO: /* not supported yet */
- case SMB_SET_FILE_ALLOCATION_INFO: /* not supported yet */
- default:
- {
- return(ERROR(ERRDOS,ERRunknownlevel));
- }
- }
-
- DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
- DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
- DEBUG(6,("size: %x " , size));
- DEBUG(6,("mode: %x\n" , mode));
-
- /* get some defaults (no modifications) if any info is zero. */
- if (!tvs.actime) tvs.actime = st.st_atime;
- if (!tvs.modtime) tvs.modtime = st.st_mtime;
- if (!size) size = st.st_size;
-
- /* Try and set the times, size and mode of this file -
- if they are different from the current values
- */
- if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime)
- {
- if(sys_utime(fname, &tvs)!=0)
- {
- return(ERROR(ERRDOS,ERRnoaccess));
- }
- }
-
- /* check the mode isn't different, before changing it */
- if (mode != dos_mode(cnum, fname, &st) && dos_chmod(cnum, fname, mode, NULL))
- {
- DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
- return(ERROR(ERRDOS,ERRnoaccess));
- }
-
- if(size != st.st_size)
- {
- if (fd == -1)
- {
- fd = sys_open(fname,O_RDWR,0);
- if (fd == -1)
- {
- return(ERROR(ERRDOS,ERRbadpath));
- }
- set_filelen(fd, size);
- close(fd);
- }
- else
- {
- set_filelen(fd, size);
- }
- }
-
- SSVAL(params,0,0);
-
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
-
- return(-1);
-}
-
-/****************************************************************************
- reply to a TRANS2_MKDIR (make directory with extended attributes).
-****************************************************************************/
-static int call_trans2mkdir(char *inbuf, char *outbuf, int length, int bufsize,
- int cnum, char **pparams, char **ppdata)
-{
- char *params = *pparams;
- pstring directory;
- int ret = -1;
- BOOL bad_path = False;
-
- if (!CAN_WRITE(cnum))
- return(ERROR(ERRSRV,ERRaccess));
-
- pstrcpy(directory, &params[4]);
-
- DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
-
- unix_convert(directory,cnum,0,&bad_path);
- if (check_name(directory,cnum))
- ret = sys_mkdir(directory,unix_mode(cnum,aDIR));
-
- if(ret < 0)
- {
- DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
- if((errno == ENOENT) && bad_path)
- {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- /* Realloc the parameter and data sizes */
- params = *pparams = Realloc(*pparams,2);
- if(params == NULL)
- return(ERROR(ERRDOS,ERRnomem));
-
- SSVAL(params,0,0);
-
- send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
-
- return(-1);
-}
-
-/****************************************************************************
- reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
- We don't actually do this - we just send a null response.
-****************************************************************************/
-static int call_trans2findnotifyfirst(char *inbuf, char *outbuf, int length, int bufsize,
- int cnum, char **pparams, char **ppdata)
-{
- static uint16 fnf_handle = 257;
- char *params = *pparams;
- uint16 info_level = SVAL(params,4);
-
- DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
-
- switch (info_level)
- {
- case 1:
- case 2:
- break;
- default:
- return(ERROR(ERRDOS,ERRunknownlevel));
- }
-
- /* Realloc the parameter and data sizes */
- params = *pparams = Realloc(*pparams,6);
- if(params == NULL)
- return(ERROR(ERRDOS,ERRnomem));
-
- SSVAL(params,0,fnf_handle);
- SSVAL(params,2,0); /* No changes */
- SSVAL(params,4,0); /* No EA errors */
-
- fnf_handle++;
-
- if(fnf_handle == 0)
- fnf_handle = 257;
-
- send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
-
- return(-1);
-}
-
-/****************************************************************************
- reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
- changes). Currently this does nothing.
-****************************************************************************/
-static int call_trans2findnotifynext(char *inbuf, char *outbuf, int length, int bufsize,
- int cnum, char **pparams, char **ppdata)
-{
- char *params = *pparams;
-
- DEBUG(3,("call_trans2findnotifynext\n"));
-
- /* Realloc the parameter and data sizes */
- params = *pparams = Realloc(*pparams,4);
- if(params == NULL)
- return(ERROR(ERRDOS,ERRnomem));
-
- SSVAL(params,0,0); /* No changes */
- SSVAL(params,2,0); /* No EA errors */
-
- send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
-
- return(-1);
-}
-
-/****************************************************************************
- reply to a SMBfindclose (stop trans2 directory search)
-****************************************************************************/
-int reply_findclose(char *inbuf,char *outbuf,int length,int bufsize)
-{
- int cnum;
- int outsize = 0;
- int16 dptr_num=SVALS(inbuf,smb_vwv0);
-
- cnum = SVAL(inbuf,smb_tid);
-
- DEBUG(3,("reply_findclose, cnum = %d, dptr_num = %d\n", cnum, dptr_num));
-
- dptr_close(dptr_num);
-
- outsize = set_message(outbuf,0,0,True);
-
- DEBUG(3,("%s SMBfindclose cnum=%d, dptr_num = %d\n",timestring(),cnum,dptr_num));
-
- return(outsize);
-}
-
-/****************************************************************************
- reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
-****************************************************************************/
-int reply_findnclose(char *inbuf,char *outbuf,int length,int bufsize)
-{
- int cnum;
- int outsize = 0;
- int dptr_num= -1;
-
- cnum = SVAL(inbuf,smb_tid);
- dptr_num = SVAL(inbuf,smb_vwv0);
-
- DEBUG(3,("reply_findnclose, cnum = %d, dptr_num = %d\n", cnum, dptr_num));
-
- /* We never give out valid handles for a
- findnotifyfirst - so any dptr_num is ok here.
- Just ignore it. */
-
- outsize = set_message(outbuf,0,0,True);
-
- DEBUG(3,("%s SMB_findnclose cnum=%d, dptr_num = %d\n",timestring(),cnum,dptr_num));
-
- return(outsize);
-}
-
-
-/****************************************************************************
- reply to a SMBtranss2 - just ignore it!
-****************************************************************************/
-int reply_transs2(char *inbuf,char *outbuf,int length,int bufsize)
-{
- DEBUG(4,("Ignoring transs2 of length %d\n",length));
- return(-1);
-}
-
-/****************************************************************************
- reply to a SMBtrans2
-****************************************************************************/
-int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize)
-{
- int outsize = 0;
- int cnum = SVAL(inbuf,smb_tid);
- unsigned int total_params = SVAL(inbuf, smb_tpscnt);
- unsigned int total_data =SVAL(inbuf, smb_tdscnt);
-#if 0
- unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
- unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
- unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
- BOOL close_tid = BITSETW(inbuf+smb_flags,0);
- BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
- int32 timeout = IVALS(inbuf,smb_timeout);
-#endif
- unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
- unsigned int tran_call = SVAL(inbuf, smb_setup0);
- char *params = NULL, *data = NULL;
- int num_params, num_params_sofar, num_data, num_data_sofar;
-
- outsize = set_message(outbuf,0,0,True);
-
- /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
- is so as a sanity check */
- if(suwcnt != 1 )
- {
- DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
- return(ERROR(ERRSRV,ERRerror));
- }
-
- /* Allocate the space for the maximum needed parameters and data */
- if (total_params > 0)
- params = (char *)malloc(total_params);
- if (total_data > 0)
- data = (char *)malloc(total_data);
-
- if ((total_params && !params) || (total_data && !data))
- {
- DEBUG(2,("Out of memory in reply_trans2\n"));
- return(ERROR(ERRDOS,ERRnomem));
- }
-
- /* Copy the param and data bytes sent with this request into
- the params buffer */
- num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
- num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
-
- if (num_params > total_params || num_data > total_data)
- exit_server("invalid params in reply_trans2");
-
- memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
- memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
-
- if(num_data_sofar < total_data || num_params_sofar < total_params)
- {
- /* We need to send an interim response then receive the rest
- of the parameter/data bytes */
- outsize = set_message(outbuf,0,0,True);
- send_smb(Client,outbuf);
-
- while( num_data_sofar < total_data || num_params_sofar < total_params)
- {
- if(!receive_smb(Client,inbuf, SMB_SECONDARY_WAIT) ||
- CVAL(inbuf, smb_com) != SMBtranss2)
- {
- outsize = set_message(outbuf,0,0,True);
- DEBUG(2,("Invalid secondary trans2 packet\n"));
- free(params);
- free(data);
- return(ERROR(ERRSRV,ERRerror));
- }
-
- /* Revise total_params and total_data in case they have changed downwards */
- total_params = SVAL(inbuf, smb_tpscnt);
- total_data = SVAL(inbuf, smb_tdscnt);
- num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
- num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
- if (num_params_sofar > total_params || num_data_sofar > total_data)
- exit_server("data overflow in trans2");
-
- memcpy( &params[ SVAL(inbuf, smb_spsdisp)],
- smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
- memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
- smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
- }
- }
-
- if (Protocol >= PROTOCOL_NT1) {
- uint16 flg2 = SVAL(outbuf,smb_flg2);
- SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
- }
-
- /* Now we must call the relevant TRANS2 function */
- switch(tran_call)
- {
- case TRANSACT2_OPEN:
- outsize = call_trans2open(inbuf, outbuf, bufsize, cnum, &params, &data);
- break;
- case TRANSACT2_FINDFIRST:
- outsize = call_trans2findfirst(inbuf, outbuf, bufsize, cnum, &params, &data);
- break;
- case TRANSACT2_FINDNEXT:
- outsize = call_trans2findnext(inbuf, outbuf, length, bufsize, cnum, &params, &data);
- break;
- case TRANSACT2_QFSINFO:
- outsize = call_trans2qfsinfo(inbuf, outbuf, length, bufsize, cnum, &params, &data);
- break;
- case TRANSACT2_SETFSINFO:
- outsize = call_trans2setfsinfo(inbuf, outbuf, length, bufsize, cnum, &params, &data);
- break;
- case TRANSACT2_QPATHINFO:
- case TRANSACT2_QFILEINFO:
- outsize = call_trans2qfilepathinfo(inbuf, outbuf, length, bufsize, cnum, &params, &data, total_data);
- break;
- case TRANSACT2_SETPATHINFO:
- case TRANSACT2_SETFILEINFO:
- outsize = call_trans2setfilepathinfo(inbuf, outbuf, length, bufsize, cnum, &params, &data, total_data);
- break;
- case TRANSACT2_FINDNOTIFYFIRST:
- outsize = call_trans2findnotifyfirst(inbuf, outbuf, length, bufsize, cnum, &params, &data);
- break;
- case TRANSACT2_FINDNOTIFYNEXT:
- outsize = call_trans2findnotifynext(inbuf, outbuf, length, bufsize, cnum, &params, &data);
- break;
- case TRANSACT2_MKDIR:
- outsize = call_trans2mkdir(inbuf, outbuf, length, bufsize, cnum, &params, &data);
- break;
- default:
- /* Error in request */
- DEBUG(2,("%s Unknown request %d in trans2 call\n",timestring(), tran_call));
- if(params)
- free(params);
- if(data)
- free(data);
- return (ERROR(ERRSRV,ERRerror));
- }
-
- /* As we do not know how many data packets will need to be
- returned here the various call_trans2xxxx calls
- must send their own. Thus a call_trans2xxx routine only
- returns a value other than -1 when it wants to send
- an error packet.
- */
-
- if(params)
- free(params);
- if(data)
- free(data);
- return outsize; /* If a correct response was needed the call_trans2xxx
- calls have already sent it. If outsize != -1 then it is
- returning an error packet. */
-}
diff --git a/source/smbd/uid.c b/source/smbd/uid.c
deleted file mode 100644
index cdc4e474c61..00000000000
--- a/source/smbd/uid.c
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- uid/user handling
- Copyright (C) Andrew Tridgell 1992-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.
-*/
-
-#include "includes.h"
-
-extern int DEBUGLEVEL;
-
-extern connection_struct Connections[];
-
-static int initial_uid;
-static int initial_gid;
-
-/* what user is current? */
-struct current_user current_user;
-
-extern pstring OriginalDir;
-
-/****************************************************************************
-initialise the uid routines
-****************************************************************************/
-void init_uid(void)
-{
- initial_uid = current_user.uid = geteuid();
- initial_gid = current_user.gid = getegid();
-
- if (initial_gid != 0 && initial_uid == 0)
- {
-#ifdef HPUX
- setresgid(0,0,0);
-#else
- setgid(0);
- setegid(0);
-#endif
- }
-
- initial_uid = geteuid();
- initial_gid = getegid();
-
- current_user.cnum = -1;
-
- ChDir(OriginalDir);
-}
-
-
-/****************************************************************************
- become the specified uid
-****************************************************************************/
-static BOOL become_uid(int uid)
-{
- if (initial_uid != 0)
- return(True);
-
- if (uid == -1 || uid == 65535) {
- DEBUG(1,("WARNING: using uid %d is a security risk\n",uid));
- }
-
-#ifdef AIX
- {
- /* AIX 3 stuff - inspired by a code fragment in wu-ftpd */
- priv_t priv;
-
- priv.pv_priv[0] = 0;
- priv.pv_priv[1] = 0;
- if (setpriv(PRIV_SET|PRIV_INHERITED|PRIV_EFFECTIVE|PRIV_BEQUEATH,
- &priv, sizeof(priv_t)) < 0 ||
- setuidx(ID_REAL|ID_EFFECTIVE, (uid_t)uid) < 0 ||
- seteuid((uid_t)uid) < 0)
- DEBUG(1,("Can't set uid (AIX3)\n"));
- }
-#endif
-
-#ifdef USE_SETRES
- if (setresuid(-1,uid,-1) != 0)
-#elif defined(USE_SETFS)
- if (setfsuid(uid) != 0)
-#else
- if ((seteuid(uid) != 0) &&
- (setuid(uid) != 0))
-#endif
- {
- DEBUG(0,("Couldn't set uid %d currently set to (%d,%d)\n",
- uid,getuid(), geteuid()));
- if (uid > 32000)
- DEBUG(0,("Looks like your OS doesn't like high uid values - try using a different account\n"));
- return(False);
- }
-
- if (((uid == -1) || (uid == 65535)) && geteuid() != uid) {
- DEBUG(0,("Invalid uid -1. perhaps you have a account with uid 65535?\n"));
- return(False);
- }
-
- current_user.uid = uid;
-
- return(True);
-}
-
-
-/****************************************************************************
- become the specified gid
-****************************************************************************/
-static BOOL become_gid(int gid)
-{
- if (initial_uid != 0)
- return(True);
-
- if (gid == -1 || gid == 65535) {
- DEBUG(1,("WARNING: using gid %d is a security risk\n",gid));
- }
-
-#ifdef USE_SETRES
- if (setresgid(-1,gid,-1) != 0)
-#elif defined(USE_SETFS)
- if (setfsgid(gid) != 0)
-#else
- if (setgid(gid) != 0)
-#endif
- {
- DEBUG(0,("Couldn't set gid %d currently set to (%d,%d)\n",
- gid,getgid(),getegid()));
- if (gid > 32000)
- DEBUG(0,("Looks like your OS doesn't like high gid values - try using a different account\n"));
- return(False);
- }
-
- current_user.gid = gid;
-
- return(True);
-}
-
-
-/****************************************************************************
- become the specified uid and gid
-****************************************************************************/
-static BOOL become_id(int uid,int gid)
-{
- return(become_gid(gid) && become_uid(uid));
-}
-
-/****************************************************************************
-become the guest user
-****************************************************************************/
-BOOL become_guest(void)
-{
- BOOL ret;
- static struct passwd *pass=NULL;
-
- if (initial_uid != 0)
- return(True);
-
- if (!pass)
- pass = Get_Pwnam(lp_guestaccount(-1),True);
- if (!pass) return(False);
-
- ret = become_id(pass->pw_uid,pass->pw_gid);
-
- if (!ret)
- DEBUG(1,("Failed to become guest. Invalid guest account?\n"));
-
- current_user.cnum = -2;
-
- return(ret);
-}
-
-/*******************************************************************
-check if a username is OK
-********************************************************************/
-static BOOL check_user_ok(int cnum,user_struct *vuser,int snum)
-{
- int i;
- for (i=0;i<Connections[cnum].uid_cache.entries;i++)
- if (Connections[cnum].uid_cache.list[i] == vuser->uid) return(True);
-
- if (!user_ok(vuser->name,snum)) return(False);
-
- i = Connections[cnum].uid_cache.entries % UID_CACHE_SIZE;
- Connections[cnum].uid_cache.list[i] = vuser->uid;
-
- if (Connections[cnum].uid_cache.entries < UID_CACHE_SIZE)
- Connections[cnum].uid_cache.entries++;
-
- return(True);
-}
-
-
-/****************************************************************************
- become the user of a connection number
-****************************************************************************/
-BOOL become_user(int cnum, uint16 vuid)
-{
- user_struct *vuser = get_valid_user_struct(vuid);
- int snum,gid;
- int uid;
-
- if (current_user.cnum == cnum && vuser != 0 && current_user.id == vuser->uid) {
- DEBUG(4,("Skipping become_user - already user\n"));
- return(True);
- }
-
- unbecome_user();
-
- if (!OPEN_CNUM(cnum)) {
- DEBUG(2,("Connection %d not open\n",cnum));
- return(False);
- }
-
- snum = Connections[cnum].service;
-
- if (Connections[cnum].force_user ||
- lp_security() == SEC_SHARE ||
- !(vuser) || (vuser->guest) ||
- !check_user_ok(cnum,vuser,snum)) {
- uid = Connections[cnum].uid;
- gid = Connections[cnum].gid;
- current_user.groups = Connections[cnum].groups;
- current_user.igroups = Connections[cnum].igroups;
- current_user.ngroups = Connections[cnum].ngroups;
- } else {
- if (!vuser) {
- DEBUG(2,("Invalid vuid used %d\n",vuid));
- return(False);
- }
- uid = vuser->uid;
- if(!*lp_force_group(snum))
- gid = vuser->gid;
- else
- gid = Connections[cnum].gid;
- current_user.groups = vuser->user_groups;
- current_user.igroups = vuser->user_igroups;
- current_user.ngroups = vuser->user_ngroups;
- }
-
- if (initial_uid == 0)
- {
- if (!become_gid(gid)) return(False);
-
-#ifndef NO_SETGROUPS
- if (!IS_IPC(cnum)) {
- /* groups stuff added by ih/wreu */
- if (current_user.ngroups > 0)
- if (setgroups(current_user.ngroups,current_user.groups)<0)
- DEBUG(0,("setgroups call failed!\n"));
- }
-#endif
-
- if (!Connections[cnum].admin_user && !become_uid(uid))
- return(False);
- }
-
- current_user.cnum = cnum;
- current_user.id = uid;
-
- DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n",
- getuid(),geteuid(),getgid(),getegid()));
-
- return(True);
-}
-
-/****************************************************************************
- unbecome the user of a connection number
-****************************************************************************/
-BOOL unbecome_user(void )
-{
- if (current_user.cnum == -1)
- return(False);
-
- ChDir(OriginalDir);
-
- if (initial_uid == 0)
- {
-#ifdef USE_SETRES
- setresuid(-1,getuid(),-1);
- setresgid(-1,getgid(),-1);
-#elif defined(USE_SETFS)
- setfsuid(initial_uid);
- setfsgid(initial_gid);
-#else
- if (seteuid(initial_uid) != 0)
- setuid(initial_uid);
- setgid(initial_gid);
-#endif
- }
-#ifdef NO_EID
- if (initial_uid == 0)
- DEBUG(2,("Running with no EID\n"));
- initial_uid = getuid();
- initial_gid = getgid();
-#else
- if (geteuid() != initial_uid)
- {
- DEBUG(0,("Warning: You appear to have a trapdoor uid system\n"));
- initial_uid = geteuid();
- }
- if (getegid() != initial_gid)
- {
- DEBUG(0,("Warning: You appear to have a trapdoor gid system\n"));
- initial_gid = getegid();
- }
-#endif
-
- current_user.uid = initial_uid;
- current_user.gid = initial_gid;
-
- if (ChDir(OriginalDir) != 0)
- DEBUG(0,("%s chdir(%s) failed in unbecome_user\n",
- timestring(),OriginalDir));
-
- DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n",
- getuid(),geteuid(),getgid(),getegid()));
-
- current_user.cnum = -1;
-
- return(True);
-}
-
-
-/****************************************************************************
-This is a utility function of smbrun(). It must be called only from
-the child as it may leave the caller in a privilaged state.
-****************************************************************************/
-static BOOL setup_stdout_file(char *outfile,BOOL shared)
-{
- int fd;
- struct stat st;
- mode_t mode = S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH;
- int flags = O_RDWR|O_CREAT|O_TRUNC|O_EXCL;
-
- close(1);
-
- if (shared) {
- /* become root - unprivilaged users can't delete these files */
-#ifdef USE_SETRES
- setresgid(0,0,0);
- setresuid(0,0,0);
-#else
- setuid(0);
- seteuid(0);
-#endif
- }
-
- if(stat(outfile, &st) == 0) {
- /* Check we're not deleting a device file. */
- if(st.st_mode & S_IFREG)
- unlink(outfile);
- else
- flags = O_RDWR;
- }
- /* now create the file */
- fd = open(outfile,flags,mode);
-
- if (fd == -1) return False;
-
- if (fd != 1) {
- if (dup2(fd,1) != 0) {
- DEBUG(2,("Failed to create stdout file descriptor\n"));
- close(fd);
- return False;
- }
- close(fd);
- }
- return True;
-}
-
-
-/****************************************************************************
-run a command being careful about uid/gid handling and putting the output in
-outfile (or discard it if outfile is NULL).
-
-if shared is True then ensure the file will be writeable by all users
-but created such that its owned by root. This overcomes a security hole.
-
-if shared is not set then open the file with O_EXCL set
-****************************************************************************/
-int smbrun(char *cmd,char *outfile,BOOL shared)
-{
- int fd,pid;
- int uid = current_user.uid;
- int gid = current_user.gid;
-
-#if USE_SYSTEM
- int ret;
- pstring syscmd;
- char *path = lp_smbrun();
-
- /* in the old method we use system() to execute smbrun which then
- executes the command (using system() again!). This involves lots
- of shell launches and is very slow. It also suffers from a
- potential security hole */
- if (!file_exist(path,NULL))
- {
- DEBUG(0,("SMBRUN ERROR: Can't find %s. Installation problem?\n",path));
- return(1);
- }
-
- sprintf(syscmd,"%s %d %d \"(%s 2>&1) > %s\"",
- path,uid,gid,cmd,
- outfile?outfile:"/dev/null");
-
- DEBUG(5,("smbrun - running %s ",syscmd));
- ret = system(syscmd);
- DEBUG(5,("gave %d\n",ret));
- return(ret);
-#else
- /* in this newer method we will exec /bin/sh with the correct
- arguments, after first setting stdout to point at the file */
-
- if ((pid=fork())) {
- int status=0;
- /* the parent just waits for the child to exit */
- if (sys_waitpid(pid,&status,0) != pid) {
- DEBUG(2,("waitpid(%d) : %s\n",pid,strerror(errno)));
- return -1;
- }
- return status;
- }
-
-
- /* we are in the child. we exec /bin/sh to do the work for us. we
- don't directly exec the command we want because it may be a
- pipeline or anything else the config file specifies */
-
- /* point our stdout at the file we want output to go into */
- if (outfile && !setup_stdout_file(outfile,shared)) {
- exit(80);
- }
-
- /* now completely lose our privilages. This is a fairly paranoid
- way of doing it, but it does work on all systems that I know of */
-#ifdef USE_SETRES
- setresgid(0,0,0);
- setresuid(0,0,0);
- setresgid(gid,gid,gid);
- setresuid(uid,uid,uid);
-#else
- setuid(0);
- seteuid(0);
- setgid(gid);
- setegid(gid);
- setuid(uid);
- seteuid(uid);
-#endif
-
- if (getuid() != uid || geteuid() != uid ||
- getgid() != gid || getegid() != gid) {
- /* we failed to lose our privilages - do not execute the command */
- exit(81); /* we can't print stuff at this stage, instead use exit codes
- for debugging */
- }
-
- /* close all other file descriptors, leaving only 0, 1 and 2. 0 and
- 2 point to /dev/null from the startup code */
- for (fd=3;fd<256;fd++) close(fd);
-
- execl("/bin/sh","sh","-c",cmd,NULL);
-
- /* not reached */
- exit(82);
-#endif
- return 1;
-}
diff --git a/source/smbd/vt_mode.c b/source/smbd/vt_mode.c
deleted file mode 100644
index 07558274a52..00000000000
--- a/source/smbd/vt_mode.c
+++ /dev/null
@@ -1,490 +0,0 @@
-/* vt_mode.c */
-/*
-support vtp-sessions
-
-written by Christian A. Lademann <cal@zls.com>
-*/
-
-/*
-02.05.95:cal:ported to samba-1.9.13
-*/
-
-#define __vt_mode_c__
-
-
-/* #include <stdio.h> */
-/* #include <fcntl.h> */
-/* #include <sys/types.h> */
-/* #include <unistd.h> */
-/* #include <signal.h> */
-/* #include <errno.h> */
-/* #include <ctype.h> */
-/* #include <utmp.h> */
-/* #include <sys/param.h> */
-/* #include <sys/ioctl.h> */
-/* #include <stdlib.h> */
-/* #include <string.h> */
-
-#include "includes.h"
-#include "vt_mode.h"
-#include <utmp.h>
-
-#ifdef SCO
- extern char *strdup();
-#endif
-
-extern int Client;
-
-#ifdef LINUX
-# define HAS_VTY
-#endif
-
-#ifdef SCO
-# define HAS_PTY
-# define HAS_VTY
-
-# include <sys/tty.h>
-#endif
-
-extern int DEBUGLEVEL;
-extern char *InBuffer, *OutBuffer;
-extern int done_become_user;
-
-char master_name [64], slave_name [64];
-int master, slave, i, o, e;
-
-int ms_type = MS_NONE,
- ms_poll = 0;
-
-
-/*
-VT_Check: test incoming packet for "vtp" or "iVT1\0"
-*/
-int VT_Check(char *buffer)
-{
- DEBUG(3,("Checking packet: <%10s...>\n", buffer+4));
- if((strncmp(buffer+4, "vtp", 3) == 0 && smb_len(buffer) == 3) || (strncmp(buffer+4, "iVT1\0", 5) == 0 && smb_len(buffer) == 5))
- return(1);
- else
- return(0);
-}
-
-
-/*
-VT_Start_utmp: prepare /etc/utmp for /bin/login
-*/
-int VT_Start_utmp(void)
-{
- struct utmp u, *v;
- char *tt;
-
-
- setutent();
-
- fstrcpy(u.ut_line, VT_Line);
-
- if((v = getutline(&u)) == NULL) {
- if(strncmp(VT_Line, "tty", 3) == 0)
- tt = VT_Line + 3;
- else if(strlen(VT_Line) > 4)
- tt = VT_Line + strlen(VT_Line) - 4;
- else
- tt = VT_Line;
-
- fstrcpy(u.ut_id, tt);
- u.ut_time = time((time_t*)0);
- }
-
- fstrcpy(u.ut_user, "LOGIN");
- fstrcpy(u.ut_line, VT_Line);
- u.ut_pid = getpid();
- u.ut_type = LOGIN_PROCESS;
- pututline(&u);
-
- endutent();
-
- return(0);
-}
-
-
-/*
-VT_Stop_utmp: prepare /etc/utmp for other processes
-*/
-int VT_Stop_utmp(void)
-{
- struct utmp u, *v;
-
-
- if(VT_Line != NULL) {
- setutent();
-
- fstrcpy(u.ut_line, VT_Line);
-
- if((v = getutline(&u)) != NULL) {
- fstrcpy(v->ut_user, "");
- v->ut_type = DEAD_PROCESS;
- v->ut_time = time((time_t*)0);
- pututline(v);
- }
-
- endutent();
- }
-
- return(0);
-}
-
-
-/*
-VT_AtExit: Things to do when the program exits
-*/
-void VT_AtExit(void)
-{
- if(VT_ChildPID > 0) {
- kill(VT_ChildPID, SIGHUP);
- (void)wait(NULL);
- }
-
- VT_Stop_utmp();
-}
-
-
-/*
-VT_SigCLD: signalhandler for SIGCLD: set flag if child-process died
-*/
-void VT_SigCLD(int sig)
-{
- if(wait(NULL) == VT_ChildPID)
- VT_ChildDied = True;
- else
- signal(SIGCLD, VT_SigCLD);
-}
-
-
-/*
-VT_SigEXIT: signalhandler for signals that cause the process to exit
-*/
-void VT_SigEXIT(int sig)
-{
- VT_AtExit();
-
- exit(1);
-}
-
-
-/*
-VT_Start: initialize vt-specific data, alloc pty, spawn shell and send ACK
-*/
-int VT_Start(void)
-{
- char OutBuf [64], *X, *Y;
-
-
- ms_type = MS_NONE;
- master = slave = -1;
-
-#ifdef HAS_VTY
-#ifdef LINUX
-# define MASTER_TMPL "/dev/pty "
-# define SLAVE_TMPL "/dev/tty "
-# define LETTER1 "pqrs"
-# define POS1 8
-# define LETTER2 "0123456789abcdef"
-# define POS2 9
-#endif
-
-#ifdef SCO
-# define MASTER_TMPL "/dev/ptyp_ "
-# define SLAVE_TMPL "/dev/ttyp_ "
-# define LETTER1 "0123456"
-# define POS1 10
-# define LETTER2 "0123456789abcdef"
-# define POS2 11
-#endif
-
- if(ms_poll == MS_VTY || ms_poll == 0) {
- strcpy(master_name, MASTER_TMPL);
- strcpy(slave_name, SLAVE_TMPL);
-
- for(X = LETTER1; *X && master < 0; X++)
- for(Y = LETTER2; *Y && master < 0; Y++) {
- master_name [POS1] = *X;
- master_name [POS2] = *Y;
- if((master = open(master_name, O_RDWR)) >= 0) {
- slave_name [POS1] = *X;
- slave_name [POS2] = *Y;
- if((slave = open(slave_name, O_RDWR)) < 0)
- close(master);
- }
- }
-
- if(master >= 0 && slave >= 0)
- ms_type = MS_VTY;
- }
-
-# undef MASTER_TMPL
-# undef SLAVE_TMPL
-# undef LETTER1
-# undef LETTER2
-# undef POS1
-# undef POS2
-#endif
-
-
-#ifdef HAS_PTY
-#ifdef SCO
-# define MASTER_TMPL "/dev/ptyp%d"
-# define SLAVE_TMPL "/dev/ttyp%d"
-# define MIN_I 0
-# define MAX_I 63
-#endif
-
- if(ms_poll == MS_PTY || ms_poll == 0) {
- int i;
-
- for(i = MIN_I; i <= MAX_I && master < 0; i++) {
- sprintf(master_name, MASTER_TMPL, i);
- if((master = open(master_name, O_RDWR)) >= 0) {
- sprintf(slave_name, SLAVE_TMPL, i);
- if((slave = open(slave_name, O_RDWR)) < 0)
- close(master);
- }
- }
-
- if(master >= 0 && slave >= 0)
- ms_type = MS_PTY;
- }
-
-# undef MASTER_TMPL
-# undef SLAVE_TMPL
-# undef MIN_I
-# undef MAX_I
-#endif
-
-
- if(! ms_type)
- return(-1);
-
- VT_Line = strdup(strrchr(slave_name, '/') + 1);
-
- switch((VT_ChildPID = fork())) {
- case -1:
- return(-1);
- break;
-
- case 0:
-#ifdef SCO
- setsid();
-#endif
- close(0);
- close(1);
- close(2);
-
- i = open(slave_name, O_RDWR);
- o = open(slave_name, O_RDWR);
- e = open(slave_name, O_RDWR);
-
-#ifdef LINUX
- setsid();
- if (ioctl(slave, TIOCSCTTY, (char *)NULL) == -1)
- exit(1);
-#endif
-#ifdef SCO
- tcsetpgrp(0, getpid());
-#endif
-
- VT_Start_utmp();
-
- system("stty sane");
- execlp("/bin/login", "login", "-c", (char*)0);
- exit(1);
- break;
-
- default:
- VT_Mode = True;
- VT_Status = VT_OPEN;
- VT_ChildDied = False;
- VT_Fd = master;
-
- signal(SIGCLD, VT_SigCLD);
-
- signal(SIGHUP, VT_SigEXIT);
- signal(SIGTERM, VT_SigEXIT);
- signal(SIGINT, VT_SigEXIT);
- signal(SIGQUIT, VT_SigEXIT);
-
- memset(OutBuf, 0, sizeof(OutBuf));
- OutBuf [4] = 0x06;
- _smb_setlen(OutBuf, 1);
-
- send_smb(Client,OutBuf);
-
- return(0);
- break;
- }
-}
-
-
-/*
-VT_Output: transport data from socket to pty
-*/
-int VT_Output(char *Buffer)
-{
- int i, len, nb;
-
-
- if(VT_Status != VT_OPEN)
- return(-1);
-
- len = smb_len(Buffer);
-
- nb = write(VT_Fd, Buffer + 4, len);
-
- return((nb == len) ? 0 : -1);
-}
-
-
-/*
-VT_Input: transport data from pty to socket
-*/
-int VT_Input(char *Buffer,int Size)
-{
- int len;
-
-
- if(VT_Status != VT_OPEN)
- return(-1);
-
- memset(Buffer, 0, Size);
- len = read(VT_Fd, Buffer + 4, MIN(VT_MAXREAD, Size));
-
- _smb_setlen(Buffer, len);
-
- return(len + 4);
-}
-
-
-/*
-VT_Process: main loop while in vt-mode
-*/
-void VT_Process(void)
-{
- static int trans_num = 0;
- extern int Client;
- int nread;
-
-
- VT_Start();
-
- atexit(VT_AtExit);
-
- while (True) {
- int32 len;
- int msg_type;
- int msg_flags;
- int counter;
- int last_keepalive=0;
- struct fd_set si;
- struct timeval to, *top;
- int n, ret, t;
-
-
- errno = 0;
- t = SMBD_SELECT_LOOP*1000;
-
-
- FD_ZERO(&si);
- FD_SET(Client, &si);
-
- FD_SET(VT_Fd, &si);
-
- if(t >= 0) {
- to.tv_sec = t / 1000;
- to.tv_usec = t - (to.tv_sec * 1000);
-
- top = &to;
- } else
- top = NULL;
-
- if(VT_ChildDied)
- goto leave_VT_Process;
-
- n = select(MAX(VT_Fd, Client) + 1, &si, NULL, NULL, top);
-
- if(VT_ChildDied)
- goto leave_VT_Process;
-
- if(n == 0) {
- int i;
- time_t t;
- BOOL allidle = True;
- extern int keepalive;
-
- counter += SMBD_SELECT_LOOP;
-
- t = time(NULL);
-
- if (keepalive && (counter-last_keepalive)>keepalive) {
- if (!send_keepalive(Client))
- goto leave_VT_Process;
- last_keepalive = counter;
- }
- } else if(n > 0) {
- counter = 0;
-
- if(FD_ISSET(VT_Fd, &si)) {
- /* got input from vt */
- nread = VT_Input(OutBuffer, MIN(BUFFER_SIZE,lp_maxxmit()));
-
- if(nread > 0)
- send_smb(Client,OutBuffer);
- }
-
- if(FD_ISSET(Client, &si)) {
- /* got input from socket */
-
- if(receive_smb(Client,InBuffer, 0)) {
- msg_type = CVAL(InBuffer,0);
- msg_flags = CVAL(InBuffer,1);
-
- len = smb_len(InBuffer);
-
- DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len));
-
- nread = len + 4;
-
- DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread));
-
- if(msg_type == 0)
- VT_Output(InBuffer);
- else {
- nread = construct_reply(InBuffer,OutBuffer,nread,MIN(BUFFER_SIZE,lp_maxxmit()));
-
- if(nread > 0) {
- if (nread != smb_len(OutBuffer) + 4) {
- DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
- nread,
- smb_len(OutBuffer)));
- } else
- send_smb(Client,OutBuffer);
- }
- }
- } else
- if(errno == EBADF)
- goto leave_VT_Process;
- }
- }
-
- trans_num++;
- }
-
- leave_VT_Process:
-/*
- if(VT_ChildPID > 0)
- kill(VT_ChildPID, SIGHUP);
-
- VT_Stop_utmp(VT_Line);
- return;
-*/
- close_sockets();
- exit(0);
-}
diff --git a/source/smbparse.c b/source/smbparse.c
deleted file mode 100644
index 01438281ef1..00000000000
--- a/source/smbparse.c
+++ /dev/null
@@ -1,551 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Samba utility functions
- Copyright (C) Luke Leighton 1996 - 1997 Paul Ashton 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.
-*/
-
-#include "includes.h"
-
-extern int DEBUGLEVEL;
-
-
-/*******************************************************************
-reads or writes a UTIME type.
-********************************************************************/
-char* smb_io_utime(BOOL io, UTIME *t, char *q, char *base, int align)
-{
- if (t == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- RW_IVAL (io, q, t->time, 0); q += 4;
-
- return q;
-}
-
-/*******************************************************************
-reads or writes an NTTIME structure.
-********************************************************************/
-char* smb_io_time(BOOL io, NTTIME *nttime, char *q, char *base, int align)
-{
- if (nttime == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- RW_IVAL(io, q, nttime->low , 0); q += 4; /* low part */
- RW_IVAL(io, q, nttime->high, 0); q += 4; /* high part */
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a DOM_SID structure.
-********************************************************************/
-char* smb_io_dom_sid(BOOL io, DOM_SID *sid, char *q, char *base, int align)
-{
- int i;
-
- if (sid == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- RW_CVAL(io, q, sid->sid_no, 0); q++;
- RW_CVAL(io, q, sid->num_auths, 0); q++;
-
- for (i = 0; i < 6; i++)
- {
- RW_CVAL(io, q, sid->id_auth[i], 0); q++;
- }
-
- /* oops! XXXX should really issue a warning here... */
- if (sid->num_auths > MAXSUBAUTHS) sid->num_auths = MAXSUBAUTHS;
-
- RW_PSVAL(io, q, sid->sub_auths, sid->num_auths); q += sid->num_auths * 2;
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a UNIHDR structure.
-********************************************************************/
-char* smb_io_unihdr(BOOL io, UNIHDR *hdr, char *q, char *base, int align)
-{
- if (hdr == NULL) return NULL;
-
- /* should be value 4, so enforce it. */
- hdr->undoc = 4;
-
- q = align_offset(q, base, align);
-
- RW_IVAL(io, q, hdr->uni_max_len, 0); q += 4;
- RW_IVAL(io, q, hdr->uni_str_len, 0); q += 4;
- RW_IVAL(io, q, hdr->undoc , 0); q += 4;
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a UNIHDR2 structure.
-********************************************************************/
-char* smb_io_unihdr2(BOOL io, UNIHDR2 *hdr2, char *q, char *base, int align)
-{
- if (hdr2 == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- q = smb_io_unihdr(io, &(hdr2->unihdr), q, base, align);
- RW_IVAL(io, q, hdr2->undoc_buffer, 0); q += 4;
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a UNISTR structure.
-XXXX NOTE: UNISTR structures NEED to be null-terminated.
-********************************************************************/
-char* smb_io_unistr(BOOL io, UNISTR *uni, char *q, char *base, int align)
-{
- if (uni == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- if (io)
- {
- /* io True indicates read _from_ the SMB buffer into the string */
- q += 2 * unistrcpy((char*)uni->buffer, q);
- }
- else
- {
- /* io True indicates copy _from_ the string into SMB buffer */
- q += 2 * unistrcpy(q, (char*)uni->buffer);
- }
- return q;
-}
-
-/*******************************************************************
-reads or writes a UNISTR2 structure.
-XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
- the uni_str_len member tells you how long the string is;
- the uni_max_len member tells you how large the buffer is.
-********************************************************************/
-char* smb_io_unistr2(BOOL io, UNISTR2 *uni2, char *q, char *base, int align)
-{
- if (uni2 == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- /* should be value 0, so enforce it. */
- uni2->undoc = 0;
-
- RW_IVAL(io, q, uni2->uni_max_len, 0); q += 4;
- RW_IVAL(io, q, uni2->undoc , 0); q += 4;
- RW_IVAL(io, q, uni2->uni_str_len, 0); q += 4;
-
- /* oops! XXXX maybe issue a warning that this is happening... */
- if (uni2->uni_max_len > MAX_UNISTRLEN) uni2->uni_max_len = MAX_UNISTRLEN;
- if (uni2->uni_str_len > MAX_UNISTRLEN) uni2->uni_str_len = MAX_UNISTRLEN;
-
- /* buffer advanced by indicated length of string
- NOT by searching for null-termination */
- RW_PSVAL(io, q, uni2->buffer, uni2->uni_max_len); q += uni2->uni_max_len * 2;
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a DOM_SID2 structure.
-********************************************************************/
-char* smb_io_dom_sid2(BOOL io, DOM_SID2 *sid2, char *q, char *base, int align)
-{
- if (sid2 == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- /* should be value 5, so enforce it */
- sid2->type = 5;
-
- /* should be value 0, so enforce it */
- sid2->undoc = 0;
-
- RW_IVAL(io, q, sid2->type , 0); q += 4;
- RW_IVAL(io, q, sid2->undoc, 0); q += 4;
-
- q = smb_io_unihdr2(io, &(sid2->hdr), q, base, align);
- q = smb_io_unistr (io, &(sid2->str), q, base, align);
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a DOM_RID2 structure.
-********************************************************************/
-char* smb_io_dom_rid2(BOOL io, DOM_RID2 *rid2, char *q, char *base, int align)
-{
- if (rid2 == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- /* should be value 5, so enforce it */
- rid2->type = 5;
-
- /* should be value 5, so enforce it */
- rid2->undoc = 5;
-
- RW_IVAL(io, q, rid2->type, 0); q += 4;
- RW_IVAL(io, q, rid2->undoc , 0); q += 4;
- RW_IVAL(io, q, rid2->rid , 0); q += 4;
- RW_IVAL(io, q, rid2->rid_idx , 0); q += 4;
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a DOM_LOG_INFO structure.
-********************************************************************/
-char* smb_io_log_info(BOOL io, DOM_LOG_INFO *log, char *q, char *base, int align)
-{
- if (log == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- RW_IVAL(io, q, log->undoc_buffer, 0); q += 4;
-
- q = smb_io_unistr2(io, &(log->uni_logon_srv), q, base, align);
- q = smb_io_unistr2(io, &(log->uni_acct_name), q, base, align);
-
- RW_SVAL(io, q, log->sec_chan, 0); q += 2;
-
- /* XXXX no alignment required between sec_chan and uni_comp_name */
- q = smb_io_unistr2(io, &(log->uni_comp_name), q, base, 0);
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a DOM_CHAL structure.
-********************************************************************/
-char* smb_io_chal(BOOL io, DOM_CHAL *chal, char *q, char *base, int align)
-{
- if (chal == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- RW_PCVAL(io, q, chal->data, 8); q += 8;
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a DOM_CRED structure.
-********************************************************************/
-char* smb_io_cred(BOOL io, DOM_CRED *cred, char *q, char *base, int align)
-{
- if (cred == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- q = smb_io_chal (io, &(cred->challenge), q, base, align);
- q = smb_io_utime(io, &(cred->timestamp), q, base, align);
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a DOM_CLNT_INFO structure.
-********************************************************************/
-char* smb_io_clnt_info(BOOL io, DOM_CLNT_INFO *clnt, char *q, char *base, int align)
-{
- if (clnt == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- q = smb_io_log_info(io, &(clnt->login), q, base, align);
- q = smb_io_cred (io, &(clnt->cred ), q, base, align);
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a DOM_LOGON_ID structure.
-********************************************************************/
-char* smb_io_logon_id(BOOL io, DOM_LOGON_ID *log, char *q, char *base, int align)
-{
- if (log == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- RW_IVAL(io, q, log->low , 0); q += 4;
- RW_IVAL(io, q, log->high, 0); q += 4;
-
- return q;
-}
-
-/*******************************************************************
-reads or writes an ARC4_OWF structure.
-********************************************************************/
-char* smb_io_arc4_owf(BOOL io, ARC4_OWF *hash, char *q, char *base, int align)
-{
- if (hash == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- RW_PCVAL(io, q, hash->data, 16); q += 16;
-
- return q;
-}
-
-/*******************************************************************
-reads or writes an DOM_ID_INFO_1 structure.
-********************************************************************/
-char* smb_io_id_info1(BOOL io, DOM_ID_INFO_1 *id, char *q, char *base, int align)
-{
- if (id == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- q = smb_io_unihdr(io, &(id->hdr_domain_name ), q, base, align);
-
- RW_IVAL(io, q, id->param, 0); q += 4;
- q = smb_io_logon_id(io, &(id->logon_id), q, base, align);
-
- q = smb_io_unihdr(io, &(id->hdr_user_name ), q, base, align);
- q = smb_io_unihdr(io, &(id->hdr_workgroup_name), q, base, align);
-
- q = smb_io_arc4_owf(io, &(id->arc4_lm_owf), q, base, align);
- q = smb_io_arc4_owf(io, &(id->arc4_nt_owf), q, base, align);
-
- q = smb_io_unistr2(io, &(id->uni_domain_name ), q, base, align);
- q = smb_io_unistr2(io, &(id->uni_user_name ), q, base, align);
- q = smb_io_unistr2(io, &(id->uni_workgroup_name), q, base, align);
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a DOM_SAM_INFO structure.
-********************************************************************/
-char* smb_io_sam_info(BOOL io, DOM_SAM_INFO *sam, char *q, char *base, int align)
-{
- if (sam == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- q = smb_io_clnt_info(io, &(sam->client ), q, base, align);
- q = smb_io_cred (io, &(sam->rtn_cred), q, base, align);
-
- RW_IVAL(io, q, sam->logon_level, 0); q += 4;
- RW_SVAL(io, q, sam->auth_level , 0); q += 4;
-
- switch (sam->auth_level)
- {
- case 1:
- {
- q = smb_io_id_info1(io, &(sam->auth.id1), q, base, align);
- break;
- }
- default:
- {
- /* PANIC! */
- break;
- }
- }
- return q;
-}
-
-/*******************************************************************
-reads or writes a DOM_GID structure.
-********************************************************************/
-char* smb_io_gid(BOOL io, DOM_GID *gid, char *q, char *base, int align)
-{
- if (gid == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- RW_IVAL(io, q, gid->gid , 0); q += 4;
- RW_IVAL(io, q, gid->attr, 0); q += 4;
-
- return q;
-}
-
-/*******************************************************************
-reads or writes an RPC_HDR structure.
-********************************************************************/
-char* smb_io_rpc_hdr(BOOL io, RPC_HDR *rpc, char *q, char *base, int align)
-{
- if (rpc == NULL) return NULL;
-
- /* reserved should be zero: enforce it */
- rpc->reserved = 0;
-
- RW_CVAL(io, q, rpc->major, 0); q++;
- RW_CVAL(io, q, rpc->minor, 0); q++;
- RW_CVAL(io, q, rpc->pkt_type, 0); q++;
- RW_CVAL(io, q, rpc->frag, 0); q++;
- RW_IVAL(io, q, rpc->pack_type, 0); q += 4;
- RW_SVAL(io, q, rpc->frag_len, 0); q += 2;
- RW_SVAL(io, q, rpc->auth_len, 0); q += 2;
- RW_IVAL(io, q, rpc->call_id, 0); q += 4;
- RW_SVAL(io, q, rpc->alloc_hint, 0); q += 2;
- RW_CVAL(io, q, rpc->context_id, 0); q++;
- RW_CVAL(io, q, rpc->reserved, 0); q++;
-
- return q;
-}
-
-/*******************************************************************
-reads or writes an LSA_POL_HND structure.
-********************************************************************/
-char* smb_io_pol_hnd(BOOL io, LSA_POL_HND *pol, char *q, char *base, int align)
-{
- if (pol == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- RW_PCVAL(io, q, pol->data, POL_HND_SIZE); q += POL_HND_SIZE;
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a dom query structure.
-********************************************************************/
-char* smb_io_dom_query_3(BOOL io, DOM_QUERY_3 *d_q, char *q, char *base, int align)
-{
- return smb_io_dom_query(io, d_q, q, base, align);
-}
-
-/*******************************************************************
-reads or writes a dom query structure.
-********************************************************************/
-char* smb_io_dom_query_5(BOOL io, DOM_QUERY_3 *d_q, char *q, char *base, int align)
-{
- return smb_io_dom_query(io, d_q, q, base, align);
-}
-
-/*******************************************************************
-reads or writes a dom query structure.
-********************************************************************/
-char* smb_io_dom_query(BOOL io, DOM_QUERY *d_q, char *q, char *base, int align)
-{
- if (d_q == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
-
- RW_SVAL(io, q, d_q->uni_dom_max_len, 0); q += 2; /* domain name string length * 2 */
- RW_SVAL(io, q, d_q->padding , 0); q += 2; /* 2 padding bytes */
- RW_SVAL(io, q, d_q->uni_dom_str_len, 0); q += 2; /* domain name string length * 2 */
-
- RW_IVAL(io, q, d_q->buffer_dom_name, 0); q += 4; /* undocumented domain name string buffer pointer */
- RW_IVAL(io, q, d_q->buffer_dom_sid , 0); q += 4; /* undocumented domain SID string buffer pointer */
-
- if (d_q->buffer_dom_name != 0)
- {
- q = smb_io_unistr2(io, &(d_q->uni_domain_name), q, base, align); /* domain name (unicode string) */
- }
- if (d_q->buffer_dom_sid != 0)
- {
- q = smb_io_dom_sid(io, &(d_q->dom_sid), q, base, align); /* domain SID */
- }
-
- return q;
-}
-
-/*******************************************************************
-reads or writes a DOM_R_REF structure.
-********************************************************************/
-char* smb_io_dom_r_ref(BOOL io, DOM_R_REF *r_r, char *q, char *base, int align)
-{
- int i;
-
- if (r_r == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- RW_IVAL(io, q, r_r->undoc_buffer, 0); q += 4; /* undocumented buffer pointer. */
- RW_IVAL(io, q, r_r->num_ref_doms_1, 0); q += 4; /* num referenced domains? */
- RW_IVAL(io, q, r_r->buffer_dom_name, 0); q += 4; /* undocumented domain name buffer pointer. */
- RW_IVAL(io, q, r_r->max_entries, 0); q += 4; /* 32 - max number of entries */
- RW_IVAL(io, q, r_r->num_ref_doms_2, 0); q += 4; /* 4 - num referenced domains? */
-
- q = smb_io_unihdr2(io, &(r_r->hdr_dom_name), q, base, align); /* domain name unicode string header */
-
- for (i = 0; i < r_r->num_ref_doms_1-1; i++)
- {
- q = smb_io_unihdr2(io, &(r_r->hdr_ref_dom[i]), q, base, align);
- }
-
- q = smb_io_unistr(io, &(r_r->uni_dom_name), q, base, align); /* domain name unicode string */
-
- for (i = 0; i < r_r->num_ref_doms_2; i++)
- {
- q = smb_io_dom_sid(io, &(r_r->ref_dom[i]), q, base, align); /* referenced domain SIDs */
- }
- return q;
-}
-
-/*******************************************************************
-reads or writes a DOM_NAME structure.
-********************************************************************/
-char* smb_io_dom_name(BOOL io, DOM_NAME *name, char *q, char *base, int align)
-{
- if (name == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- RW_IVAL(io, q, name->uni_str_len, 0); q += 4;
-
- /* don't know if len is specified by uni_str_len member... */
- /* assume unicode string is unicode-null-terminated, instead */
-
- q = smb_io_unistr(io, &(name->str), q, base, align);
-
- return q;
-}
-
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-char* smb_io_neg_flags(BOOL io, NEG_FLAGS *neg, char *q, char *base, int align)
-{
- if (neg == NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- RW_IVAL(io, q, neg->neg_flags, 0); q += 4;
-
- return q;
-}
-
-
-#if 0
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
- char* smb_io_(BOOL io, *, char *q, char *base, int align)
-{
- if (== NULL) return NULL;
-
- q = align_offset(q, base, align);
-
- RW_IVAL(io, q, , 0); q += 4;
-
- return q;
-}
-#endif
diff --git a/source/utils/make_smbcodepage.c b/source/utils/make_smbcodepage.c
deleted file mode 100644
index b4cb1523349..00000000000
--- a/source/utils/make_smbcodepage.c
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Create codepage files from codepage_def.XXX files.
-
- Copyright (C) Jeremy Allison 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.
-*/
-
-#include "includes.h"
-
-static char *prog_name = NULL;
-
-/*
- * Print program usage and die.
- */
-
-void codepage_usage(char *progname)
-{
- fprintf(stderr, "Usage is : %s [c|d] <codepage> <inputfile> <outputfile>\n",
- progname);
- exit(1);
-}
-
-/*
- * Read a line from a buffer into a line buffer. Ensure null
- * terminated.
- */
-
-void read_line( char **buf, char *line_buf, int size)
-{
- char *p = *buf;
- int num = 0;
-
- for(; *p && (*p != '\n'); p++)
- {
- if(num < (size - 1))
- line_buf[num++] = *p;
- }
- if(*p)
- p++; /* Go past the '\n' */
- line_buf[num] = '\0';
- *buf = p;
-}
-
-/*
- * Strip comment lines and blank lines from the data.
- * Copies into a new buffer and frees the old.
- * Returns the number of lines copied.
- */
-
-int clean_data( char **buf, uint32 *size)
-{
- char linebuf[512];
- char *p = *buf;
- int num_lines = 0;
- char *newbuf = (char *)malloc( *size + 1);
- char *newbuf_p = NULL;
-
- if(newbuf == NULL)
- {
- fprintf(stderr, "%s: malloc fail for size %d.\n", prog_name, *size + 1);
- exit(1);
- }
-
- newbuf_p = newbuf;
- *newbuf_p = '\0';
-
- while( *p )
- {
- char *cp;
-
- read_line( &p, linebuf, sizeof(linebuf));
- /* Null terminate after comment. */
- if((cp = strchr( linebuf, '#'))!= NULL)
- *cp = '\0';
-
- for(cp = linebuf;*cp && isspace(*cp); cp++)
- ;
-
- if(*cp == '\0')
- continue;
-
- strcpy(newbuf_p, cp);
- num_lines++;
- newbuf_p += (strlen(newbuf_p) + 1);
- }
-
- free(*buf);
- *buf = newbuf;
- return num_lines;
-}
-
-/*
- * Parse a byte from a codepage file.
- */
-
-BOOL parse_byte(char *buf, unsigned char *bp)
-{
- unsigned int b;
- char *endptr = NULL;
-
- b = (unsigned int)strtol(buf, &endptr, 0);
- if(endptr == buf || b > 255)
- return False;
-
- *bp = (unsigned char)b;
- return True;
-}
-
-/*
- * Parse a bool from a codepage file.
- */
-
-BOOL parse_bool(char *buf, unsigned char *bp)
-{
- if(isdigit(*buf))
- {
- char *endptr = NULL;
-
- *bp = (unsigned char)strtol(buf, &endptr, 0);
- if(endptr == buf )
- return False;
- if(*bp != 0)
- *bp = 1;
- } else {
- if(strcasecmp(buf, "True") && strcasecmp(buf, "False"))
- return False;
- if(strcasecmp(buf, "True")==0)
- *bp = 1;
- else
- *bp = 0;
- }
- return True;
-}
-
-/*
- * Print a parse error and exit.
- */
-
-void parse_error(char *buf, char *msg)
-{
- fprintf(stderr, "%s: %s whilst parsing line \n%s\n", prog_name,
- msg, buf);
- exit(1);
-}
-
-/*
- * Create a compiled codepage file from a codepage definition file.
- */
-
-int do_compile(int codepage, char *input_file, char *output_file)
-{
- FILE *fp = NULL;
- uint32 size = 0;
- char *buf = NULL;
- char output_buf[CODEPAGE_HEADER_SIZE + 512];
- int num_lines = 0;
- int i = 0;
- struct stat st;
-
- /* Get the size of the input file. Read the entire thing into memory. */
- if(stat((char *)input_file, &st)!= 0)
- {
- fprintf(stderr, "%s: failed to get the file size for file %s. Error was %s\n",
- prog_name, input_file, strerror(errno));
- exit(1);
- }
-
- size = (uint32)st.st_size;
-
- /* I don't believe these things should be bigger than 100k :-) */
- if(size > 100*1024)
- {
- fprintf(stderr, "%s: filesize %d is too large for a codepage definition file. \
-The maximum size I will believe is 100k.\n", prog_name, size);
- exit(1);
- }
-
- if((fp = fopen(input_file, "r")) == NULL)
- {
- fprintf(stderr, "%s: cannot open file %s for input.\n", prog_name, input_file);
- exit(1);
- }
-
- /* As we will be reading text, allocate one more byte for a '\0' */
- if((buf = (char *)malloc( size + 1 )) == NULL)
- {
- fprintf(stderr, "%s: malloc fail for size %d.\n", prog_name, size + 1);
- fclose(fp);
- exit(1);
- }
-
- if(fread( buf, 1, size, fp) != size)
- {
- fprintf(stderr, "%s: read failed for file %s. Error was %s.\n", prog_name,
- input_file, strerror(errno));
- free((char *)buf);
- fclose(fp);
- exit(1);
- }
-
- /* Null terminate the text read. */
- buf[size] = '\0';
-
- /* Go through the data line by line, strip out comments (anything
- after a '#' to end-of-line) and blank lines. The rest should be
- the codepage data.
- */
-
- num_lines = clean_data( &buf, &size);
-
- /* There can be a maximum of 128 lines. */
- if(num_lines > 128)
- {
- fprintf(stderr, "%s: There can be a maximum 128 lines of data in a codepage \
-definition file. File %s has %d.\n", prog_name, input_file, num_lines);
- exit(1);
- }
-
- /* Setup the output file header. */
- SSVAL(output_buf,CODEPAGE_VERSION_OFFSET,CODEPAGE_FILE_VERSION_ID);
- SSVAL(output_buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET,(uint16)codepage);
- SIVAL(output_buf,CODEPAGE_LENGTH_OFFSET,(num_lines * 4));
-
- /* Now convert the lines into the compiled form. */
- for(i = 0; i < num_lines; i++)
- {
- char token_buf[512];
- char *p = buf;
- unsigned char b = 0;
-
- /* Get the 'lower' value. */
- if(!next_token(&p, token_buf, NULL))
- parse_error(buf, "cannot parse first value");
- if(!parse_byte( token_buf, &b))
- parse_error(buf, "first value doesn't resolve to a byte");
-
- /* Add this to the output buffer. */
- SCVAL(output_buf,CODEPAGE_HEADER_SIZE+(i*4),b);
-
- /* Get the 'upper' value. */
- if(!next_token(&p, token_buf, NULL))
- parse_error(buf, "cannot parse second value");
- if(!parse_byte( token_buf, &b))
- parse_error(buf, "second value doesn't resolve to a byte");
-
- /* Add this to the output buffer. */
- SCVAL(output_buf,CODEPAGE_HEADER_SIZE+(i*4) + 1,b);
-
- /* Get the 'upper to lower' value. */
- if(!next_token(&p, token_buf, NULL))
- parse_error(buf, "cannot parse third value");
- if(!parse_bool( token_buf, &b))
- parse_error(buf, "third value doesn't resolve to a boolean");
-
- /* Add this to the output buffer. */
- SCVAL(output_buf,CODEPAGE_HEADER_SIZE+(i*4) + 2,b);
-
- /* Get the 'lower to upper' value. */
- if(!next_token(&p, token_buf, NULL))
- parse_error(buf, "cannot parse fourth value");
- if(!parse_bool( token_buf, &b))
- parse_error(buf, "fourth value doesn't resolve to a boolean");
-
- /* Add this to the output buffer. */
- SCVAL(output_buf,CODEPAGE_HEADER_SIZE+(i*4) + 3,b);
-
- buf += (strlen(buf) + 1);
- }
-
- /* Now write out the output_buf. */
- if((fp = fopen(output_file, "w"))==NULL)
- {
- fprintf(stderr, "%s: Cannot open output file %s. Error was %s.\n",
- prog_name, output_file, strerror(errno));
- exit(1);
- }
-
- if(fwrite(output_buf, 1, CODEPAGE_HEADER_SIZE + (num_lines*4), fp) !=
- CODEPAGE_HEADER_SIZE + (num_lines*4))
- {
- fprintf(stderr, "%s: Cannot write output file %s. Error was %s.\n",
- prog_name, output_file, strerror(errno));
- exit(1);
- }
-
- fclose(fp);
-
- return 0;
-}
-
-/*
- * Placeholder for now.
- */
-
-int do_decompile( int codepage, char *input_file, char *output_file)
-{
- uint32 size = 0;
- struct stat st;
- char header_buf[CODEPAGE_HEADER_SIZE];
- char *buf = NULL;
- FILE *fp = NULL;
- int num_lines = 0;
- int i = 0;
-
- /* Get the size of the input file. Read the entire thing into memory. */
- if(stat((char *)input_file, &st)!= 0)
- {
- fprintf(stderr, "%s: failed to get the file size for file %s. Error was %s\n",
- prog_name, input_file, strerror(errno));
- exit(1);
- }
-
- size = (uint32)st.st_size;
-
- if( size < CODEPAGE_HEADER_SIZE || size > (CODEPAGE_HEADER_SIZE + 256))
- {
- fprintf(stderr, "%s: file %s is an incorrect size for a \
-code page file.\n", prog_name, input_file);
- exit(1);
- }
-
- /* Read the first 8 bytes of the codepage file - check
- the version number and code page number. All the data
- is held in little endian format.
- */
-
- if((fp = fopen( input_file, "r")) == NULL)
- {
- fprintf(stderr, "%s: cannot open file %s. Error was %s\n",
- prog_name, input_file, strerror(errno));
- exit(1);
- }
-
- if(fread( header_buf, 1, CODEPAGE_HEADER_SIZE, fp)!=CODEPAGE_HEADER_SIZE)
- {
- fprintf(stderr, "%s: cannot read header from file %s. Error was %s\n",
- prog_name, input_file, strerror(errno));
- exit(1);
- }
-
- /* Check the version value */
- if(SVAL(header_buf,CODEPAGE_VERSION_OFFSET) != CODEPAGE_FILE_VERSION_ID)
- {
- fprintf(stderr, "%s: filename %s has incorrect version id. \
-Needed %hu, got %hu.\n",
- prog_name, input_file, (uint16)CODEPAGE_FILE_VERSION_ID,
- SVAL(header_buf,CODEPAGE_VERSION_OFFSET));
- exit(1);
- }
-
- /* Check the codepage matches */
- if(SVAL(header_buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET) != (uint16)codepage)
- {
- fprintf(stderr, "%s: filename %s has incorrect codepage. \
-Needed %hu, got %hu.\n",
- prog_name, input_file, (uint16)codepage,
- SVAL(header_buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET));
- exit(1);
- }
-
- /* Check the length is correct. */
- if(IVAL(header_buf,CODEPAGE_LENGTH_OFFSET) !=
- (unsigned int)(size - CODEPAGE_HEADER_SIZE))
- {
- fprintf(stderr, "%s: filename %s has incorrect size headers. \
-Needed %u, got %u.\n", prog_name, input_file, size - CODEPAGE_HEADER_SIZE,
- IVAL(header_buf,CODEPAGE_LENGTH_OFFSET));
- exit(1);
- }
-
- size -= CODEPAGE_HEADER_SIZE; /* Remove header */
-
- /* Make sure the size is a multiple of 4. */
- if((size % 4 ) != 0)
- {
- fprintf(stderr, "%s: filename %s has a codepage size not a \
-multiple of 4.\n", prog_name, input_file);
- exit(1);
- }
-
- /* Allocate space for the code page file and read it all in. */
- if((buf = (char *)malloc( size )) == NULL)
- {
- fprintf (stderr, "%s: malloc fail for size %d.\n",
- prog_name, size );
- exit(1);
- }
-
- if(fread( buf, 1, size, fp)!=size)
- {
- fprintf(stderr, "%s: read fail on file %s. Error was %s.\n",
- prog_name, input_file, strerror(errno));
- exit(1);
- }
-
- fclose(fp);
-
- /* Now dump the codepage into an ascii file. */
- if((fp = fopen(output_file, "w")) == NULL)
- {
- fprintf(stderr, "%s: cannot open file %s. Error was %s\n",
- prog_name, output_file, strerror(errno));
- exit(1);
- }
-
- fprintf(fp, "#\n# Codepage definition file for IBM Code Page %d.\n#\n",
- codepage);
- fprintf(fp, "# This file was automatically generated.\n#\n");
- fprintf(fp, "# defines lower->upper mapping.\n");
- fprintf(fp, "#\n#The columns are :\n# lower\tupper\tu-t-l\tl-t-u\n#\n");
-
- num_lines = size / 4;
- for( i = 0; i < num_lines; i++)
- {
- fprintf(fp, "0x%02X\t0x%02X\t%s\t%s\n", CVAL(buf, (i*4)), CVAL(buf, (i*4)+1),
- CVAL(buf, (i*4)+2) ? "True" : "False",
- CVAL(buf, (i*4)+3) ? "True" : "False");
- }
- fclose(fp);
- return 0;
-}
-
-int main(int argc, char **argv)
-{
- int codepage = 0;
- char *input_file = NULL;
- char *output_file = NULL;
- BOOL compile = False;
-
- prog_name = argv[0];
-
- if(argc != 5)
- codepage_usage(prog_name);
-
- if(argv[1][0] != 'c' && argv[1][0] != 'C' && argv[1][0] != 'd' &&
- argv[1][0] != 'D')
- codepage_usage(prog_name);
-
- input_file = argv[3];
- output_file = argv[4];
-
- /* Are we compiling or decompiling. */
- if(argv[1][0] == 'c' || argv[1][0] == 'C')
- compile = True;
-
- /* Convert the second argument into a client codepage value. */
- if((codepage = atoi(argv[2])) == 0)
- {
- fprintf(stderr, "%s: %s is not a valid codepage.\n", prog_name, argv[2]);
- exit(1);
- }
-
- if(compile)
- return do_compile( codepage, input_file, output_file);
- else
- return do_decompile( codepage, input_file, output_file);
-}
diff --git a/source/utils/nmblookup.c b/source/utils/nmblookup.c
deleted file mode 100644
index 63ca156449f..00000000000
--- a/source/utils/nmblookup.c
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT client - used to lookup netbios names
- Copyright (C) Andrew Tridgell 1994-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.
-
-*/
-
-#ifdef SYSLOG
-#undef SYSLOG
-#endif
-
-#include "includes.h"
-
-extern int DEBUGLEVEL;
-
-extern pstring scope;
-
-extern pstring myhostname;
-extern struct in_addr ipzero;
-
-int ServerFD= -1;
-
-int RootPort = 0;
-
-/****************************************************************************
- open the socket communication
- **************************************************************************/
-static BOOL open_sockets(void)
-{
- struct hostent *hp;
-
- /* get host info */
- if ((hp = Get_Hostbyname(myhostname)) == 0)
- {
- DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",myhostname));
- return False;
- }
-
- ServerFD = open_socket_in( SOCK_DGRAM,
- (RootPort ? 137 :0),
- 3,
- interpret_addr(lp_socket_address()) );
-
- if (ServerFD == -1)
- return(False);
-
- set_socket_options(ServerFD,"SO_BROADCAST");
-
- DEBUG(3, ("Socket opened.\n"));
- return True;
-}
-
-
-/****************************************************************************
- initialise connect, service and file structs
-****************************************************************************/
-static BOOL init_structs(void )
-{
- if (!get_myname(myhostname,NULL))
- return(False);
-
- return True;
-}
-
-/****************************************************************************
-usage on the program
-****************************************************************************/
-static void usage(void)
-{
- printf("Usage: nmblookup [-M] [-B bcast address] [-d debuglevel] name\n");
- printf("Version %s\n",VERSION);
- printf("\t-d debuglevel set the debuglevel\n");
- printf("\t-B broadcast address the address to use for broadcasts\n");
- printf("\t-M searches for a master browser\n");
- printf("\t-S lookup node status as well\n");
- printf("\t-r Use root port 137 (Win95 only replies to this)\n");
- printf("\t-A Do a node status on <name> as an IP Address\n");
- printf("\n");
-}
-
-
-/****************************************************************************
- main program
-****************************************************************************/
-int main(int argc,char *argv[])
-{
- int opt;
- unsigned int lookup_type = 0x0;
- pstring lookup;
- extern int optind;
- extern char *optarg;
- BOOL find_master=False;
- BOOL find_status=False;
- int i;
- static pstring servicesf = CONFIGFILE;
- struct in_addr bcast_addr;
- BOOL got_bcast = False;
- BOOL lookup_by_ip = False;
-
- DEBUGLEVEL = 1;
- *lookup = 0;
-
- TimeInit();
-
- setup_logging(argv[0],True);
-
- charset_initialise();
-
- while ((opt = getopt(argc, argv, "d:B:i:s:SMrhA")) != EOF)
- switch (opt)
- {
- case 'B':
- iface_set_default(NULL,optarg,NULL);
- bcast_addr = *interpret_addr2(optarg);
- got_bcast = True;
- break;
- case 'i':
- fstrcpy(scope,optarg);
- strupper(scope);
- break;
- case 'M':
- find_master = True;
- break;
- case 'S':
- find_status = True;
- break;
- case 'd':
- DEBUGLEVEL = atoi(optarg);
- break;
- case 's':
- pstrcpy(servicesf, optarg);
- break;
- case 'r':
- RootPort = -1;
- break;
- case 'h':
- usage();
- exit(0);
- break;
- case 'A':
- lookup_by_ip = True;
- break;
- default:
- usage();
- exit(1);
- }
-
- if (argc < 2) {
- usage();
- exit(1);
- }
-
- if (!lp_load(servicesf,True)) {
- fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
- }
-
- load_interfaces();
- init_structs();
- if (!open_sockets()) return(1);
-
- if (!got_bcast)
- bcast_addr = *iface_bcast(ipzero);
-
- DEBUG(1,("Sending queries to %s\n",inet_ntoa(bcast_addr)));
-
-
- for (i=optind;i<argc;i++)
- {
- BOOL bcast = True;
- int retries = 2;
- char *p;
- struct in_addr ip;
-
- fstrcpy(lookup,argv[i]);
-
- if(lookup_by_ip)
- {
- strcpy(lookup,"*");
- ip = *interpret_addr2(argv[i]);
- printf("Looking up status of %s\n",inet_ntoa(ip));
- name_status(ServerFD,lookup,lookup_type,True,ip,NULL,NULL,NULL);
- printf("\n");
- continue;
- }
-
- if (find_master) {
- if (*lookup == '-') {
- strcpy(lookup,"\01\02__MSBROWSE__\02");
- lookup_type = 1;
- } else {
- lookup_type = 0x1d;
- }
- }
-
- p = strchr(lookup,'#');
-
- if (p) {
- *p = 0;
- sscanf(p+1,"%x",&lookup_type);
- bcast = False;
- retries = 1;
- }
-
- if (name_query(ServerFD,lookup,lookup_type,bcast,True,
- bcast_addr,&ip,NULL))
- {
- printf("%s %s\n",inet_ntoa(ip),lookup);
-
- /* We can only do find_status if the ip address returned
- was valid - ie. name_query returned true.
- */
- if (find_status)
- {
- printf("Looking up status of %s\n",inet_ntoa(ip));
- name_status(ServerFD,lookup,lookup_type,True,ip,NULL,NULL,NULL);
- printf("\n");
- }
- }
- else
- {
- printf("name_query failed to find name %s\n", lookup);
- }
- }
-
- return(0);
-}
diff --git a/source/utils/smbpasswd.c b/source/utils/smbpasswd.c
deleted file mode 100644
index d20ff42c0e8..00000000000
--- a/source/utils/smbpasswd.c
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * Unix SMB/Netbios implementation. Version 1.9. smbpasswd module. Copyright
- * (C) Jeremy Allison 1995-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.
- */
-
-#include "includes.h"
-
-/* Static buffers we will return. */
-static struct smb_passwd pw_buf;
-static pstring user_name;
-static unsigned char smbpwd[16];
-static unsigned char smbntpwd[16];
-
-static int gethexpwd(char *p, char *pwd)
-{
- int i;
- unsigned char lonybble, hinybble;
- char *hexchars = "0123456789ABCDEF";
- char *p1, *p2;
- for (i = 0; i < 32; i += 2) {
- hinybble = toupper(p[i]);
- lonybble = toupper(p[i + 1]);
-
- p1 = strchr(hexchars, hinybble);
- p2 = strchr(hexchars, lonybble);
- if (!p1 || !p2)
- return (False);
-
- hinybble = PTR_DIFF(p1, hexchars);
- lonybble = PTR_DIFF(p2, hexchars);
-
- pwd[i / 2] = (hinybble << 4) | lonybble;
- }
- return (True);
-}
-
-struct smb_passwd *
-_my_get_smbpwnam(FILE * fp, char *name, BOOL * valid_old_pwd,
- BOOL *got_valid_nt_entry, long *pwd_seekpos)
-{
- char linebuf[256];
- unsigned char c;
- unsigned char *p;
- long uidval;
- long linebuf_len;
-
- /*
- * Scan the file, a line at a time and check if the name matches.
- */
- while (!feof(fp)) {
- linebuf[0] = '\0';
- *pwd_seekpos = ftell(fp);
-
- fgets(linebuf, 256, fp);
- if (ferror(fp))
- return NULL;
-
- /*
- * Check if the string is terminated with a newline - if not
- * then we must keep reading and discard until we get one.
- */
- linebuf_len = strlen(linebuf);
- if (linebuf[linebuf_len - 1] != '\n') {
- c = '\0';
- while (!ferror(fp) && !feof(fp)) {
- c = fgetc(fp);
- if (c == '\n')
- break;
- }
- } else
- linebuf[linebuf_len - 1] = '\0';
-
- if ((linebuf[0] == 0) && feof(fp))
- break;
- /*
- * The line we have should be of the form :-
- *
- * username:uid:[32hex bytes]:....other flags presently
- * ignored....
- *
- * or,
- *
- * username:uid:[32hex bytes]:[32hex bytes]:....ignored....
- *
- * if Windows NT compatible passwords are also present.
- */
-
- if (linebuf[0] == '#' || linebuf[0] == '\0')
- continue;
- p = (unsigned char *) strchr(linebuf, ':');
- if (p == NULL)
- continue;
- /*
- * As 256 is shorter than a pstring we don't need to check
- * length here - if this ever changes....
- */
- strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
- user_name[PTR_DIFF(p, linebuf)] = '\0';
- if (!strequal(user_name, name))
- continue;
-
- /* User name matches - get uid and password */
- p++; /* Go past ':' */
- if (!isdigit(*p))
- return (False);
-
- uidval = atoi((char *) p);
- while (*p && isdigit(*p))
- p++;
-
- if (*p != ':')
- return (False);
-
- /*
- * Now get the password value - this should be 32 hex digits
- * which are the ascii representations of a 16 byte string.
- * Get two at a time and put them into the password.
- */
- p++;
- *pwd_seekpos += PTR_DIFF(p, linebuf); /* Save exact position
- * of passwd in file -
- * this is used by
- * smbpasswd.c */
- if (*p == '*' || *p == 'X') {
- /* Password deliberately invalid - end here. */
- *valid_old_pwd = False;
- *got_valid_nt_entry = False;
- pw_buf.smb_nt_passwd = NULL; /* No NT password (yet)*/
-
- /* Now check if the NT compatible password is
- available. */
- p += 33; /* Move to the first character of the line after
- the lanman password. */
- if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
- /* NT Entry was valid - even if 'X' or '*', can be overwritten */
- *got_valid_nt_entry = True;
- if (*p != '*' && *p != 'X') {
- if (gethexpwd((char *)p,(char *)smbntpwd))
- pw_buf.smb_nt_passwd = smbntpwd;
- }
- }
- pw_buf.smb_name = user_name;
- pw_buf.smb_userid = uidval;
- pw_buf.smb_passwd = NULL; /* No password */
- return (&pw_buf);
- }
- if (linebuf_len < (PTR_DIFF(p, linebuf) + 33))
- return (False);
-
- if (p[32] != ':')
- return (False);
-
- if (!strncasecmp((char *)p, "NO PASSWORD", 11)) {
- pw_buf.smb_passwd = NULL; /* No password */
- } else {
- if(!gethexpwd((char *)p,(char *)smbpwd))
- return False;
- pw_buf.smb_passwd = smbpwd;
- }
-
- pw_buf.smb_name = user_name;
- pw_buf.smb_userid = uidval;
- pw_buf.smb_nt_passwd = NULL;
- *got_valid_nt_entry = False;
- *valid_old_pwd = True;
-
- /* Now check if the NT compatible password is
- available. */
- p += 33; /* Move to the first character of the line after
- the lanman password. */
- if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
- /* NT Entry was valid - even if 'X' or '*', can be overwritten */
- *got_valid_nt_entry = True;
- if (*p != '*' && *p != 'X') {
- if (gethexpwd((char *)p,(char *)smbntpwd))
- pw_buf.smb_nt_passwd = smbntpwd;
- }
- }
- return &pw_buf;
- }
- return NULL;
-}
-
-/*
- * Print command usage on stderr and die.
- */
-static void usage(char *name)
-{
- fprintf(stderr, "Usage is : %s [-add] [username] [password]\n", name);
- exit(1);
-}
-
- int main(int argc, char **argv)
-{
- int real_uid;
- struct passwd *pwd;
- fstring old_passwd;
- uchar old_p16[16];
- uchar old_nt_p16[16];
- fstring new_passwd;
- uchar new_p16[16];
- uchar new_nt_p16[16];
- char *p;
- struct smb_passwd *smb_pwent;
- FILE *fp;
- BOOL valid_old_pwd = False;
- BOOL got_valid_nt_entry = False;
- BOOL add_user = False;
- int add_pass = 0;
- long seekpos;
- int pwfd;
- char ascii_p16[66];
- char c;
- int ret, i, err, writelen;
- int lockfd = -1;
- char *pfile = SMB_PASSWD_FILE;
- char readbuf[16 * 1024];
-
- TimeInit();
-
- setup_logging(argv[0],True);
-
- charset_initialise();
-
-#ifndef DEBUG_PASSWORD
- /* Check the effective uid */
- if (geteuid() != 0) {
- fprintf(stderr, "%s: Must be setuid root.\n", argv[0]);
- exit(1);
- }
-#endif
-
- /* Get the real uid */
- real_uid = getuid();
-
- /* Deal with usage problems */
- if (real_uid == 0)
- {
- /* As root we can change anothers password and add a user. */
- if (argc > 4 )
- usage(argv[0]);
- }
- else if (argc == 2 || argc > 3)
- {
- fprintf(stderr, "%s: Only root can set anothers password.\n", argv[0]);
- usage(argv[0]);
- }
-
- if (real_uid == 0 && (argc > 1))
- {
- /* We are root - check if we should add the user */
- if ((argv[1][0] == '-') && (argv[1][1] == 'a'))
- add_user = True;
-
- if(add_user && (argc <= 2 || argc > 4))
- usage(argv[0]);
-
- /* root can specify password on command-line */
- if (argc == (add_user ? 4 : 3))
- {
- /* -a argument (add_user): new password is 3rd argument. */
- /* no -a argument (add_user): new password is 2nd argument */
-
- add_pass = add_user ? 3 : 2;
- }
-
- /* If we are root we can change another's password. */
- strncpy(user_name, add_user ? argv[2] : argv[1], sizeof(user_name) - 1);
- user_name[sizeof(user_name) - 1] = '\0';
-
- pwd = getpwnam(user_name);
- }
- else
- {
- /* non-root can specify old pass / new pass on command-line */
- if (argc == 3)
- {
- /* non-root specifies new password as 2nd argument */
- add_pass = 2;
- }
-
- pwd = getpwuid(real_uid);
- }
-
- if (pwd == 0) {
- fprintf(stderr, "%s: Unable to get UNIX password entry for user.\n", argv[0]);
- exit(1);
- }
-
- /* If we are root we don't ask for the old password. */
- old_passwd[0] = '\0';
- if (real_uid != 0)
- {
- if (add_pass)
- {
- /* old password, as non-root, is 1st argument */
- strncpy(old_passwd, argv[1], sizeof(fstring));
- }
- else
- {
- p = getpass("Old SMB password:");
- strncpy(old_passwd, p, sizeof(fstring));
- }
- old_passwd[sizeof(fstring)-1] = '\0';
- }
-
- if (add_pass)
- {
- /* new password is specified on the command line */
- strncpy(new_passwd, argv[add_user ? 3 : 2], sizeof(new_passwd) - 1);
- new_passwd[sizeof(new_passwd) - 1] = '\0';
- }
- else
- {
- new_passwd[0] = '\0';
-
- p = getpass("New SMB password:");
-
- strncpy(new_passwd, p, sizeof(fstring));
- new_passwd[sizeof(fstring)-1] = '\0';
-
- p = getpass("Retype new SMB password:");
-
- if (strncmp(p, new_passwd, sizeof(fstring)-1))
- {
- fprintf(stderr, "%s: Mismatch - password unchanged.\n", argv[0]);
- exit(1);
- }
- }
-
- if (new_passwd[0] == '\0')
- {
- printf("Password not set\n");
- exit(0);
- }
-
- /* Calculate the MD4 hash (NT compatible) of the old and new passwords */
- memset(old_nt_p16, '\0', 16);
- E_md4hash((uchar *)old_passwd, old_nt_p16);
-
- memset(new_nt_p16, '\0', 16);
- E_md4hash((uchar *) new_passwd, new_nt_p16);
-
- /* Mangle the passwords into Lanman format */
- old_passwd[14] = '\0';
- strupper(old_passwd);
- new_passwd[14] = '\0';
- strupper(new_passwd);
-
- /*
- * Calculate the SMB (lanman) hash functions of both old and new passwords.
- */
-
- memset(old_p16, '\0', 16);
- E_P16((uchar *) old_passwd, old_p16);
-
- memset(new_p16, '\0', 16);
- E_P16((uchar *) new_passwd, new_p16);
-
- /*
- * Open the smbpaswd file XXXX - we need to parse smb.conf to get the
- * filename
- */
- fp = fopen(pfile, "r+");
- if (!fp && errno == ENOENT) {
- fp = fopen(pfile, "w");
- if (fp) {
- fprintf(fp, "# Samba SMB password file\n");
- fclose(fp);
- fp = fopen(pfile, "r+");
- }
- }
- if (!fp) {
- err = errno;
- fprintf(stderr, "%s: Failed to open password file %s.\n",
- argv[0], pfile);
- errno = err;
- perror(argv[0]);
- exit(err);
- }
-
- /* Set read buffer to 16k for effiecient reads */
- setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf));
-
- /* make sure it is only rw by the owner */
- chmod(pfile, 0600);
-
- /* Lock the smbpasswd file for write. */
- if ((lockfd = pw_file_lock(pfile, F_WRLCK, 5)) < 0) {
- err = errno;
- fprintf(stderr, "%s: Failed to lock password file %s.\n",
- argv[0], pfile);
- fclose(fp);
- errno = err;
- perror(argv[0]);
- exit(err);
- }
- /* Get the smb passwd entry for this user */
- smb_pwent = _my_get_smbpwnam(fp, pwd->pw_name, &valid_old_pwd,
- &got_valid_nt_entry, &seekpos);
- if (smb_pwent == NULL) {
- if(add_user == False) {
- fprintf(stderr, "%s: Failed to find entry for user %s in file %s.\n",
- argv[0], pwd->pw_name, pfile);
- fclose(fp);
- pw_file_unlock(lockfd);
- exit(1);
- }
-
- /* Create a new smb passwd entry and set it to the given password. */
- {
- int fd;
- int new_entry_length;
- char *new_entry;
- long offpos;
-
- /* The add user write needs to be atomic - so get the fd from
- the fp and do a raw write() call.
- */
- fd = fileno(fp);
-
- if((offpos = lseek(fd, 0, SEEK_END)) == -1) {
- fprintf(stderr, "%s: Failed to add entry for user %s to file %s. \
-Error was %s\n", argv[0], pwd->pw_name, pfile, strerror(errno));
- fclose(fp);
- pw_file_unlock(lockfd);
- exit(1);
- }
-
- new_entry_length = strlen(pwd->pw_name) + 1 + 15 + 1 +
- 32 + 1 + 32 + 1 + strlen(pwd->pw_gecos) +
- 1 + strlen(pwd->pw_dir) + 1 +
- strlen(pwd->pw_shell) + 1;
- if((new_entry = (char *)malloc( new_entry_length )) == 0) {
- fprintf(stderr, "%s: Failed to add entry for user %s to file %s. \
-Error was %s\n", argv[0], pwd->pw_name, pfile, strerror(errno));
- fclose(fp);
- pw_file_unlock(lockfd);
- exit(1);
- }
-
- sprintf(new_entry, "%s:%u:", pwd->pw_name, pwd->pw_uid);
- p = &new_entry[strlen(new_entry)];
- for( i = 0; i < 16; i++)
- sprintf(&p[i*2], "%02X", new_p16[i]);
- p += 32;
- *p++ = ':';
- for( i = 0; i < 16; i++)
- sprintf(&p[i*2], "%02X", new_nt_p16[i]);
- p += 32;
- *p++ = ':';
- sprintf(p, "%s:%s:%s\n", pwd->pw_gecos,
- pwd->pw_dir, pwd->pw_shell);
- if(write(fd, new_entry, strlen(new_entry)) != strlen(new_entry)) {
- fprintf(stderr, "%s: Failed to add entry for user %s to file %s. \
-Error was %s\n", argv[0], pwd->pw_name, pfile, strerror(errno));
- /* Remove the entry we just wrote. */
- if(ftruncate(fd, offpos) == -1) {
- fprintf(stderr, "%s: ERROR failed to ftruncate file %s. \
-Error was %s. Password file may be corrupt ! Please examine by hand !\n",
- argv[0], pwd->pw_name, strerror(errno));
- }
- fclose(fp);
- pw_file_unlock(lockfd);
- exit(1);
- }
-
- fclose(fp);
- pw_file_unlock(lockfd);
- exit(0);
- }
- } else {
- /* the entry already existed */
- add_user = False;
- }
-
- /* If we are root or the password is 'NO PASSWORD' then
- we don't need to check the old password. */
- if (real_uid != 0) {
- if (valid_old_pwd == False) {
- fprintf(stderr, "%s: User %s has no old SMB password.\n", argv[0], pwd->pw_name);
- }
- /* Check the old Lanman password - NULL means 'NO PASSWORD' */
- if (smb_pwent->smb_passwd != NULL) {
- if (memcmp(old_p16, smb_pwent->smb_passwd, 16)) {
- fprintf(stderr, "%s: Couldn't change password.\n", argv[0]);
- fclose(fp);
- pw_file_unlock(lockfd);
- exit(1);
- }
- }
- /* Check the NT password if it exists */
- if (smb_pwent->smb_nt_passwd != NULL) {
- if (memcmp(old_nt_p16, smb_pwent->smb_nt_passwd, 16)) {
- fprintf(stderr, "%s: Couldn't change password.\n", argv[0]);
- fclose(fp);
- pw_file_unlock(lockfd);
- exit(1);
- }
- }
- }
- /*
- * If we get here either we were root or the old password checked out
- * ok.
- */
- /* Create the 32 byte representation of the new p16 */
- for (i = 0; i < 16; i++) {
- sprintf(&ascii_p16[i * 2], "%02X", (uchar) new_p16[i]);
- }
- if(got_valid_nt_entry) {
- /* Add on the NT md4 hash */
- ascii_p16[32] = ':';
- for (i = 0; i < 16; i++) {
- sprintf(&ascii_p16[(i * 2)+33], "%02X", (uchar) new_nt_p16[i]);
- }
- }
- /*
- * Do an atomic write into the file at the position defined by
- * seekpos.
- */
- pwfd = fileno(fp);
- ret = lseek(pwfd, seekpos - 1, SEEK_SET);
- if (ret != seekpos - 1) {
- err = errno;
- fprintf(stderr, "%s: seek fail on file %s.\n",
- argv[0], pfile);
- fclose(fp);
- errno = err;
- perror(argv[0]);
- pw_file_unlock(lockfd);
- exit(1);
- }
- /* Sanity check - ensure the character is a ':' */
- if (read(pwfd, &c, 1) != 1) {
- err = errno;
- fprintf(stderr, "%s: read fail on file %s.\n",
- argv[0], pfile);
- fclose(fp);
- errno = err;
- perror(argv[0]);
- pw_file_unlock(lockfd);
- exit(1);
- }
- if (c != ':') {
- fprintf(stderr, "%s: sanity check on passwd file %s failed.\n",
- argv[0], pfile);
- fclose(fp);
- pw_file_unlock(lockfd);
- exit(1);
- }
- writelen = (got_valid_nt_entry) ? 65 : 32;
- if (write(pwfd, ascii_p16, writelen) != writelen) {
- err = errno;
- fprintf(stderr, "%s: write fail in file %s.\n",
- argv[0], pfile);
- fclose(fp);
- errno = err;
- perror(argv[0]);
- pw_file_unlock(lockfd);
- exit(err);
- }
- fclose(fp);
- pw_file_unlock(lockfd);
- printf("Password changed\n");
- return 0;
-}
-
diff --git a/source/utils/status.c b/source/utils/status.c
deleted file mode 100644
index 4143244ab4d..00000000000
--- a/source/utils/status.c
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- status reporting
- Copyright (C) Andrew Tridgell 1994-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.
-
- Revision History:
-
- 12 aug 96: Erik.Devriendt@te6.siemens.be
- added support for shared memory implementation of share mode locking
-*/
-
-/*
- * This program reports current SMB connections
- */
-
-#ifdef SYSLOG
-#undef SYSLOG
-#endif
-
-#include "includes.h"
-
-struct connect_record crec;
-
-struct session_record{
- int pid;
- int uid;
- char machine[31];
- time_t start;
- struct session_record *next;
-} *srecs;
-
-extern int DEBUGLEVEL;
-extern FILE *dbf;
-extern pstring myhostname;
-
-static pstring Ucrit_username = ""; /* added by OH */
-int Ucrit_pid[100]; /* Ugly !!! */ /* added by OH */
-int Ucrit_MaxPid=0; /* added by OH */
-unsigned int Ucrit_IsActive = 0; /* added by OH */
-
-#ifndef FAST_SHARE_MODES
-static char *read_share_file(int fd, char *fname, char *progname)
-{
- struct stat sb;
- char *buf;
- int size;
-
- if(fstat(fd, &sb) != 0)
- {
- printf("%s: ERROR: read_share_file: Failed to do stat on share file %s (%s)\n",
- progname, fname, strerror(errno));
- return 0;
- }
-
- if(sb.st_size == 0)
- {
- return 0;
- }
-
- /* Allocate space for the file */
- if((buf = (char *)malloc(sb.st_size)) == NULL)
- {
- printf("%s: read_share_file: malloc for file size %d fail !\n",
- progname, (int)sb.st_size);
- return 0;
- }
-
- if(lseek(fd, 0, SEEK_SET) != 0)
- {
- printf("%s: ERROR: read_share_file: Failed to reset position to 0 \
-for share file %s (%s)\n", progname, fname, strerror(errno));
- if(buf)
- free(buf);
- return 0;
- }
-
- if (read(fd,buf,sb.st_size) != sb.st_size)
- {
- printf("%s: ERROR: read_share_file: Failed to read share file %s (%s)\n",
- progname, fname, strerror(errno));
- if(buf)
- free(buf);
- return 0;
- }
-
- if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION) {
- printf("%s: ERROR: read_share_file: share file %s has incorrect \
-locking version (was %d, should be %d).\n",fname,
- progname, IVAL(buf,SMF_VERSION_OFFSET), LOCKING_VERSION);
- if(buf)
- free(buf);
- return 0;
- }
-
- /* Sanity check for file contents */
- size = sb.st_size;
- size -= SMF_HEADER_LENGTH; /* Remove the header */
-
- /* Remove the filename component. */
- size -= SVAL(buf, SMF_FILENAME_LEN_OFFSET);
-
- /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */
- if((size % SMF_ENTRY_LENGTH) != 0)
- {
- printf("%s: ERROR: read_share_file: share file %s is an incorrect length.\n",
- progname, fname);
- if(buf)
- free(buf);
- return 0;
- }
-
- return buf;
-}
-#endif /* FAST_SHARE_MODES */
-
- int main(int argc, char *argv[])
-{
- FILE *f;
- pstring fname;
- int uid, c;
- static pstring servicesf = CONFIGFILE;
- extern char *optarg;
- int verbose = 0, brief =0;
- BOOL firstopen=True;
- BOOL processes_only=False;
- int last_pid=0;
-#ifdef FAST_SHARE_MODES
- pstring shmem_file_name;
- share_mode_record *file_scanner_p;
- smb_shm_offset_t *mode_array;
- int bytes_free, bytes_used, bytes_overhead, bytes_total;
-#else /* FAST_SHARE_MODES */
- void *dir;
- char *s;
-#endif /* FAST_SHARE_MODES */
- int oplock_type;
- int i;
- struct session_record *ptr;
-
-
- TimeInit();
- setup_logging(argv[0],True);
-
- charset_initialise();
-
- DEBUGLEVEL = 0;
- dbf = fopen("/dev/null","w");
-
- if (getuid() != geteuid()) {
- printf("smbstatus should not be run setuid\n");
- return(1);
- }
-
- while ((c = getopt(argc, argv, "pds:u:b")) != EOF) {
- switch (c) {
- case 'b':
- brief = 1;
- break;
- case 'd':
- verbose = 1;
- break;
- case 'p':
- processes_only = 1;
- break;
- case 's':
- strcpy(servicesf, optarg);
- break;
- case 'u': /* added by OH */
- Ucrit_addUsername(optarg); /* added by OH */
- break;
- default:
- fprintf(stderr, "Usage: %s [-d] [-p] [-s configfile] [-u username]\n", *argv); /* changed by OH */
- return (-1);
- }
- }
-
- get_myname(myhostname, NULL);
-
- if (!lp_load(servicesf,False)) {
- fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
- return (-1);
- }
-
- if (verbose) {
- printf("using configfile = %s\n", servicesf);
- printf("lockdir = %s\n", *lp_lockdir() ? lp_lockdir() : "NULL");
- }
-
- strcpy(fname,lp_lockdir());
- standard_sub_basic(fname);
- trim_string(fname,"","/");
- strcat(fname,"/STATUS..LCK");
-
- f = fopen(fname,"r");
- if (!f) {
- printf("Couldn't open status file %s\n",fname);
- if (!lp_status(-1))
- printf("You need to have status=yes in your smb config file\n");
- return(0);
- }
- else if (verbose) {
- printf("Opened status file %s\n", fname);
- }
-
- uid = getuid();
-
- if (!processes_only) {
- printf("\nSamba version %s\n",VERSION);
-
- if (brief)
- {
- printf("PID Username Machine Time logged in\n");
- printf("-------------------------------------------------------------------\n");
- }
- else
- {
- printf("Service uid gid pid machine\n");
- printf("----------------------------------------------\n");
- }
- }
-
- while (!feof(f))
- {
- if (fread(&crec,sizeof(crec),1,f) != 1)
- break;
- if ( crec.magic == 0x280267 && process_exists(crec.pid)
- && Ucrit_checkUsername(uidtoname(crec.uid)) /* added by OH */
- )
- {
- if (brief)
- {
- ptr=srecs;
- while (ptr!=NULL)
- {
- if ((ptr->pid==crec.pid)&&(strncmp(ptr->machine,crec.machine,30)==0))
- {
- if (ptr->start > crec.start)
- ptr->start=crec.start;
- break;
- }
- ptr=ptr->next;
- }
- if (ptr==NULL)
- {
- ptr=(struct session_record *) malloc(sizeof(struct session_record));
- ptr->uid=crec.uid;
- ptr->pid=crec.pid;
- ptr->start=crec.start;
- strncpy(ptr->machine,crec.machine,30);
- ptr->machine[30]='\0';
- ptr->next=srecs;
- srecs=ptr;
- }
- }
- else
- {
- Ucrit_addPid(crec.pid); /* added by OH */
- if (processes_only) {
- if (last_pid != crec.pid)
- printf("%d\n",crec.pid);
- last_pid = crec.pid; /* XXXX we can still get repeats, have to
- add a sort at some time */
- }
- else
- printf("%-10.10s %-8s %-8s %5d %-8s (%s) %s",
- crec.name,uidtoname(crec.uid),gidtoname(crec.gid),crec.pid,
- crec.machine,crec.addr,
- asctime(LocalTime(&crec.start)));
- }
- }
- }
- fclose(f);
-
- if (processes_only) exit(0);
-
- if (brief)
- {
- ptr=srecs;
- while (ptr!=NULL)
- {
- printf("%-8d%-10.10s%-30.30s%s",ptr->pid,uidtoname(ptr->uid),ptr->machine,asctime(LocalTime(&(ptr->start))));
- ptr=ptr->next;
- }
- printf("\n");
- exit(0);
- }
-
- printf("\n");
-
-#ifdef FAST_SHARE_MODES
- /*******************************************************************
- initialize the shared memory for share_mode management
- ******************************************************************/
-
- strcpy(shmem_file_name,lp_lockdir());
- trim_string(shmem_file_name,"","/");
- if (!*shmem_file_name) exit(-1);
- strcat(shmem_file_name, "/SHARE_MEM_FILE");
- if(!smb_shm_open(shmem_file_name, lp_shmem_size())) exit(-1);
-
- mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off());
- if(mode_array == NULL)
- {
- printf("%s: base of shared memory hash array == 0! Exiting.\n", argv[0]);
- smb_shm_close();
- exit(-1);
- }
-
- for( i = 0; i < lp_shmem_hash_size(); i++)
- {
- smb_shm_lock_hash_entry(i);
- if(mode_array[i] == NULL_OFFSET)
- {
- smb_shm_unlock_hash_entry(i);
- continue;
- }
- file_scanner_p = (share_mode_record *)smb_shm_offset2addr(mode_array[i]);
- while((file_scanner_p != 0) && (file_scanner_p->num_share_mode_entries != 0))
- {
- share_mode_entry *entry_scanner_p =
- (share_mode_entry *)smb_shm_offset2addr(
- file_scanner_p->share_mode_entries);
-
- while(entry_scanner_p != 0)
- {
- struct timeval t;
- int pid = entry_scanner_p->pid;
- int mode = entry_scanner_p->share_mode;
-
- t.tv_sec = entry_scanner_p->time.tv_sec;
- t.tv_usec = entry_scanner_p->time.tv_usec;
- strcpy(fname, file_scanner_p->file_name);
- oplock_type = entry_scanner_p->op_type;
-
-#else /* FAST_SHARE_MODES */
-
- /* For slow share modes go through all the files in
- the share mode directory and read the entries in
- each.
- */
-
- dir = opendir(lp_lockdir());
- if (!dir)
- {
- printf("%s: Unable to open lock directory %s.\n", argv[0], lp_lockdir());
- return(0);
- }
- while ((s=readdirname(dir))) {
- char *buf;
- char *base;
- int fd;
- pstring lname;
- uint32 dev,inode;
-
- if (sscanf(s,"share.%u.%u",&dev,&inode)!=2) continue;
-
- strcpy(lname,lp_lockdir());
- trim_string(lname,NULL,"/");
- strcat(lname,"/");
- strcat(lname,s);
-
- fd = open(lname,O_RDWR,0);
- if (fd < 0)
- {
- printf("%s: Unable to open share file %s.\n", argv[0], lname);
- continue;
- }
-
- /* Lock the share mode file while we read it. */
- if(fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False)
- {
- printf("%s: Unable to lock open share file %s.\n", argv[0], lname);
- close(fd);
- continue;
- }
-
- if(( buf = read_share_file( fd, lname, argv[0] )) == NULL)
- {
- close(fd);
- continue;
- }
- strcpy( fname, &buf[10]);
- close(fd);
-
- base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
- for( i = 0; i < IVAL(buf, SMF_NUM_ENTRIES_OFFSET); i++)
- {
- char *p = base + (i*SMF_ENTRY_LENGTH);
- struct timeval t;
- int pid = IVAL(p,SME_PID_OFFSET);
- int mode = IVAL(p,SME_SHAREMODE_OFFSET);
-
- t.tv_sec = IVAL(p,SME_SEC_OFFSET);
- t.tv_usec = IVAL(p,SME_USEC_OFFSET);
- oplock_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
-#endif /* FAST_SHARE_MODES */
-
- fname[sizeof(fname)-1] = 0;
-
- if (firstopen) {
- firstopen=False;
- printf("Locked files:\n");
- printf("Pid DenyMode R/W Oplock Name\n");
- printf("--------------------------------------------------\n");
- }
-
-
- printf("%-5d ",pid);
- switch ((mode>>4)&0xF)
- {
- case DENY_NONE: printf("DENY_NONE "); break;
- case DENY_ALL: printf("DENY_ALL "); break;
- case DENY_DOS: printf("DENY_DOS "); break;
- case DENY_READ: printf("DENY_READ "); break;
- case DENY_WRITE:printf("DENY_WRITE "); break;
- }
- switch (mode&0xF)
- {
- case 0: printf("RDONLY "); break;
- case 1: printf("WRONLY "); break;
- case 2: printf("RDWR "); break;
- }
-
- if((oplock_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) == (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
- printf("EXCLUSIVE+BATCH ");
- else if (oplock_type & EXCLUSIVE_OPLOCK)
- printf("EXCLUSIVE ");
- else if (oplock_type & BATCH_OPLOCK)
- printf("BATCH ");
- else
- printf("NONE ");
-
- printf(" %s %s",fname,asctime(LocalTime((time_t *)&t.tv_sec)));
-
-#ifdef FAST_SHARE_MODES
-
- entry_scanner_p = (share_mode_entry *)smb_shm_offset2addr(
- entry_scanner_p->next_share_mode_entry);
- } /* end while entry_scanner_p */
- file_scanner_p = (share_mode_record *)smb_shm_offset2addr(
- file_scanner_p->next_offset);
- } /* end while file_scanner_p */
- smb_shm_unlock_hash_entry(i);
- } /* end for */
-
- smb_shm_get_usage(&bytes_free, &bytes_used, &bytes_overhead);
- bytes_total = bytes_free + bytes_used + bytes_overhead;
-
- /*******************************************************************
- deinitialize the shared memory for share_mode management
- ******************************************************************/
- smb_shm_close();
-
-#else /* FAST_SHARE_MODES */
- } /* end for i */
-
- if(buf)
- free(buf);
- base = 0;
- } /* end while */
- closedir(dir);
-
-#endif /* FAST_SHARE_MODES */
- if (firstopen)
- printf("No locked files\n");
-#ifdef FAST_SHARE_MODES
- printf("\nShare mode memory usage (bytes):\n");
- printf(" %d(%d%%) free + %d(%d%%) used + %d(%d%%) overhead = %d(100%%) total\n",
- bytes_free, (bytes_free * 100)/bytes_total,
- bytes_used, (bytes_used * 100)/bytes_total,
- bytes_overhead, (bytes_overhead * 100)/bytes_total,
- bytes_total);
-
-#endif /* FAST_SHARE_MODES */
-
- return (0);
-}
-
-/* added by OH */
-void Ucrit_addUsername(pstring username)
-{
- strcpy(Ucrit_username, username);
- if(strlen(Ucrit_username) > 0)
- Ucrit_IsActive = 1;
-}
-
-unsigned int Ucrit_checkUsername(pstring username)
-{
- if ( !Ucrit_IsActive) return 1;
- if (strcmp(Ucrit_username,username) ==0) return 1;
- return 0;
-}
-
-void Ucrit_addPid(int pid)
-{
- int i;
- if ( !Ucrit_IsActive) return;
- for (i=0;i<Ucrit_MaxPid;i++)
- if( pid == Ucrit_pid[i] ) return;
- Ucrit_pid[Ucrit_MaxPid++] = pid;
-}
-
-unsigned int Ucrit_checkPid(int pid)
-{
- int i;
- if ( !Ucrit_IsActive) return 1;
- for (i=0;i<Ucrit_MaxPid;i++)
- if( pid == Ucrit_pid[i] ) return 1;
- return 0;
-}
-
diff --git a/source/utils/testparm.c b/source/utils/testparm.c
deleted file mode 100644
index ca364cb8c94..00000000000
--- a/source/utils/testparm.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Test validity of smb.conf
- Copyright (C) Karl Auer 1993, 1994-1997
-
- Extensively modified by Andrew Tridgell, 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.
-*/
-
-/*
- * Testbed for loadparm.c/params.c
- *
- * This module simply loads a specified configuration file and
- * if successful, dumps it's contents to stdout. Note that the
- * operation is performed with DEBUGLEVEL at 3.
- *
- * Useful for a quick 'syntax check' of a configuration file.
- *
- */
-
-#include "includes.h"
-#include "smb.h"
-
-/* these live in util.c */
-extern FILE *dbf;
-extern int DEBUGLEVEL;
-
- int main(int argc, char *argv[])
-{
- pstring configfile;
- int s;
-
- TimeInit();
-
- setup_logging(argv[0],True);
-
- charset_initialise();
-
- if (argc < 2)
- strcpy(configfile,CONFIGFILE);
- else
- strcpy(configfile,argv[1]);
-
- dbf = stdout;
- DEBUGLEVEL = 2;
-
- printf("Load smb config files from %s\n",configfile);
-
- if (!lp_load(configfile,False))
- {
- printf("Error loading services.\n");
- return(1);
- }
-
-
- printf("Loaded services file OK.\n");
-
- for (s=0;s<1000;s++)
- if (VALID_SNUM(s))
- if (strlen(lp_servicename(s)) > 8) {
- printf("WARNING: You have some share names that are longer than 8 chars\n");
- printf("These may give errors while browsing or may not be accessible\nto some older clients\n");
- break;
- }
-
- if (argc < 4)
- {
- printf("Press enter to see a dump of your service definitions\n");
- fflush(stdout);
- getc(stdin);
- lp_dump(stdout);
- }
-
- if (argc == 4)
- {
- char *cname = argv[2];
- char *caddr = argv[3];
-
- /* this is totally ugly, a real `quick' hack */
- for (s=0;s<1000;s++)
- if (VALID_SNUM(s))
- {
- if (allow_access(lp_hostsdeny(s),lp_hostsallow(s),cname,caddr))
- {
- printf("Allow connection from %s (%s) to %s\n",
- cname,caddr,lp_servicename(s));
- }
- else
- {
- printf("Deny connection from %s (%s) to %s\n",
- cname,caddr,lp_servicename(s));
- }
- }
- }
- return(0);
-}
-
-
diff --git a/source/utils/testprns.c b/source/utils/testprns.c
deleted file mode 100644
index 4a2ddb7c635..00000000000
--- a/source/utils/testprns.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- test printer setup
- Copyright (C) Karl Auer 1993, 1994-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.
-*/
-
-/*
- * Testbed for pcap.c
- *
- * This module simply checks a given printer name against the compiled-in
- * printcap file.
- *
- * The operation is performed with DEBUGLEVEL at 3.
- *
- * Useful for a quick check of a printcap file.
- *
- */
-
-#include "includes.h"
-#include "smb.h"
-
-/* these live in util.c */
-extern FILE *dbf;
-extern int DEBUGLEVEL;
-
-int main(int argc, char *argv[])
-{
- char *pszTemp;
-
- TimeInit();
-
- setup_logging(argv[0],True);
-
- charset_initialise();
-
- if (argc < 2 || argc > 3)
- printf("Usage: testprns printername [printcapfile]\n");
- else
- {
- dbf = fopen("test.log", "w");
- if (dbf == NULL) {
- printf("Unable to open logfile.\n");
- } else {
- DEBUGLEVEL = 3;
- pszTemp = (argc < 3) ? PRINTCAP_NAME : argv[2];
- printf("Looking for printer %s in printcap file %s\n",
- argv[1], pszTemp);
- if (!pcap_printername_ok(argv[1], pszTemp))
- printf("Printer name %s is not valid.\n", argv[1]);
- else
- printf("Printer name %s is valid.\n", argv[1]);
- fclose(dbf);
- }
- }
- return (0);
-}
-
diff --git a/source/web/cgi.c b/source/web/cgi.c
deleted file mode 100644
index 56c293985d6..00000000000
--- a/source/web/cgi.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- some simple CGI helper routines
- 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.
-*/
-
-
-#include "includes.h"
-
-#define MAX_VARIABLES 512
-
-struct var {
- char *name;
- char *value;
-};
-
-static struct var variables[MAX_VARIABLES];
-static int num_variables;
-
-
-static int grab_line(int *cl, char *line, int maxsize)
-{
- int i = 0;
-
- while ((*cl)) {
- int c = fgetc(stdin);
- (*cl)--;
-
- if (c == EOF) {
- (*cl) = 0;
- break;
- }
-
- if (c == '+') {
- c = ' ';
- }
-
- if (c == '\r') continue;
-
- if (strchr("\n&", c)) break;
-
- if (c == '%' && (*cl) >= 2) {
- int c1, c2;
- c1 = fgetc(stdin);
- c2 = fgetc(stdin);
- (*cl) -= 2;
- if (c1 == EOF || c2 == EOF) break;
- if (c1 >= '0' && c1 <= '9')
- c1 = c1 - '0';
- else if (c1 >= 'A' && c1 <= 'F')
- c1 = 10 + c1 - 'A';
- else if (c1 >= 'a' && c1 <= 'f')
- c1 = 10 + c1 - 'a';
- else break;
-
- if (c2 >= '0' && c2 <= '9')
- c2 = c2 - '0';
- else if (c2 >= 'A' && c2 <= 'F')
- c2 = 10 + c2 - 'A';
- else if (c2 >= 'a' && c2 <= 'f')
- c2 = 10 + c2 - 'a';
- else break;
-
- c = (c1<<4) | c2;
- }
-
- line[i++] = c;
-
- if (i == maxsize) break;
- }
-
- /* now unescape the line */
-
-
- line[i] = 0;
- return 1;
-}
-
-
-/***************************************************************************
- load all the variables passed to the CGI program
- ***************************************************************************/
-void cgi_load_variables(void)
-{
- static pstring line;
- char *p;
- int len;
-
- if (!(p=getenv("CONTENT_LENGTH"))) return;
-
- len = atoi(p);
-
- if (len <= 0) return;
-
-
-
- while (len && grab_line(&len, line, sizeof(line)-1)) {
- p = strchr(line,'=');
- if (!p) continue;
-
- *p = 0;
-
- variables[num_variables].name = strdup(line);
- variables[num_variables].value = strdup(p+1);
-
- if (!variables[num_variables].name ||
- !variables[num_variables].value)
- continue;
-
-#if 0
- printf("%s=%s<br>\n",
- variables[num_variables].name,
- variables[num_variables].value);
-#endif
-
- num_variables++;
- if (num_variables == MAX_VARIABLES) break;
- }
-
- fclose(stdin);
-}
-
-
-/***************************************************************************
- find a variable passed via CGI
- ***************************************************************************/
-char *cgi_variable(char *name)
-{
- int i;
-
- for (i=0;i<num_variables;i++)
- if (strcmp(variables[i].name, name) == 0)
- return variables[i].value;
- return NULL;
-}
-
-
-/***************************************************************************
- return the value of a CGI boolean variable.
- ***************************************************************************/
-int cgi_boolean(char *name, int def)
-{
- char *p = cgi_variable(name);
-
- if (!p) return def;
-
- return strcmp(p, "1") == 0;
-}
diff --git a/source/wsmbconf.c b/source/wsmbconf.c
deleted file mode 100644
index 203952c204f..00000000000
--- a/source/wsmbconf.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- html smb.conf editing - prototype only
- 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.
-*/
-
-#ifdef SYSLOG
-#undef SYSLOG
-#endif
-
-#include "includes.h"
-#include "smb.h"
-
-#define SDEFAULTS "Service defaults"
-#define SGLOBAL "Global Parameters"
-#define GLOBALS_SNUM -2
-#define DEFAULTS_SNUM -1
-
-
-/* start the page with standard stuff */
-static void print_header(void)
-{
- printf("Content-type: text/html\n\n");
- printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n");
- printf("<HTML>\n<HEAD>\n<TITLE>smb.conf</TITLE>\n</HEAD>\n<BODY>\n\n");
-}
-
-
-/* finish off the page */
-static void print_footer(void)
-{
- printf("\n</BODY>\n</HTML>\n");
-}
-
-/* setup persisant variables */
-static void set_persistent(char *name)
-{
- char *p;
- p = cgi_variable(name);
- if (!p) return;
- printf("<input type=hidden name=%s value=%s>\n", name, p);
-}
-
-/* display a servce, ready for editing */
-static void show_service(int snum, int allparameters)
-{
- int i = 0;
- pstring label, value;
- char *sname;
-
- if (snum == GLOBALS_SNUM)
- sname = SGLOBAL;
- else if (snum == DEFAULTS_SNUM)
- sname = SDEFAULTS;
- else sname = lp_servicename(snum);
-
- printf("\n<p><table border=0>\n<tr>\n<td></td><td>\n\n");
- printf("<form method=POST>\n");
- printf("<H3>%s</H3>\n", sname);
- printf("<input type=hidden name=service value=\"%s\">\n", sname);
- printf("<input type=submit name=request value=Change>\n");
- printf("<input type=submit name=request value=Rename>\n");
- printf("<input type=submit name=request value=Copy>\n");
- printf("<input type=submit name=request value=Remove>\n");
- printf("<br><input name=newvalue><br>\n");
- printf("<select name=parameter size=5>\n");
-
- while (lp_next_parameter(snum, &i, label, value, allparameters)) {
- printf("<option value=\"%s\">%s = %s\n",
- label, label, value);
- }
-
- printf("</select>\n");
- printf("</form>\n</td>\n</tr>\n</table>\n");
-
- printf("<p>\n");
-}
-
-
-/* loop over all services, displaying them one after the other */
-static void show_services(void)
-{
- int i;
- int n;
- int allparameters = cgi_boolean("allparameters", 0);
-
- printf("<FORM METHOD=POST>\n");
- printf("<p>Show all parameters?\n");
- printf("<INPUT NAME=allparameters TYPE=checkbox VALUE=1 %s>\n",
- allparameters?"CHECKED":"");
-
- printf("<INPUT TYPE=submit NAME=reload VALUE=Reload>\n");
-
- printf("</FORM>\n");
-
- n = lp_numservices();
-
- show_service(GLOBALS_SNUM, allparameters);
- show_service(DEFAULTS_SNUM, allparameters);
-
- for (i=0;i<n;i++)
- if (VALID_SNUM(i))
- show_service(i, allparameters);
-}
-
-
-/* load the smb.conf file into loadparm. this also does the chroot
- to the config directory. This must be called _BEFORE_ any client
- supplied data is parsed */
-static int load_config(void)
-{
- static pstring servicesf = CONFIGFILE;
- char *p;
-
- p = strrchr(servicesf,'/');
- if (!p) return 0;
-
- *p = 0;
-
- setuid(0);
-
- if (chdir(servicesf) || chroot(servicesf)) {
- printf("wsmbconf is not configured correctly\n");
- return 0;
- }
-
- *p = '/';
-
- if (!lp_load(p,False)) {
- printf("<b>Can't load %s - using defaults</b><p>\n",
- servicesf);
- }
- return 1;
-}
-
-
-static int save_reload(void)
-{
- static pstring servicesf = CONFIGFILE;
- char *p;
- FILE *f;
-
- p = strrchr(servicesf,'/');
- if (!p) return 0;
-
- f = fopen(p,"w");
- if (!f) {
- printf("failed to open %s for writing\n", servicesf);
- return 0;
- }
-
- fprintf(f, "# Samba config file created using wsmbconf\n");
-
- lp_dump(f);
-
- fclose(f);
-
- lp_killunused(NULL);
-
- if (!lp_load(p,False)) {
- printf("Can't reload %s\n", servicesf);
- return 0;
- }
-
- return 1;
-}
-
-static void process_requests(void)
-{
- char *req = cgi_variable("request");
- char *newvalue = cgi_variable("newvalue");
- char *parameter = cgi_variable("parameter");
- char *service = cgi_variable("service");
- int snum=0;
-
- if (!req) return;
-
- if (service) {
- /* work out what service it is */
- if (strcmp(service,SGLOBAL) == 0) {
- snum = GLOBALS_SNUM;
- } else if (strcmp(service,SDEFAULTS) == 0) {
- snum = DEFAULTS_SNUM;
- } else {
- snum = lp_servicenumber(service);
- if (snum < 0) return;
- }
- }
-
- if (!newvalue)
- newvalue = "";
-
- if (strcmp(req,"Change") == 0) {
- /* change the value of a parameter */
- if (!parameter || !service) return;
-
- lp_do_parameter(snum, parameter, newvalue);
- } else if (strcmp(req,"Rename") == 0) {
- /* rename a service */
- if (!newvalue || !service) return;
-
- lp_rename_service(snum, newvalue);
- } else if (strcmp(req,"Remove") == 0) {
- /* remove a service */
- if (!service) return;
-
- lp_remove_service(snum);
- } else if (strcmp(req,"Copy") == 0) {
- /* copy a service */
- if (!service || !newvalue) return;
-
- lp_copy_service(snum, newvalue);
- }
-
- save_reload();
-}
-
-
-int main(int argc, char *argv[])
-{
- extern FILE *dbf;
-
- print_header();
-
- dbf = stderr;
-
- charset_initialise();
-
- if (load_config()) {
- cgi_load_variables();
- process_requests();
- show_services();
- }
- print_footer();
- return 0;
-}
diff --git a/source/wsmbstatus.c b/source/wsmbstatus.c
deleted file mode 100644
index 2762b8610e7..00000000000
--- a/source/wsmbstatus.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- html status reporting
- 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.
-*/
-
-#ifdef SYSLOG
-#undef SYSLOG
-#endif
-
-#include "includes.h"
-
-static void print_header(void)
-{
- printf("Content-type: text/html\n\n");
- printf("<HTML>\n<HEAD>\n<TITLE>smbstatus</TITLE>\n</HEAD>\n<BODY>\n\n");
-}
-
-static void print_footer(void)
-{
- printf("\n</BODY>\n</HTML>\n");
-}
-
-static void show_connections(void)
-{
- static pstring servicesf = CONFIGFILE;
- pstring fname;
- FILE *f;
- struct connect_record crec;
-
- if (!lp_load(servicesf,False)) {
- printf("Can't load %s - run testparm to debug it\n", servicesf);
- return;
- }
-
- strcpy(fname,lp_lockdir());
- standard_sub_basic(fname);
- trim_string(fname,"","/");
- strcat(fname,"/STATUS..LCK");
-
- f = fopen(fname,"r");
- if (!f) {
- printf("Couldn't open status file %s\n",fname);
- if (!lp_status(-1))
- printf("You need to have status=yes in your smb config file\n");
- return;
- }
-
-
- printf("\nSamba version %s\n<p>",VERSION);
-
- while (!feof(f)) {
- if (fread(&crec,sizeof(crec),1,f) != 1)
- break;
- if (crec.magic == 0x280267 && process_exists(crec.pid)) {
- printf("%-10.10s %-8s %-8s %5d %-8s (%s) %s<br>",
- crec.name,uidtoname(crec.uid),
- gidtoname(crec.gid),crec.pid,
- crec.machine,crec.addr,
- asctime(LocalTime(&crec.start)));
- }
- }
- fclose(f);
-}
-
-int main(int argc, char *argv[])
-{
- print_header();
- show_connections();
- print_footer();
- return 0;
-}