1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

This commit was generated by cvs2svn to compensate for changes in r4,

which included commits to RCS files with non-trunk default branches.
(This used to be commit c8a46aca03)
This commit is contained in:
Samba Release Account 1996-05-04 07:50:46 +00:00
commit 0db2ec0e94
110 changed files with 54142 additions and 0 deletions

339
COPYING Normal file
View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
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.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

111
README Normal file
View File

@ -0,0 +1,111 @@
This is version 1.9 of Samba, the free SMB client and server for unix.
>>>> Please read THE WHOLE of this file as it gives important information
>>>> about the configuration and use of Samba.
This software is freely distributable under the GNU public license, a
copy of which you should have received with this software (in a file
called COPYING).
WHAT CAN SAMBA DO?
==================
Here is a very short list of what samba includes, and what it does
- a SMB server, to provide LanManager style file and print services to PCs
- a Netbios (rfc1001/1002) nameserver
- a ftp-like SMB client so you can access PC resources (disks and
printers) from unix
- a tar extension to the client for backing up PCs
Related packages include:
- ksmbfs, a linux-only filesystem allowing you to mount remote SMB
filesystems from PCs on your linux box
- tcpdump-smb, a extension to tcpdump to allow you to investigate SMB
networking problems over netbeui and tcp/ip
CONTRIBUTIONS
=============
If you want to contribute to the development of the software then
please join the mailing list. I accept patches (preferably in
"diff -u" format) and am always glad to receive feedback or suggestions.
You could also send hardware/software/money/jewelry or pizza
vouchers directly to me. The pizza vouchers would be especially
welcome :-)
If you like a particular feature then look through the change-log and
see who added it, then send them an email.
Remember that free software of this kind lives or dies by the response
we get. If noone tells us they like it then we'll probably move onto
something else.
Andrew Tridgell
Email: samba-bugs@anu.edu.au
3 Ballow Crescent
Macgregor, A.C.T.
2615 Australia
MORE INFO
=========
DOCUMENTATION
-------------
There is quite a bit of documentation included with the package,
including man pages, and lots of .txt files with hints and useful
info.
FTP SITE
--------
The main anonymous ftp distribution site for this software is
nimbus.anu.edu.au in the directory pub/tridge/samba/.
MAILING LIST
------------
There is a mailing list for discussion of Samba. To subscribe send
mail to listproc@anu.edu.au with a body of "subscribe samba Your Name"
To send mail to everyone on the list mail to samba@listproc.anu.edu.au
There is also an announcement mailing list where I announce new
versions. To subscribe send mail to listproc@anu.edu.au with a body
of "subscribe samba-announce Your Name". All announcements also go to
the samba list.
NEWS GROUP
----------
You might also like to look at the usenet news group
comp.protocols.smb as it often contains lots of useful info and is
frequented by lots of Samba users. The newsgroup was initially setup
by people on the Samba mailing list. It is not, however, exclusive to
Samba, it is a forum for discussing the SMB protocol (which Samba
implements).
WEB SITE
--------
A Samba WWW site has been setup with lots of useful info. Connect to:
http://lake.canberra.edu.au/pub/samba/
It is maintained by Paul Blackman (thanks Paul!). You can contact him
at ictinus@lake.canberra.edu.au.

119
docs/THANKS Normal file
View File

@ -0,0 +1,119 @@
=====================================================================
This file is for thanks to individuals or organisations who have
helped with the development of Samba, other than by coding or bug
reports. Their contributions are gratefully acknowledged.
Please refer to the manual pages and change-log for a list of those
who have contributed in the form of patches, bug fixes or other
direct changes to the package.
Contributions of any kind are welcomed. If you want to help then
please contact Andrew.Tridgell@anu.edu.au, or via normal mail at
Andrew Tridgell
3 Ballow Crescent
Macgregor, A.C.T
2615 Australia
=====================================================================
Lee Fisher (leefi@microsoft.com)
Charles Fox (cfox@microsoft.com)
Dan Perry (danp@exchnge.microsoft.com)
These Microsoft people have been very helpful and supportive of
the development of Samba.
Lee very kindly supplied me with a copy of the X/Open SMB
specs. These have been invaluable in getting the details of the
implementation right. They will become even more important as we move
towards a Lanman 2.1 compliant server. Lee has provided very
useful advice on several aspects of the server.
Lee has also provided me with copies of Windows NTAS 3.1, Visual C
and a developers CD-ROM. Being able to run NT at home is a
great help.
Charles has helped out in numerous ways with the provision of SMB
specifications and helpful advice. He has been following the
discussion of Samba on the mailing list and has stepped in
regularly to clarify points and to offer help.
Dan has put me in touch with NT developers to help sort out bugs and
compatability issues. He has also supplied me with a copy of the
NT browsing spec, which will help a lot in the development of the
Samba browser code.
Bruce Perens (bruce@pixar.com)
In appreciation of his effort on Samba we have sent Andrew copies of
various Pixar computer-graphics software products. Pixar is best known
for its "Renderman" product, the 3-D renderer used by ILM to make special
effects for "Terminator II" and "Jurassic Park". We won the first Oscar
given to a computer graphic animated feature for our short film "Tin Toy".
Our retail products "Typestry" and "Showplace", incorporate the same
renderer used on the films, and are available on Windows and the
Macintosh.
Henry Lee (hyl@microplex.co)
Henry sent me a M202 ethernet print server, making my little lan
one of the few home networks to have it's own print server!
``Microplex Systems Ltd. is a manufacturer of local and wide area
network communications equipment based in beautiful Vancouver, British
Columbia, Canada. Microplex's first products were synchronous wide
area network devices used in the mainframe communication networks. In
August 1991 Microplex introduced its first LAN product, the M200 print
server, the first high performance print server under US$1,000.''
Tom Haapanen (tomh@metrics.com)
Tom sent me two 16 bit SMC ethernet cards to replace my ancient 8
bit ones. The performance is much better!
Software Metrics Inc. is a small custom software development and
consulting firm located in Waterloo, Ontario, Canada. We work
with a variety of environments (such as Windows, Windows NT and
Unix), tools and application areas, and can provide assistance for
development work ranging from a few days to to multiple man-year
projects. You can find more information at http://www.metrics.com/.
Steve Kennedy (steve@gbnet.net)
Steve sent me 16Mb of ram so that I could install/test
NT3.5. I previous had only 8Mb ram in my test machine, which
wasn't enough to install a properly functioning copy of
NTAS. Being able to directly test NT3.5 allowed me to solve
several long standing NT<->Samba problems. Thanks Steve!
John Terpstra (jht@aquasoft.com.au)
Aquasoft are a speciaist consulting company whose Samba using
customers span the world.
Aquasoft have been avid supporters of the Samba project. As a
token of appreciation Aquasoft have donated a 486DX2/66 PC with
a 540MB EIDE drive and 20MB RAM.
John has helped to isolate quite a few little glitches over time
and has managed to implement some very interesting installations
of Samba.
The donation of the new PC will make it possible to more fully
diagnose and observe the behaviour of Samba in conjuction with
other SMB protocol utilising systems.
Timothy F. Sipples (tsipple@vnet.IBM.COM)
Steve Withers (swithers@vnet.IBM.COM)
Tim and Steve from IBM organised a copy of the OS/2 developers
connection CD set for me, and gave lots of help in getting
OS/2 Warp installed. I hope this will allow me to finally fix
up those annoying OS/2 related Samba bugs that I have been
receiving reports of.

129
docs/announce Normal file
View File

@ -0,0 +1,129 @@
Announcing Samba version 1.9
============================
What is Samba?
--------------
Samba is a Unix based SMB file server. This allows a Unix host to
act as a file and print server for SMB clients. This includes
Lan-Manager compatible clients such as LanManager for DOS, Windows for
Workgroups, Windows NT, Windows 95, OS/2, Pathworks and many more.
The package also includes a Unix SMB client and a netbios nameserver.
What can it do for me?
----------------------
If you have any PCs running SMB clients, such as a PC running Windows
for Workgroups, then you can mount file space or printers from a unix
host, so that directories, files and printers on the unix host are
available on the PC.
The client part of the package will also allow you to attach to other
SMB-based servers (such as windows NT and windows for workgroups) so
that you can copy files to and from your unix host. The client also
allows you to access a SMB printer (such as one attached to an OS/2 or
WfWg server) from Unix, using an entry in /etc/printcap, or by
explicitly specifying the command used to print files.
What are it's features?
------------------------
Samba supports many features that are not supported in other SMB
implementations (all of which are commercial). Some of it's features
include host as well as username/password security, a unix client,
automatic home directory exporting, automatic printer exporting, dead
connection timeouts, umask support, guest connections, name mangling
and hidden and system attribute mapping. Look at the man pages
included with the package for a full list of features.
What's new since 1.8?
---------------------
Lots of stuff. See the change log and man pages for details.
Where can I get a client for my PC?
-----------------------------------
There is a free client for MS-DOS based PCs available from
ftp.microsoft.com in the directory bussys/Clients/MSCLIENT/. Please
read the licencing information before downloading. The built in
Windows for Workgroups client is also very good.
What network protocols are supported?
-------------------------------------
Currently only TCP/IP is supported. There has been some discussion
about ports to other protocols but nothing is yet available.
There is a free TCP/IP implementation for Windows for Workgroups
available from ftp.microsoft.com (it's small, fast and quite reliable).
How much does it cost?
----------------------
Samba software is free software. It is available under the
GNU Public licence in source code form at no cost. Please read the
file COPYING that comes with the package for more information.
What flavours of unix does it support?
---------------------------------------
The code has been written to be as portable as possible. It has been
"ported" to many unixes, which mostly required changing only a few
lines of code. It has been run (to my knowledge) on at least these
unixes:
Linux, SunOS, Solaris, SVR4, Ultrix, OSF1, AIX, BSDI, NetBSD,
Sequent, HP-UX, SGI, FreeBSD, NeXT, ISC, A/UX, SCO, Intergraph,
Domain/OS and DGUX.
Some of these have received more testing than others. If it doesn't
work with your unix then it should be easy to fix.
Who wrote it?
-------------
Many people on the internet have contributed to the development of
Samba. The maintainer and original author is Andrew Tridgell, but
large parts of the package were contributed by several people from all
over the world. Please look at the file `change-log' for information
on who did what bits.
Where can I get it?
-------------------
The package is available via anonymous ftp from nimbus.anu.edu.au in
the directory pub/tridge/samba/.
What about SMBServer?
---------------------
Samba used to be known as SMBServer, until it was pointed out that
Syntax, who make a commercial Unix SMB based server, have trademarked
that name. The name was then changed to Samba. Also, in 1992 a very
early incarnation of Samba was distributed as nbserver.
If you see any copies of nbserver or smbserver on ftp sites please let
me or the ftp archive maintainer know, as I want to get them deleted.
Where can I get more info?
---------------------------
Please join the mailing list if you want to discuss the development or
use of Samba. To join the mailing list send mail to
listproc@listproc.anu.edu.au with a body of "subscribe samba Your
Name".
There is also an announcement mailing list for new version
announcements. Subscribe as above but with "subscribe samba-announce
Your Name".
There is also often quite a bit of discussion about Samba on the
newsgroup comp.protocols.smb.
A WWW site with lots of Samba info can be found at
http://lake.canberra.edu.au/pub/samba/
Andrew Tridgell (Contact: samba-bugs@anu.edu.au)
January 1995

165
docs/history Normal file
View File

@ -0,0 +1,165 @@
Note: This file is now quite out of date - but perhaps that's
appropriate?
=========
This is a short history of this project. It's not supposed to be
comprehensive, just enough so that new users can get a feel for where
this project has come from and maybe where it's going to.
The whole thing really started in December 1991. I was (and still am)
a PhD student in the Computer Sciences Laboratory at the Australian
Netional University, in Canberra, Australia. We had just got a
beta copy of eXcursion from Digital, and I was testing it on my PC. At
this stage I was a MS-DOS user, dabbling in windows.
eXcursion ran (at the time) only with Dec's `Pathworks' network for
DOS. I had up till then been using PC-NFS to connect to our local sun
workstations, and was reasonably happy with it. In order to run
pathworks I had to stop using PC-NFS and try using pathworks to mount
disk space. Unfortunately pathworks was only available for digital
workstations running VMS or Ultrix so I couldn't mount from the suns
anymore.
I had access to a a decstation 3100 running Ultrix that I used to
administer, and I got the crazy notion that the protocol that
pathworks used to talk to ultrix couldn't be that hard, and maybe I
could work it out. I had never written a network program before, and
certainly didn't know what a socket was.
In a few days, after looking at some example code for sockets, I
discovered it was pretty easy to write a program to "spy" on the file
sharing protocol. I wrote and installed this program (the sockspy.c
program supplied with this package) and captured everything that the
pathworks client said to the pathworks server.
I then tried writing short C programs (using Turbo C under DOS) to do
simple file operations on the network drive (open, read, cd etc) and
looked at the packets that the server and client exchanged. From this
I worked out what some of the bytes in the packets meant, and started
to write my own program to do the same thing on a sun.
After a day or so more I had my first successes and actually managed
to get a connection and to read a file. From there it was all
downhill, and a week later I was happily (if a little unreliably)
mounting disk space from a sun to my PC running pathworks. The server
code had a lot of `magic' values in it, which seemed to be always
present with the ultrix server. It was not till 2 years later that I
found out what all these values meant.
Anyway, I thought other people might be interested in what I had done,
so I asked a few people at uni, and noone seemed much interested. I
also spoke to a person at Digital in Canberra (the person who had
organised a beta test of eXcursion) and asked if I could distribute
what I'd done, or was it illegal. It was then that I first heard the
word "netbios" when he told me that he thought it was all covered by a
spec of some sort (the netbios spec) and thus what I'd done was not
only legal, but silly.
I found the netbios spec after asking around a bit (the RFC1001 and
RFC1002 specs) and found they looked nothing like what I'd written, so
I thought maybe the Digital person was mistaken. I didn't realise RFCs
referred to the name negotiation and packet encapsulation over TCP/IP,
and what I'd written was really a SMB implementation.
Anyway, he encouraged me to release it so I put out "Server 0.1" in
January 1992. I got quite a good response from people wanting to use
pathworks with non-digital unix workstations, and I soon fixed a few
bugs, and released "Server 0.5" closely followed by "Server 1.0". All
three releases came out within about a month of each other.
At this point I got an X Terminal on my desk, and I no longer needed eXcursion
and I prompty forgot about the whole project, apart from a few people
who e-mailed me occasionally about it.
Nearly two years then passed with just occasional e-mails asking about
new versions and bugs. I even added a note to the ftp site asking for
a volunteer to take over the code as I no longer used it. No one
volunteered.
During this time I did hear from a couple of people who said it should
be possible to use my code with Lanmanager, but I never got any
definite confirmation.
One e-mail I got about the code did, however, make an impression. It
was from Dan Shearer at the university of South Australia, and he said
this:
I heard a hint about a free Pathworks server for Unix in the
Net channel of the Linux list. After quite a bit of chasing
(and lots of interested followups from other Linux people) I
got hold of a release news article from you, posted in Jan 92,
from someone in the UK.
Can you tell me what the latest status is? I think you might
suddenly find a whole lot of interested hackers in the Linux
world at least, which is a place where things tend to happen
fast (and even some reliable code gets written, BION!)
I asked him what Linux was, and he told me it was a free Unix for PCs.
This was in November 1992 and a few months later I was a Linux
convert! I still didn't need a pathworks server though, so I didn't do
the port, but I think Dan did.
At about this time I got an e-mail from Digital, from a person working
on the Alpha software distribution. He asked if I would mind if they
included my server with the "contributed" cd-rom. This was a bit of a
shock to me as I never expected Dec to ask me if they could use my
code! I wrote back saying it was OK, but never heard from him again. I
don't know if it went on the cd-rom.
Anyway, the next big event was in December 1993, when Dan again sent
me an e-mail saying my server had "raised it's ugly head" on
comp.protocols.tcpip.ibmpc. I had a quick look on the group, and was
surprised to see that there were people interested in this thing.
At this time a person from our computer center offered me a couple of
cheap ethernet cards (3c505s for $15 each) and coincidentially someone
announced on one of the Linux channels that he had written a 3c505
driver for Linux. I bought the cards, hacked the driver a little and
setup a home network between my wifes PC and my Linux box. I then
needed some way to connect the two, and I didn't own PC-NFS at home,
so I thought maybe my server could be useful. On the newsgroup among
the discussions of my server someone had mentioned that there was a
free client that might work with my server that Microsoft had put up
for ftp. I downloaded it and found to my surprise that it worked first
time with my `pathworks' server!
Well, I then did a bit of hacking, asked around a bit and found (I
think from Dan) that the spec I needed was for the "SMB" protocol, and
that it was available via ftp. I grabbed it and started removing all
those ugly constants from the code, now that all was explained.
On December 1st 1993 I announced the start of the "Netbios for Unix"
project, seeding the mailing list with all the people who had e-mailed
me over the years asking about the server.
About 35 versions (and two months) later I wrote a short history of
the project, which you have just read. There are now over a hundred
people on the mailing list, and lots of people report that they use
the code and like it. In a few days I will be announcing the release
of version 1.6 to some of the more popular (and relevant) newsgroups.
Andrew Tridgell
6th February 1994
---------------------
It is now May 1995 and there are about 1400 people on the mailing
list. I got downloads from the main Samba ftp site from around 5000
unique hosts in a two month period. There are several mirror
sites as well. The current version number is 1.9.13.
---------------------
---------------------
It's now March 1996 and version 1.9.16alpha1 has just been
released. There have been lots of changes recently with master browser
support and the ability to do domain logons etc. Samba has also been
ported to OS/2, the amiga and NetWare. There are now 3000 people on
the samba mailing list.
---------------------

175
docs/htmldocs/wfw_slip.htm Normal file
View File

@ -0,0 +1,175 @@
<HTML>
<HEAD>
<TITLE>Peter Karrer Announces SLIP for WFW</TITLE>
</HEAD>
<BODY>
<H1><I>Winserve</I></H1>
<HR>
<H2><I>Peter Karrer Announces SLIP for WFW</I></H2>
[NEW 03-22-95)
<HR>
<B>Hello,</B>
<P>
I've discovered a way to run WfW's TCP/IP-32 over a SLIP packet driver. This
allows WfW users to do Windows networking over dialup lines just like it is
possible with NT and the Windows 95 beta!
<P>
For instance, you can mount Microsoft's FTP server as a network drive in File
Manager or connect to an MS Mail post office over the Internet. Of course,
the usual Internet stuff works as well. Another interesting site is
WINSERVE.001; check out www.winserve.com.
<HR>
This method should work with any class 1 (Ethernet II) packet driver. However,
I'm not in a position to try anything else than SLIPPER/CSLIPPER.
<HR>
<H3>Files you need:</H3>
<B>WFWT32.EXE:</B> ftp://ftp.microsoft.com/bussys/msclient/wfw/wfwt32.exe
<P>
Microsoft's free TCP/IP for WfW. It's a self-extracting archive which
should be executed in an empty directory.
<P>
<B>SLIPPER.EXE:</B> ftp://biocserver.bioc.cwru.edu/pub/dos/slipper/slippr15.zip
<P>
Peter Tattam's SLIP packet driver. CSLIPPER.EXE is a variant which supports
VJ header compression.
<P>
<B>PDETHER.EXE:</B> ftp://sjf-lwp.idz.sjf.novell.com/odi/pdether/pde105.zip
<P>
Don Provan's ODI-over-Packet Driver shim. This *must* be version 1.05 (or
above).
<P>
<B>LSL.COM:</B>
<P>
Novell's LAN Support Layer. If you're an owner of Windows 3.10, you'll
have it on one of your install disks. Use "expand a:lsl.co_ lsl.com" to
expand it. Microsoft has stopped bundling LSL.COM with WfW 3.11, though.
The newest version of LSL.COM can be downloaded as part of
ftp://ftp.novell.com/pub/netware/nwos/dosclnt12/vlms/vlmup2.exe.
However, it's not clear if this one may be legally used outside Netware
environments.
<P>
<B>NET.CFG:</B>
<P>
A configuration file for LSL and PDETHER. It should contain the following
text:
<P>
<PRE>
Link Support
Buffers 8 1600
Link Driver PDETHER
Int 60
Frame Ethernet_II
Protocol IP 800 Ethernet_II
Protocol ARP 806 Ethernet_II
Protocol RARP 8035 Ethernet_II
</PRE>
<P>
<B>DISCOMX.COM:</B>
<P>
A little hack of mine to disable the COM port used by the SLIP packet driver.
Usage is e.g. "discomx 2" to disable COM2. This should be run before
starting WfW, otherwise you'll get "device conflict" messages. Here it is:
<P><PRE>
begin 644 discomx.com
F,=N)V8H.@`"P(+^!`/.N3XH="=MT!DN`XP/1XS')!R:)CP`$S2``
`
end
</PRE>
(Save this text to disk as <I>filename</I>, then run "uudecode <I>filename</I>".
uudecode can be found, for instance, at
ftp://ftp.switch.ch/mirror/simtel/msdos/starter/uudecode.com )
<P>
<B>LMHOSTS:</B>
<P>
An optional file which should be stored in your Windows subdirectory. It is
used to map NetBIOS computer names to IP addresses. Example:
<P>
<PRE>
198.105.232.1 ftp #PRE # ftp.microsoft.com
204.118.34.11 winserve.001 #PRE # Winserve
</PRE>
<HR>
<H3>How to install it:</H3>
<P>
<UL>
<LI>Put the files mentioned above into a directory, e.g. C:\SLIP.
<P>
<LI>Put the following lines into AUTOEXEC.BAT:
<P><PRE>
cd \slip
slipper com1 vec=60 baud=57600 ether (may vary with your modem setup)
lsl
pdether
discomx 1 (must correspond to SLIPPER's COM port)
</PRE>
(If you use another vec= setting, you must update that in NET.CFG as well.)
Use CSLIPPER instead of SLIPPER if your SLIP provider supports VJC.
<P>
<LI>Start WfW.
<UL>
<LI>Under Windows Setup, choose "Change Network Settings".
<LI>Select "Install Microsoft Windows Network".
<LI>In "Drivers...", choose "Add Adapter"
and install the "IPXODI Support driver (Ethernet) [ODI/NDIS3]".
<LI>In "Add Protocols...", select "Unlisted or Updated Protocol". When asked for a
driver disk, enter the directory where you expanded WFWT32.EXE.
<LI>Configure TCP/IP (IP address, enable LMHOSTS lookup, try 204.118.34.11 as primary
WINS server). Remove all other protocols (NetBEUI, IPX/SPX).
</UL>
<P>
<LI>Windows will probably update the first lines of AUTOEXEC.BAT with
<P>
<PRE>
c:\windows\net start
c:\windows\odihlp.exe.
</PRE>
The "odihlp" line must be moved behind the "pdether" line.
<P>
<LI>Windows will also update NET.CFG with some "Frame" lines. These must
be removed (except "Frame Ethernet_II").
<P>
<LI>Somehow, you will have to dial in to your SLIP provider. I do it manually
before slipper (or cslipper) gets loaded, using a DOS-based terminal program.
But there are some automatic dialers around. I've seen recommendations for
ftp://mvmpc9.ciw.uni-karlsruhe.de/x-slip/slip_it.exe.
<P>
<LI>To connect to Microsoft's FTP server (or Winserve) go into File Manager,
choose "Connect Network drive" and enter "\\ftp" or "\\winserve.001" into
the "Path:" field.
</UL>
<HR>
<H3>How it works:</H3>
<P>
Microsoft's TCP/IP-32 requires an NDIS3 interface. NDIS is Microsoft's way
to interface with a network.
<P>
WfW also contains an NDIS3-over-ODI "shim", whose real mode component is
ODIHLP.EXE. ODI is Novell's way to interface with a network.
<P>
SLIPPER is a Packet Driver (PD) for use over serial lines. PDs are everybody
else's way to interface with a network. SLIPPER's "ether" option makes it
look like an Ethernet PD to applications using it.
<P>
A "shim" is a program which simulates a network application programming
interface on top of another.
<P>
There is no NDIS SLIP driver which would work with WfW.
<P>
There is no NDIS-over-PD shim.
<P>
However, there's an ODI-over-PD shim (PDETHER) and an NDIS-over-ODI shim
(ODIHLP etc.)
<P>
OK, so let's do NDIS-over-ODI-over-PD!
<P>
This should have worked all the time; however, a non-feature in PDETHER
versions < 1.05 has prevented the method from functioning until now.
<HR>
<B>Questions, suggestions etc. please to
<P>
<PRE>
Peter Karrer pkarrer@ife.ee.ethz.ch
</PRE>
</B>
</BODY>
</HTML>

491
docs/manpages/nmbd.8 Normal file
View File

@ -0,0 +1,491 @@
.TH NMBD 8 17/1/1995 nmbd nmbd
.SH NAME
nmbd \- provide netbios nameserver support to clients
.SH SYNOPSIS
.B nmbd
[
.B -B
.I broadcast address
] [
.B -I
.I IP address
] [
.B -D
] [
.B -C comment string
] [
.B -G
.I group name
] [
.B -H
.I netbios hosts file
] [
.B -N
.I netmask
] [
.B -d
.I debuglevel
] [
.B -l
.I log basename
] [
.B -n
.I netbios name
] [
.B -p
.I port number
] [
.B -s
.I config file name
]
.SH DESCRIPTION
This program is part of the Samba suite.
.B nmbd
is a server that understands and can reply to netbios
name service requests, like those produced by LanManager
clients. It also controls browsing.
LanManager clients, when they start up, may wish to locate a LanManager server.
That is, they wish to know what IP number a specified host is using.
This program simply listens for such requests, and if its own name is specified
it will respond with the IP number of the host it is running on. "Its own name"
is by default the name of the host it is running on, but this can be overriden
with the
.B -n
option (see "OPTIONS" below). Using the
.B -S
option (see "OPTIONS" below), it can also be instructed to respond with IP
information about other hosts, provided they are locatable via the
gethostbyname() call, or they are in a netbios hosts file.
Nmbd can also be used as a WINS (Windows Internet Name Server)
server. It will do this automatically by default. What this basically
means is that it will respond to all name requests that it receives
that are not broadcasts, as long as it can resolve the name.
.SH OPTIONS
.B -B
.RS 3
On some systems, the server is unable to determine the broadcast address to
use for name registration requests. If your system has this difficulty, this
parameter may be used to specify an appropriate broadcast address. The
address should be given in standard "a.b.c.d" notation.
Only use this parameter if you are sure that the server cannot properly
determine the proper broadcast address.
The default broadcast address is determined by the server at run time. If it
encounters difficulty doing so, it makes a guess based on the local IP
number.
.RE
.B -I
.RS 3
On some systems, the server is unable to determine the correct IP
address to use. This allows you to override the default choice.
.RE
.B -D
.RS 3
If specified, this parameter causes the server to operate as a daemon. That is,
it detaches itself and runs in the background, fielding requests on the
appropriate port.
By default, the server will NOT operate as a daemon.
.RE
.B -C comment string
.RS 3
This allows you to set the "comment string" that is shown next to the
machine name in browse listings.
A %v will be replaced with the Samba version number.
A %h will be replaced with the hostname.
It defaults to "Samba %v".
.RE
.B -G
.RS 3
This option allows you to specify a netbios group (also known as
lanmanager domain) that the server should be part of. You may include
several of these on the command line if you like. Alternatively you
can use the -H option to load a netbios hosts file containing domain names.
At startup, unless the -R switch has been used, the server will
attempt to register all group names in the hosts file and on the
command line (from the -G option).
The server will also respond to queries on this name.
.RE
.B -H
.RS 3
It may be useful in some situations to be able to specify a list of
netbios names for which the server should send a reply if
queried. This option allows that. The syntax is similar to the
standard /etc/hosts file format, but has some extensions.
The file contains three columns. Lines beginning with a # are ignored
as comments. The first column is an IP address, or a hostname. If it
is a hostname then it is interpreted as the IP address returned by
gethostbyname() when read. Any IP address of 0.0.0.0 will be
interpreted as the servers own IP address.
The second column is a netbios name. This is the name that the server
will respond to. It must be less than 20 characters long.
The third column is optional, and is intended for flags. Currently the
only flags supported are G, S and M. A G indicates that the name is a
group (also known as domain) name.
At startup all groups known to the server (either from this file or
from the -G option) are registered on the network (unless the -R
option has been selected).
A S or G means that the specified address is a broadcast address of a
network that you want people to be able to browse you from. Nmbd will
search for a master browser in that domain and will send host
announcements to that machine, informing it that the specifed somain
is available.
A M means that this name is the default netbios name for this
machine. This has the same affect as specifying the -n option to nmbd.
After startup the server waits for queries, and will answer queries to
any name known to it. This includes all names in the netbios hosts
file (if any), it's own name, and any names given with the -G option.
The primary intention of the -H option is to allow a mapping from
netbios names to internet domain names, and to allow the specification
of groups that the server should be part of.
.B Example:
# This is a sample netbios hosts file
# DO NOT USE THIS FILE AS-IS
# YOU MAY INCONVENIENCE THE OWNERS OF THESE IPs
# if you want to include a name with a space in it then
# use double quotes.
# first put ourselves in the group LANGROUP
0.0.0.0 LANGROUP G
# next add a netbios alias for a faraway host
arvidsjaur.anu.edu.au ARVIDSJAUR
# finally put in an IP for a hard to find host
130.45.3.213 FREDDY
# now we want another subnet to be able to browse
# us in the workgroup UNIXSERV
192.0.2.255 UNIXSERV G
.RE
.B -M
.I workgroup name
.RS 3
If this parameter is given, the server will look for a master browser
for the specified workgroup name, report success or failure, then
exit. If successful, the IP address of the name located will be
reported.
If you use the workgroup name "-" then nmbd will search for a master
browser for any workgroup by using the name __MSBROWSE__.
This option is meant to be used interactively on the command line, not
as a daemon or in inetd.
.RE
.B -N
.RS 3
On some systems, the server is unable to determine the netmask. If
your system has this difficulty, this parameter may be used to specify
an appropriate netmask. The mask should be given in standard
"a.b.c.d" notation.
Only use this parameter if you are sure that the server cannot properly
determine the proper netmask.
The default netmask is determined by the server at run time. If it
encounters difficulty doing so, it makes a guess based on the local IP
number.
.RE
.B -d
.I debuglevel
.RS 3
debuglevel is an integer from 0 to 5.
The default value if this parameter is not specified is zero.
The higher this value, the more detail will be logged to the log files about
the activities of the server. At level 0, only critical errors and serious
warnings will be logged. Level 1 is a reasonable level for day to day running
- it generates a small amount of information about operations carried out.
Levels above 1 will generate considerable amounts of log data, and should
only be used when investigating a problem. Levels above 3 are designed for
use only by developers and generate HUGE amounts of log data, most of which
is extremely cryptic.
.RE
.B -l
.I log file
.RS 3
If specified,
.I logfile
specifies a base filename into which operational data from the running server
will be logged.
The default base name is specified at compile time.
The base name is used to generate actual log file names. For example, if the
name specified was "log", the following files would be used for log data:
.RS 3
log.nmb (containing debugging information)
log.nmb.in (containing inbound transaction data)
log.nmb.out (containing outbound transaction data)
.RE
The log files generated are never removed by the server.
.RE
.RE
.B -n
.I netbios name
.RS 3
This parameter tells the server what netbios name to respond with when
queried. The same name is also registered on startup unless the -R
parameter was specified.
The default netbios name used if this parameter is not specified is the
name of the host on which the server is running.
.RE
.B -p
.I port number
.RS 3
port number is a positive integer value.
The default value if this parameter is not specified is 137.
This number is the port number that will be used when making connections to
the server from client software. The standard (well-known) port number for the
server is 137, hence the default. If you wish to run the server as an ordinary
user rather than as root, most systems will require you to use a port number
greater than 1024 - ask your system administrator for help if you are in this
situation.
Note that the name server uses UDP, not TCP!
This parameter is not normally specified except in the above situation.
.RE
.SH FILES
.B /etc/inetd.conf
.RS 3
If the server is to be run by the inetd meta-daemon, this file must contain
suitable startup information for the meta-daemon. See the section
"INSTALLATION" below.
.RE
.B /etc/rc.d/rc.inet2
.RS 3
(or whatever initialisation script your system uses)
If running the server as a daemon at startup, this file will need to contain
an appropriate startup sequence for the server. See the section "Installation"
below.
.RE
.B /etc/services
.RS 3
If running the server via the meta-daemon inetd, this file must contain a
mapping of service name (eg., netbios-ns) to service port (eg., 137) and
protocol type (eg., udp). See the section "INSTALLATION" below.
.RE
.RE
.SH ENVIRONMENT VARIABLES
Not applicable.
.SH INSTALLATION
The location of the server and its support files is a matter for individual
system administrators. The following are thus suggestions only.
It is recommended that the server software be installed under the /usr/local
hierarchy, in a directory readable by all, writeable only by root. The server
program itself should be executable by all, as users may wish to run the
server themselves (in which case it will of course run with their privileges).
The server should NOT be setuid or setgid!
The server log files should be put in a directory readable and writable only
by root, as the log files may contain sensitive information.
The remaining notes will assume the following:
.RS 3
nmbd (the server program) installed in /usr/local/smb
log files stored in /var/adm/smblogs
.RE
The server may be run either as a daemon by users or at startup, or it may
be run from a meta-daemon such as inetd upon request. If run as a daemon, the
server will always be ready, so starting sessions will be faster. If run from
a meta-daemon some memory will be saved and utilities such as the tcpd
TCP-wrapper may be used for extra security.
When you've decided, continue with either "Running the server as a daemon" or
"Running the server on request".
.SH RUNNING THE SERVER AS A DAEMON
To run the server as a daemon from the command line, simply put the "-D" option
on the command line. There is no need to place an ampersand at the end of the
command line - the "-D" option causes the server to detach itself from the
tty anyway.
Any user can run the server as a daemon (execute permissions permitting, of
course). This is useful for testing purposes.
To ensure that the server is run as a daemon whenever the machine is started,
you will need to modify the system startup files. Wherever appropriate (for
example, in /etc/rc.d/rc.inet2), insert the following line, substituting
values appropriate to your system:
.RS 3
/usr/local/smb/nmbd -D -l/var/adm/smblogs/log
.RE
(The above should appear in your initialisation script as a single line.
Depending on your terminal characteristics, it may not appear that way in
this man page. If the above appears as more than one line, please treat any
newlines or indentation as a single space or TAB character.)
If the options used at compile time are appropriate for your system, all
parameters except the desired debug level and "-D" may be omitted. See the
section on "Options" above.
.SH RUNNING THE SERVER ON REQUEST
If your system uses a meta-daemon such as inetd, you can arrange to have the
SMB name server started whenever a process attempts to connect to it. This
requires several changes to the startup files on the host machine. If you are
experimenting as an ordinary user rather than as root, you will need the
assistance of your system administrator to modify the system files.
First, ensure that a port is configured in the file /etc/services. The
well-known port 137 should be used if possible, though any port may be used.
Ensure that a line similar to the following is in /etc/services:
.RS 3
netbios-ns 137/udp
.RE
Note for NIS/YP users: You may need to rebuild the NIS service maps rather
than alter your local /etc/services file.
Next, put a suitable line in the file /etc/inetd.conf (in the unlikely event
that you are using a meta-daemon other than inetd, you are on your own). Note
that the first item in this line matches the service name in /etc/services.
Substitute appropriate values for your system in this line (see
.B inetd(8)):
.RS 3
netbios-ns dgram udp wait root /usr/local/smb/nmbd -l/var/adm/smblogs/log
.RE
(The above should appear in /etc/inetd.conf as a single line. Depending on
your terminal characteristics, it may not appear that way in this man page.
If the above appears as more than one line, please treat any newlines or
indentation as a single space or TAB character.)
Note that there is no need to specify a port number here, even if you are
using a non-standard port number.
.SH TESTING THE INSTALLATION
If running the server as a daemon, execute it before proceeding. If
using a meta-daemon, either restart the system or kill and restart the
meta-daemon. Some versions of inetd will reread their configuration tables if
they receive a HUP signal.
To test whether the name server is running, start up a client
.I on a different machine
and see whether the desired name is now present. Alternatively, run
the nameserver
.I on a different machine
specifying "-L netbiosname", where "netbiosname" is the name you have
configured the test server to respond with. The command should respond
with success, and the IP number of the machine using the specified netbios
name. You may need the -B parameter on some systems. See the README
file for more information on testing nmbd.
.SH VERSION
This man page is (mostly) correct for version 1.9.00 of the Samba suite, plus some
of the recent patches to it. These notes will necessarily lag behind
development of the software, so it is possible that your version of
the server has extensions or parameter semantics that differ from or are not
covered by this man page. Please notify these to the address below for
rectification.
.SH SEE ALSO
.B inetd(8),
.B smbd(8),
.B smb.conf(5),
.B smbclient(1),
.B testparm(1),
.B testprns(1)
.SH DIAGNOSTICS
[This section under construction]
Most diagnostics issued by the server are logged in the specified log file. The
log file name is specified at compile time, but may be overridden on the
command line.
The number and nature of diagnostics available depends on the debug level used
by the server. If you have problems, set the debug level to 3 and peruse the
log files.
Most messages are reasonably self-explanatory. Unfortunately, at time of
creation of this man page the source code is still too fluid to warrant
describing each and every diagnostic. At this stage your best bet is still
to grep the source code and inspect the conditions that gave rise to the
diagnostics you are seeing.
.SH BUGS
None known.
.SH CREDITS
The original Samba software and related utilities were created by
Andrew Tridgell (samba-bugs@anu.edu.au). Andrew is also the Keeper
of the Source for this project.
This man page written by Karl Auer (Karl.Auer@anu.edu.au)
See
.B smb.conf(5) for a full list of contributors and details on how to
submit bug reports, comments etc.

190
docs/manpages/samba.7 Normal file
View File

@ -0,0 +1,190 @@
.TH SAMBA 7 29/3/95 Samba Samba
.SH NAME
Samba \- a LanManager like fileserver for Unix
.SH SYNOPSIS
.B Samba
.SH DESCRIPTION
The
.B Samba
software suite is a collection of programs that implements the SMB
protocol for unix systems. This protocol is sometimes also referred to
as the LanManager or Netbios protocol.
.SH COMPONENTS
The Samba suite is made up of several components. Each component is
described in a separate manual page. It is strongly recommended that
you read the documentation that comes with Samba and the manual pages
of those components that you use. If the manual pages aren't clear
enough then please send me a patch!
The smbd(8) daemon provides the file and print services to SMB clents,
such as Windows for Workgroups, Windows NT or LanManager. The
configuration file for this daemon is described in smb.conf(5).
The nmbd(8) daemon provides Netbios nameserving and browsing
support. It can also be run interactively to query other name service
daemons.
The smbclient(1) program implements a simple ftp-like client. This is
useful for accessing SMB shares on other compatible servers (such as
WfWg), and can also be used to allow a unix box to print to a printer
attached to any SMB server (such as a PC running WfWg).
The testparm(1) utility allows you to test your smb.conf(5)
configuration file.
The smbstatus(1) utility allows you to tell who is currently using the
smbd(8) server.
.SH AVAILABILITY
The Samba software suite is licensed under the Gnu Public License. A
copy of that license should have come with the package. You are
encouraged to distribute copies of the Samba suite, but please keep it
intact.
The latest version of the Samba suite can be obtained via anonymous
ftp from nimbus.anu.edu.au in the directory pub/tridge/samba/. It is
also available on several mirror sites worldwide.
You may also find useful information about Samba on the newsgroup
comp.protocols.smb and the Samba mailing list. Details on how to join
the mailing list are given in the README file that comes with Samba.
If you have access to a WWW viewer (such as Netscape or Mosaic) then
you will also find lots of useful information, including back issues
of the Samba mailing list, at http://lake.canberra.edu.au/pub/samba/
.SH AUTHOR
The main author of the Samba suite is Andrew Tridgell. He may be
contacted via e-mail at samba-bugs@anu.edu.au.
There have also been an enourmous number of contributors to Samba from
all over the world. A partial list of these contributors is included
in the CREDITS section below. The list is, however, badly out of
date. More up to date info may be obtained from the change-log that
comes with the Samba source code.
.SH CONTRIBUTIONS
If you wish to contribute to the Samba project, then I suggest you
join the Samba mailing list.
If you have patches to submit or bugs to report then you may mail them
directly to samba-bugs@anu.edu.au. Note, however, that due to the
enourmous popularity of this package I may take some time to repond to
mail. I prefer patches in "diff -u" format.
.SH CREDITS
Contributors to the project are (in alphabetical order by email address):
(NOTE: This list is very out of date)
Adams, Graham
(gadams@ddrive.demon.co.uk)
Allison, Jeremy
(jeremy@netcom.com)
Andrus, Ross
(ross@augie.insci.com)
Auer, Karl
(Karl.Auer@anu.edu.au)
Bogstad, Bill
(bogstad@cs.jhu.edu)
Boreham, Bryan
(Bryan@alex.com)
Boreham, David
(davidb@ndl.co.uk)
Butler, Michael
(imb@asstdc.scgt.oz.au)
???
(charlie@edina.demon.co.uk)
Chua, Michael
(lpc@solomon.technet.sg)
Cochran, Marc
(mcochran@wellfleet.com)
Dey, Martin N
(mnd@netmgrs.co.uk)
Errath, Maximilian
(errath@balu.kfunigraz.ac.at)
Fisher, Lee
(leefi@microsoft.com)
Foderaro, Sean
(jkf@frisky.Franz.COM)
Greer, Brad
(brad@cac.washington.edu)
Griffith, Michael A
(grif@cs.ucr.edu)
Grosen, Mark
(MDGrosen@spectron.COM)
????
(gunjkoa@dep.sa.gov.au)
Haapanen, Tom
(tomh@metrics.com)
Hench, Mike
(hench@cae.uwm.edu)
Horstman, Mark A
(mh2620@sarek.sbc.com)
Hudson, Tim
(tim.hudson@gslmail.mincom.oz.au)
Hulthen, Erik Magnus
(magnus@axiom.se)
???
(imb@asstdc.scgt.oz.au)
Iversen, Per Steinar
(iversen@dsfys1.fi.uib.no)
Kaara, Pasi
(ppk@atk.tpo.fi)
Karman, Merik
(merik@blackadder.dsh.oz.au)
Kiff, Martin
(mgk@newton.npl.co.uk)
Kiick, Chris
(cjkiick@flinx.b11.ingr.com)
Kukulies, Christoph
(kuku@acds.physik.rwth-aachen.de)
???
(lance@fox.com)
Lendecke, Volker
(lendecke@namu01.gwdg.de)
???
(lonnie@itg.ti.com)
Mahoney, Paul Thomas
(ptm@xact1.xact.com)
Mauelshagen, Heinz
(mauelsha@ez.da.telekom.de)
Merrick, Barry G
(bgm@atml.co.uk)
Mol, Marcel
(marcel@fanout.et.tudeflt.nl)
???
(njw@cpsg.com.au)
???
(noses@oink.rhein.de)
Owens, John
(john@micros.com)
Pierson, Jacques
(pierson@ketje.enet.dec.com)
Powell, Mark
(mark@scot1.ucsalf.ac.uk)
Reiz, Steven
(sreiz@aie.nl)
Schlaeger, Joerg
(joergs@toppoint.de)
S{rkel{, Vesa
(vesku@rankki.kcl.fi)
Tridgell, Andrew
(samba-bugs@anu.edu.au)
Troyer, Dean
(troyer@saifr00.ateng.az.honeywell.com)
Wakelin, Ross
(rossw@march.co.uk)
Wessels, Stefan
(SWESSELS@dos-lan.cs.up.ac.za)
Young, Ian A
(iay@threel.co.uk)
van der Zwan, Paul
(paulzn@olivetti.nl)

2719
docs/manpages/smb.conf.5 Normal file

File diff suppressed because it is too large Load Diff

1133
docs/manpages/smbclient.1 Normal file

File diff suppressed because it is too large Load Diff

407
docs/manpages/smbd.8 Normal file
View File

@ -0,0 +1,407 @@
.TH SMBD 8 17/1/1995 smbd smbd
.SH NAME
smbd \- provide SMB (aka LanManager) services to clients
.SH SYNOPSIS
.B smbd
[
.B -D
] [
.B -a
] [
.B -d
.I debuglevel
] [
.B -l
.I log file
] [
.B -p
.I port number
] [
.B -O
.I socket options
] [
.B -s
.I configuration file
]
.SH DESCRIPTION
This program is part of the Samba suite.
.B smbd
is a server that can provide most SMB services. The
server provides filespace and printer services to clients using the SMB
protocol. This is compatible with the LanManager protocol, and can
service LanManager clients.
An extensive description of the services that the server can provide is given
in the man page for the configuration file controlling the attributes of those
services (see
.B smb.conf(5)). This man page will not describe the services, but
will concentrate on the administrative aspects of running the server.
Please note that there are significant security implications to running this
server, and
.B smb.conf(5) should be regarded as mandatory reading before proceeding with
installation.
A session is created whenever a client requests one. Each client gets a copy
of the server for each session. This copy then services all connections made
by the client during that session. When all connections from its client are
are closed, the copy of the server for that client terminates.
The configuration file is automatically reloaded if it changes. You
can force a reload by sending a SIGHUP to the server.
.SH OPTIONS
.B -D
.RS 3
If specified, this parameter causes the server to operate as a daemon. That is,
it detaches itself and runs in the background, fielding requests on the
appropriate port.
By default, the server will NOT operate as a daemon.
.RE
.B -a
.RS 3
If this parameter is specified, the log files will be overwritten with each
new connection. By default, the log files will be appended to.
.RE
.B -d
.I debuglevel
.RS 3
debuglevel is an integer from 0 to 5.
The default value if this parameter is not specified is zero.
The higher this value, the more detail will be logged to the log files about
the activities of the server. At level 0, only critical errors and serious
warnings will be logged. Level 1 is a reasonable level for day to day running
- it generates a small amount of information about operations carried out.
Levels above 1 will generate considerable amounts of log data, and should
only be used when investigating a problem. Levels above 3 are designed for
use only by developers and generate HUGE amounts of log data, most of which
is extremely cryptic.
.RE
.B -l
.I log file
.RS 3
If specified,
.I logfile
specifies a base filename into which operational data from the running server
will be logged.
The default base name is specified at compile time.
The base name is used to generate actual log file names. For example, if the
name specified was "log", the following files would be used for log data:
.RS 3
log.debug (containing debugging information)
log.in (containing inbound transaction data)
log.out (containing outbound transaction data)
.RE
The log files generated are never removed by the server.
.RE
.B -O
.I socket options
.RS 3
See the socket options section of smb.conf(5) for details
.RE
.B -p
.I port number
.RS 3
port number is a positive integer value.
The default value if this parameter is not specified is 139.
This number is the port number that will be used when making connections to
the server from client software. The standard (well-known) port number for the
server is 139, hence the default. If you wish to run the server as an ordinary
user rather than as root, most systems will require you to use a port number
greater than 1024 - ask your system administrator for help if you are in this
situation.
This parameter is not normally specified except in the above situation.
.RE
.B -s
.I configuration file
.RS 3
The default configuration file name is determined at compile time.
The file specified contains the configuration details required by the server.
The information in this file includes server-specific information such as
what printcap file to use, as well as descriptions of all the services that the
server is to provide. See
.B smb.conf(5) for more information.
.RE
.SH FILES
.B /etc/inetd.conf
.RS 3
If the server is to be run by the inetd meta-daemon, this file must contain
suitable startup information for the meta-daemon. See the section
"INSTALLATION" below.
.RE
.B /etc/rc
.RS 3
(or whatever initialisation script your system uses)
If running the server as a daemon at startup, this file will need to contain
an appropriate startup sequence for the server. See the section "INSTALLATION"
below.
.RE
.B /etc/services
.RS 3
If running the server via the meta-daemon inetd, this file must contain a
mapping of service name (eg., netbios-ssn) to service port (eg., 139) and
protocol type (eg., tcp). See the section "INSTALLATION" below.
.RE
.B /usr/local/smb/smb.conf
.RS 3
This file describes all the services the server is to make available to
clients. See
.B smb.conf(5) for more information.
.RE
.RE
.SH LIMITATIONS
On some systems smbd cannot change uid back to root after a setuid() call.
Such systems are called "trapdoor" uid systems. If you have such a system,
you will be unable to connect from a client (such as a PC) as two different
users at once. Attempts to connect the second user will result in "access
denied" or similar.
.SH ENVIRONMENT VARIABLES
.B PRINTER
.RS 3
If no printer name is specified to printable services, most systems will
use the value of this variable (or "lp" if this variable is not defined)
as the name of the printer to use. This is not specific to the server,
however.
.RE
.SH INSTALLATION
The location of the server and its support files is a matter for individual
system administrators. The following are thus suggestions only.
It is recommended that the server software be installed under the
/usr/local hierarchy, in a directory readable by all, writeable only
by root. The server program itself should be executable by all, as
users may wish to run the server themselves (in which case it will of
course run with their privileges). The server should NOT be
setuid. On some systems it may be worthwhile to make smbd setgid to an
empty group. This is because some systems may have a security hole where
daemon processes that become a user can be attached to with a
debugger. Making the smbd file setgid to an empty group may prevent
this hole from being exploited. This secrity hole and the suggested
fix has only been confirmed on Linux at the time this was written. It
is possible that this hole only exists in Linux, as testing on other
systems has thus far shown them to be immune.
The server log files should be put in a directory readable and writable only
by root, as the log files may contain sensitive information.
The configuration file should be placed in a directory readable and writable
only by root, as the configuration file controls security for the services
offered by the server. The configuration file can be made readable by all if
desired, but this is not necessary for correct operation of the server and
is not recommended. A sample configuration file "smb.conf.sample" is supplied
with the source to the server - this may be renamed to "smb.conf" and
modified to suit your needs.
The remaining notes will assume the following:
.RS 3
smbd (the server program) installed in /usr/local/smb
smb.conf (the configuration file) installed in /usr/local/smb
log files stored in /var/adm/smblogs
.RE
The server may be run either as a daemon by users or at startup, or it may
be run from a meta-daemon such as inetd upon request. If run as a daemon, the
server will always be ready, so starting sessions will be faster. If run from
a meta-daemon some memory will be saved and utilities such as the tcpd
TCP-wrapper may be used for extra security.
When you've decided, continue with either "RUNNING THE SERVER AS A DAEMON" or
"RUNNING THE SERVER ON REQUEST".
.SH RUNNING THE SERVER AS A DAEMON
To run the server as a daemon from the command line, simply put the "-D" option
on the command line. There is no need to place an ampersand at the end of the
command line - the "-D" option causes the server to detach itself from the
tty anyway.
Any user can run the server as a daemon (execute permissions permitting, of
course). This is useful for testing purposes, and may even be useful as a
temporary substitute for something like ftp. When run this way, however, the
server will only have the privileges of the user who ran it.
To ensure that the server is run as a daemon whenever the machine is started,
and to ensure that it runs as root so that it can serve multiple clients, you
will need to modify the system startup files. Wherever appropriate (for
example, in /etc/rc), insert the following line, substituting
port number, log file location, configuration file location and debug level as
desired:
.RS 3
/usr/local/smb/smbd -D -l /var/adm/smblogs/log -s /usr/local/smb/smb.conf
.RE
(The above should appear in your initialisation script as a single line.
Depending on your terminal characteristics, it may not appear that way in
this man page. If the above appears as more than one line, please treat any
newlines or indentation as a single space or TAB character.)
If the options used at compile time are appropriate for your system, all
parameters except the desired debug level and "-D" may be omitted. See the
section "OPTIONS" above.
.SH RUNNING THE SERVER ON REQUEST
If your system uses a meta-daemon such as inetd, you can arrange to have the
smbd server started whenever a process attempts to connect to it. This requires
several changes to the startup files on the host machine. If you are
experimenting as an ordinary user rather than as root, you will need the
assistance of your system administrator to modify the system files.
You will probably want to set up the name server
.B nmbd
at the same time as
the smbd - refer to the man page
.B nmbd(8).
First, ensure that a port is configured in the file /etc/services. The
well-known port 139 should be used if possible, though any port may be used.
Ensure that a line similar to the following is in /etc/services:
.RS 3
netbios-ssn 139/tcp
.RE
Note for NIS/YP users - you may need to rebuild the NIS service maps rather
than alter your local /etc/services file.
Next, put a suitable line in the file /etc/inetd.conf (in the unlikely event
that you are using a meta-daemon other than inetd, you are on your own). Note
that the first item in this line matches the service name in /etc/services.
Substitute appropriate values for your system in this line (see
.B inetd(8)):
.RS 3
netbios-ssn stream tcp nowait root /usr/local/smb/smbd -d1
-l/var/adm/smblogs/log -s/usr/local/smb/smb.conf
.RE
(The above should appear in /etc/inetd.conf as a single line. Depending on
your terminal characteristics, it may not appear that way in this man page.
If the above appears as more than one line, please treat any newlines or
indentation as a single space or TAB character.)
Note that there is no need to specify a port number here, even if you are
using a non-standard port number.
Lastly, edit the configuration file to provide suitable services. To start
with, the following two services should be all you need:
.RS 3
[homes]
.RS 3
writable = yes
.RE
[printers]
.RS 3
writable = no
printable = yes
path = /tmp
public = yes
.RE
.RE
This will allow you to connect to your home directory and print to any printer
supported by the host (user privileges permitting).
.SH TESTING THE INSTALLATION
If running the server as a daemon, execute it before proceeding. If
using a meta-daemon, either restart the system or kill and restart the
meta-daemon. Some versions of inetd will reread their configuration tables if
they receive a HUP signal.
If your machine's name is "fred" and your name is "mary", you should now be
able to connect to the service "\\\\fred\\mary".
To properly test and experiment with the server, we recommend using the
smbclient program (see
.B smbclient(1)).
.SH VERSION
This man page is (mostly) correct for version 1.9.00 of the Samba suite, plus some
of the recent patches to it. These notes will necessarily lag behind
development of the software, so it is possible that your version of
the server has extensions or parameter semantics that differ from or are not
covered by this man page. Please notify these to the address below for
rectification.
.SH SEE ALSO
.B hosts_access(5),
.B inetd(8),
.B nmbd(8),
.B smb.conf(5),
.B smbclient(1),
.B testparm(1),
.B testprns(1)
.SH DIAGNOSTICS
[This section under construction]
Most diagnostics issued by the server are logged in a specified log file. The
log file name is specified at compile time, but may be overridden on the
command line.
The number and nature of diagnostics available depends on the debug level used
by the server. If you have problems, set the debug level to 3 and peruse the
log files.
Most messages are reasonably self-explanatory. Unfortunately, at time of
creation of this man page the source code is still too fluid to warrant
describing each and every diagnostic. At this stage your best bet is still
to grep the source code and inspect the conditions that gave rise to the
diagnostics you are seeing.
.SH BUGS
None known.
.SH CREDITS
The original Samba software and related utilities were created by
Andrew Tridgell (samba-bugs@anu.edu.au). Andrew is also the Keeper
of the Source for this project.
This man page written by Karl Auer (Karl.Auer@anu.edu.au)
See
.B smb.conf(5) for a full list of contributors and details on how to
submit bug reports, comments etc.

70
docs/manpages/smbrun.1 Normal file
View File

@ -0,0 +1,70 @@
.TH SMBRUN 1 17/1/1995 smbrun smbrun
.SH NAME
smbrun \- interface program between smbd and external programs
.SH SYNOPSIS
.B smbrun
.I shell-command
.SH DESCRIPTION
This program is part of the Samba suite.
.B smbrun
is a very small 'glue' program, which runs shell commands for
the
.B smbd
daemon (see
.B smbd(8)).
It first changes to the highest effective user and group ID that it can,
then runs the command line provided using the system() call. This program is
necessary to allow some operating systems to run external programs as non-root.
.SH OPTIONS
.I shell-command
.RS 3
The shell command to execute.
The command should have a fully-qualified path.
.RE
.SH ENVIRONMENT VARIABLES
The PATH variable set for the environment in which
.B smbrun
is executed will affect what executables are located and executed if a
fully-qualified path is not given in the command.
.SH INSTALLATION
The location of the server and its support files is a matter for individual
system administrators. The following are thus suggestions only.
It is recommended that the
.B smbrun
program be installed under the /usr/local hierarchy, in a directory readable
by all, writeable only by root. The program should be executable by all.
The program should NOT be setuid or setgid!
.SH VERSION
This man page is (mostly) correct for version 1.9.00 of the Samba suite, plus some
of the recent patches to it. These notes will necessarily lag behind
development of the software, so it is possible that your version of
the program has extensions or parameter semantics that differ from or are not
covered by this man page. Please notify these to the address below for
rectification.
.SH SEE ALSO
.B smbd(8),
.B smb.conf(8)
.SH DIAGNOSTICS
If smbrun cannot be located or cannot be executed by
.B smbd
then appropriate messages will be found in the smbd logs. Other diagnostics are
dependent on the shell-command being run. It is advisable for your shell
commands to issue suitable diagnostics to aid trouble-shooting.
.SH BUGS
None known.
.SH CREDITS
The original Samba software and related utilities were created by
Andrew Tridgell (samba-bugs@anu.edu.au). Andrew is also the Keeper
of the Source for this project.
This man page was written by Karl Auer (Karl.Auer@anu.edu.au)
See
.B smb.conf(5) for a full list of contributors and details of how to
submit bug reports, comments etc.

52
docs/manpages/smbstatus.1 Normal file
View File

@ -0,0 +1,52 @@
.TH SMBSTATUS 1 17/1/1995 smbstatus smbstatus
.SH NAME
smbstatus \- report on current Samba connections
.SH SYNOPSIS
.B smbstatus
[-d]
[-s
.I configuration file
]
.SH DESCRIPTION
This program is part of the Samba suite.
.B smbstatus
is a very simple program to list the current Samba connections
Just run the program and the output is self explanatory. You can offer
a configuration filename to override the default. The default is
CONFIGFILE from the Makefile.
Option
.I -d
gives verbose output.
.I -p
print a list of smbd processes and exit. Useful for scripting.
.SH ENVIRONMENT VARIABLES
Not applicable.
.SH INSTALLATION
The location of the server and its support files is a matter for individual
system administrators. The following are thus suggestions only.
It is recommended that the
.B smbstatus
program be installed under the /usr/local hierarchy, in a directory readable
by all, writeable only by root. The program itself should be executable by all.
.SH VERSION
This man page is (mostly) correct for version 1.9.00 of the Samba suite, plus some
of the recent patches to it. These notes will necessarily lag behind
development of the software, so it is possible that your version of
the program has extensions or parameter semantics that differ from or are not
covered by this man page. Please notify these to the address below for
rectification.
.SH SEE ALSO
.B smb.conf(5),
.B smbd(8)
See
.B smb.conf(5) for a full list of contributors and details on how to
submit bug reports, comments etc.

167
docs/manpages/smbtar.1 Normal file
View File

@ -0,0 +1,167 @@
.TH SMBTAR 1 18/2/96 smbtar smbtar
.SH NAME
smbtar \- shell script for backing up SMB shares directly to UNIX tape drive
.SH SYNOPSIS
.B smbtar
.B \-s
.I server
.B [ \-p
.I password
.B ]
.B [ \-x
.I service
.B ]
.B [ \-X ]
.B [ \-d
.I directory
.B ]
.B [ \-u
.I user
.B ]
.B [ \-t
.I tape
.B ]
.B [ \-b
.I blocksize
.B ]
.B [ \-N
.I filename
.B ]
.B [ \-i ]
.B [ \-r ]
.B [ \-l ]
.B [ \-v ]
.I filenames...
.SH DESCRIPTION
This program is an extension to the Samba suite.
.B smbtar
is a very small shell script on top of smbclient, which dumps SMB
shares directly to tape.
.SH OPTIONS
.B \-s
.I server
.RS 3
The PC that the share resides upon.
.RE
.B \-x
.I service
.RS 3
The share name on the PC to connect to. Default:
.I backup.
.RE
.B \-X
.RS 3
Exclude mode. Exclude
.I filenames...
from tar create or restore.
.RE
.B \-d
.I directory
.RS 3
Change to initial
.I directory
before restoring / backing up files.
.RE
.B \-v
.RS 3
Verbose mode.
.RE
.B \-p
.I password
.RS 3
The password to use to access a share. Default: none
.RE
.B \-u
.I user
.RS 3
The user id to connect as. Default: UNIX login name.
.RE
.B \-t
.I tape
.RS 3
Tape device. May be regular file or tape device. Default: Tape environmental
variable; if not set, a file called
.I tar.out.
.RE
.B \-b
.I blocksize
.RS 3
Blocking factor. Defaults to 20. See tar(1) for a fuller explanation.
.RE
.B \-N
.I filename
.RS 3
Backup only files newer than filename. Could be used (for example) on a log
file to implement incremental backups.
.RE
.B \-i
.RS 3
Incremental mode; tar files are only backed up if they have the
archive bit set. The archive bit is reset after each file is read.
.RE
.B \-r
.RS 3
Restore. Files are restored to the share from the tar file.
.RE
.B \-l
.RS 3
Debug level. Corresponds to -d flag on smbclient(1).
.RE
.SH ENVIRONMENT VARIABLES
The TAPE variable specifies the default tape device to write to. May
be overidden with the -t option.
.SH BUGS
The smbtar script has different options from ordinary tar and tar
called from smbclient.
.SH CAVEATS
Sites that are more careful about security may not like the way
the script handles PC passwords. Backup and restore work on entire shares,
should work on file lists.
.SH VERSION
This man page is correct for version 1.9.15p8 of the Samba suite.
.SH SEE ALSO
.B smbclient
(8),
.B smb.conf
(8)
.SH DIAGNOSTICS
See diagnostics for
.B smbclient
command.
.SH CREDITS
The original Samba software and related utilities were created by
Andrew Tridgell (samba-bugs@anu.edu.au). Andrew is also the Keeper
of the Source for this project.
Ricky Poulten (poultenr@logica.co.uk) wrote the tar extension and this
man page. The smbtar script was heavily rewritten and improved by
Martin Kraemer <Martin.Kraemer@mch.sni.de>. Many thanks to everyone
who suggested extensions, improvements, bug fixes, etc.
See
.B smb.conf
(5) for a full list of contributors and details of how to submit bug reports,
comments etc.

104
docs/manpages/testparm.1 Normal file
View File

@ -0,0 +1,104 @@
.TH TESTPARM 1 17/1/1995 testparm testparm
.SH NAME
testparm \- check an smbd configuration file for internal correctness
.SH SYNOPSIS
.B testparm
[
.I configfilename
[
.I hostname
.I hostIP
]
]
.SH DESCRIPTION
This program is part of the Samba suite.
.B testparm
is a very simple test program to check an
.B smbd
configuration
file for internal correctness. If this program reports no problems, you can use
the configuration file with confidence that smbd will successfully
load the configuration file.
Note that this is NOT a guarantee that the services specified in the
configuration file will be available or will operate as expected.
If the optional host name and host IP address are specified on the
command line, this test program will run through the service entries
reporting whether the specified host has access to each service.
.SH OPTIONS
.I configfilename
.RS 3
This is the name of the configuration file to check.
.RE
.I hostname
.RS 3
This is the name of the host to check access on.
If this parameter is supplied, the
.I hostIP
parameter must also be supplied, or strange things may happen.
.RE
.I hostIP
.RS 3
This is the IP number of the host specified in the previous parameter.
This number must be supplied if the
.I hostname
parameter is supplied, or strange things may happen.
.RE
.SH FILES
.B smb.conf
.RS 3
This is usually the name of the configuration file used by smbd.
.RE
.SH ENVIRONMENT VARIABLES
Not applicable.
.SH INSTALLATION
The location of the server and its support files is a matter for individual
system administrators. The following are thus suggestions only.
It is recommended that the
.B testparm
program be installed under the /usr/local hierarchy, in a directory readable
by all, writeable only by root. The program itself should be executable by all.
The program should NOT be setuid or setgid!
.SH VERSION
This man page is (mostly) correct for version 1.9.00 of the Samba suite, plus some
of the recent patches to it. These notes will necessarily lag behind
development of the software, so it is possible that your version of
the program has extensions or parameter semantics that differ from or are not
covered by this man page. Please notify these to the address below for
rectification.
.SH SEE ALSO
.B smb.conf(5),
.B smbd(8)
.SH DIAGNOSTICS
The program will issue a message saying whether the configuration file loaded
OK or not. This message may be preceded by errors and warnings if the file
did not load. If the file was loaded OK, the program then dumps all known
service details to stdout.
If a host name is specified but no host IP number, all bets are off.
Other messages are self-explanatory.
.SH BUGS
None known.
.SH CREDITS
The original Samba software and related utilities were created by
Andrew Tridgell (samba-bugs@anu.edu.au). Andrew is also the Keeper
of the Source for this project.
The testparm program and this man page were written by Karl Auer
(Karl.Auer@anu.edu.au)
See
.B samba(7) for a full list of contributors and details on how to
submit bug reports, comments etc.

107
docs/manpages/testprns.1 Normal file
View File

@ -0,0 +1,107 @@
.TH TESTPRNS 1 17/1/1995 testprns testprns
.SH NAME
testprns \- check printer name for validity with smbd
.SH SYNOPSIS
.B testprns
.I printername
[
.I printcapname
]
.SH DESCRIPTION
This program is part of the Samba suite.
.B testprns
is a very simple test program to determine whether a given
printer name is valid for use in a service to be provided by
.B smbd.
"Valid" in this context means "can be found in the printcap specified". This
program is very stupid - so stupid in fact that it would be wisest to always
specify the printcap file to use.
.SH OPTIONS
.I printername
.RS 3
The printer name to validate.
Printer names are taken from the first field in each record in the printcap
file, single printer names and sets of aliases separated by vertical bars
("|") are recognised. Note that no validation or checking of the printcap
syntax is done beyond that required to extract the printer name. It may
be that the print spooling system is more forgiving or less forgiving
than
.B testprns
however if
.B testprns
finds the printer then smbd should do as well.
.RE
.I printcapname
.RS 3
This is the name of the printcap file to search for the given printer name
in.
If no printcap name is specified,
.B testprns
will attempt to scan the printcap file specified at compile time
(PRINTCAP_NAME).
.RE
.SH FILES
.B /etc/printcap
.RS 3
This is usually the default printcap file to scan. See
.B printcap(5)).
.RE
.SH ENVIRONMENT VARIABLES
Not applicable.
.SH INSTALLATION
The location of the server and its support files is a matter for individual
system administrators. The following are thus suggestions only.
It is recommended that the
.B testprns
program be installed under the /usr/local hierarchy, in a directory readable
by all, writeable only by root. The program should be executable by all.
The program should NOT be setuid or setgid!
.SH VERSION
This man page is (mostly) correct for version 1.9.00 of the Samba suite, plus some
of the recent patches to it. These notes will necessarily lag behind
development of the software, so it is possible that your version of
the program has extensions or parameter semantics that differ from or are not
covered by this man page. Please notify these to the address below for
rectification.
.SH SEE ALSO
.B printcap(5),
.B smbd(8),
.B smbclient(1)
.SH DIAGNOSTICS
If a printer is found to be valid, the message "Printer name <printername> is
valid" will be displayed.
If a printer is found to be invalid, the message "Printer name <printername>
is not valid" will be displayed.
All messages that would normally be logged during operation of smbd are
logged by this program to the file
.I test.log
in the current directory. The program runs at debuglevel 3, so quite extensive
logging information is written. The log should be checked carefully for errors
and warnings.
Other messages are self-explanatory.
.SH BUGS
None known.
.SH CREDITS
The original Samba software and related utilities were created by
Andrew Tridgell (samba-bugs@anu.edu.au). Andrew is also the Keeper
of the Source for this project.
The testprns program and this man page were written by Karl Auer
(Karl.Auer@anu.edu.au)
See
.B samba(7) for a full list of contributors and details of how to
submit bug reports, comments etc.

26
docs/samba.lsm Normal file
View File

@ -0,0 +1,26 @@
Begin2
Title = Samba
Version = 1.8.0
Desc1 = Samba is a SMB based file and print server for unix. It
Desc2 = provides access to unix file and print services from
Desc3 = SMB compatible clients such as WinNT, WfWg, OS/2
Desc4 = and Pathworks. It also includes a ftp-style unix client
Desc5 = and a netbios nameserver.
Author = Andrew Tridgell
AuthorEmail = samba-bugs@anu.edu.au
Maintainer = Andrew Tridgell
MaintEmail = samba-bugs@anu.edu.au
Site1 = nimbus.anu.edu.au
Path1 = pub/tridge/samba/
File1 = samba-latest.tar.gz
FileSize1 = 200K
Required1 = Ansi-C compiler and a TCP/IP network.
CopyPolicy1 = GNU Public License
Keywords = LanManager, SMB, Networking
Comment1 = To join the Samba mailing list send mail to
Comment2 = listproc@listproc.anu.edu.au with a body of
Comment3 = "subscribe samba Your Name"
Entered = October 1994
EnteredBy = Andrew Tridgell
End

145
docs/textdocs/BROWSING.txt Normal file
View File

@ -0,0 +1,145 @@
BROWSING
========
Samba now fully supports browsing. The browsing is supported by nmbd
and is also controlled by options in the smb.conf file (see
smb.conf(5)).
Samba can act as a browse master for a workgroup, but currently cannot
act as a domain controller. The ability to be a domain controller will
be added in a later version.
To get browsing to work you need to run nmbd as usual, but will need
to use the "workgroup" option in smb.conf to control what workgroup
Samba becomes a part of.
The -G option is most useful for simple setups where Samba is browsable
in only one workgroup. In more complex cases the lmhosts file is
better.
Be very careful setting up your lmhosts file. An incorrectly setup
lmhosts file can have disasterous results for your net!
A simple lmhosts file might be:
# This is a simple lmhosts file
#
# This is a host alias. Anyone querying this name
# will get the specified IP
192.0.2.17 SMBDATA
#
# first put ourselves in workgroup MYGROUP using
# our own net address
0.0.0.0 MYGROUP G
Note in the above that I overrode what workgroup Samba is in using the
G flag. Also note that the 0.0.0.0 address is used, which will be
automatically replaced with the broadcast address for groups, and with
the local IP address for other entries.
Samba also has a useful option for a Samba server to offer itself for
browsing on another subnet.
This works by the lmhosts file specifying a broadcast address on the
other network to use to find a browse master for the workgroup.
For example if you wanted yourself to appear in the workgroup STAFF on
the network which has a broadcast of 192.0.3.255 then this entry would
do the trick:
# put ourselves in the STAFF workgroup on the other subnet
192.0.3.255 STAFF G
Notice the G at the end! It is very important you include this as this
entry without the G could cause a broadcast storm!
If something doesn't work then hopefully the log.nmb file will
help you track down the problem. Try a debug level of 2 or 3 for
finding problems.
Note that if it doesn't work for you, then you should still be able to
type the server name as \\SERVER in filemanager then hit enter and
filemanager should display the list of available shares.
Some people find browsing fails because they don't have the global
"guest account" set to a valid account. Remember that the IPC$
connection that lists the shares is done as guest, and thus you must
have a valid guest account.
Also, a lot of people are getting bitten by the problem of too many
parameters on the command line of nmbd in inetd.conf. This trick is to
not use spaces between the option and the parameter (eg: -d2 instead
of -d 2), and to not use the -B and -N options. New versions of nmbd
are now far more likely to correctly find your broadcast and network
addess, so in most cases these aren't needed.
The other big problem people have is that their broadcast address,
netmask or IP address is wrong (specified with the -B, -N and -I
options to nmbd).
FORCING SAMBA TO BE THE MASTER
==============================
Who becomes the "master browser" is determined by an election process
using broadcasts. Each election packet contains a number of parameters
which determine what precedence (bias) a host should have in the
election. By default Samba uses a very low precedence and thus loses
elections to just about anyone else.
If you want Samba to win elections then just set the "os level" global
option in smb.conf to a higher number. It defaults to 0. Using 33
would make it win all elections over every other system (except other
samba systems!)
A "os level" of 2 would make it beat WfWg and Win95, but not NTAS. A
NTAS domain controller uses level 32.
The maximum os level is 255
MAKING SAMBA THE DOMAIN MASTER
==============================
The domain master is responsible for collating the browse lists of
multiple subnets so that browsing can occur between subnets. You can
make samba act as the domain master by setting "domain master = yes"
in smb.conf. By default it will not be a domain master.
When samba is the domain master and the master browser it will listen
for master announcements from other subnets and then contact them to
synchronise browse lists.
If you want samba to be the domain master then I suggest you also set
the "os level" high enough to make sure it wins elections.
NOTIFYING THE DOMAIN CONTROLLER
===============================
If you have a domain controller for the domain which Samba is a part
of then you should add the line "domain controller = address" to
smb.conf. "address" can either be a name available via DNS or a IP
address or a broadcast address. If it is a broadcast address then
Samba will look for a domain controller on that network.
When Samba is the master browser it will regularly contact the domain
controller to synchronise browse lists.
NOTE ABOUT BROADCAST ADDRESSES
==============================
If your network uses a "0" based broadcast address (for example if it
ends in a 0) then you will strike problems. Windows for Workgroups
does not seem to support a 0's broadcast and you will probably find
that browsing and name lookups won't work.
You have a few options:
1) change to a 1's broadcast on your unix server. These often end in
.255 (check with your local network guru for details)
2) set the nmbd broadcast to a 1's based address on the command line using
the -B option. This only works if your network setup listens on both
0s and 1s based broadcasts. The -B option can only control what
address it sends to, not what it listens on.

123
docs/textdocs/BUGS.txt Normal file
View File

@ -0,0 +1,123 @@
This file describes how to report Samba bugs.
>> The email address for bug reports is samba-bugs@anu.edu.au <<
(NOTE: This mail may not be in place yet. If you have troubles with it
then use samba-bugs@arvidsjaur.anu.edu.au)
Please take the time to read this file before you submit a bug
report. Also, please see if it has changed between releases, as I
may be changing the bug reporting mechanism sometime soon.
Please also do as much as you can yourself to help track down the
bug. I only develop Samba in my spare time and I receive far more mail
about it than I can possibly answer, so you have a much higher chance
of an answer and a fix if you send me a "developer friendly" bug
report that lets me fix it fast.
Do not assume that if you post the bug to the comp.protocols.smb
newsgroup that I will read it. I do read all postings to the samba
mailing list (see the README). If you suspect that your problem is not
a bug but a configuration problem then it is better to send it to the
Samba mailing list, as there are (at last count) 1900 other users on
that list that may be able to help you.
You may also like to look though the recent mailing list archives,
which are conveniently accessible on the Samba web pages
at http://lake.canberra.edu.au/pub/samba/
GENERAL INFO
------------
Before submitting a bug report check your config for silly
errors. Look in your log files for obvious messages that tell you that
you've misconfigured something and run testparm to test your config
file for correct syntax.
If you include part of a log file with your bug report then be sure to
annotate it with exactly what you were doing on the client at the
time, and exactly what the results were.
DEBUG LEVELS
------------
If the bug has anything to do with Samba behaving incorrectly as a
server (like refusing to open a file) then the log files will probably
be very useful. Depending on the problem a log level of between 3 and
10 showing the problem may be appropriate. A higher level givesmore
detail, but may use too much disk space.
To set the debug level use "log level =" in your smb.conf. You may
also find it useful to set the log level higher for just one machine
and keep separate logs for each machine. To do this use:
log file = /usr/local/samba/lib/log.%m
include = /usr/local/samba/lib/smb.conf.%m
then create a file "/usr/local/samba/lib/smb.conf.machine" where
"machine" is the name of the client you wish to debug. In that file
put any smb.conf commands you want, for example "log level=" may be
useful. This also allows you to experiment with different security
systems, protocol levels etc on just one machine.
INTERNAL ERRORs
---------------
If you get a "INTERNAL ERROR" message in your log files it means that
Samba got an unexpected signal while running. It is probably a
segmentation fault and almost certainly means a bug in Samba (unless
you have faulty hardware or system software)
If the message came from smbd then it will probably be accompanied by
a message which details the last SMB message received by smbd. This
info is often very useful in tracking down the problem so please
include it in your bug report.
You should also detail how to reproduce the problem, if
possible. Please make this reasonably detailed.
You may also find that a core file appeared in a "corefiles"
subdirectory of the directory where you keep your samba log
files. This file is the most useful tool for tracking down the bug. To
use it you do this:
gdb smbd core
adding appropriate paths to smbd and core so gdb can find them. If you
don't have gdb then try "dbx". Then within the debugger use the
command "where" to give a stack trace of where the problem
occurred. Include this in your mail.
If you known any assembly language then do a "disass" of the routine
where the problem occurred (if its in a library routine then
disassemble the routine that called it) and try to work out exactly
where the problem is by looking at the surrounding code. Even if you
don't know assembly then incuding this info in the bug report can be
useful.
ATTACHING TO A RUNNING PROCESS
------------------------------
Unfortunately some unixes (in particular some recent linux kernels)
refuse to dump a core file if the task has changed uid (which smbd
does often). To debug with this sort of system you could try to attach
to the running process using "gdb smbd PID" where you get PID from
smbstatus. Then use "c" to continue and try to cause the core dump
using the client. The debugger should catch the fault and tell you
where it occurred.
PATCHES
-------
The best sort of bug report is one that includes a fix! If you send me
patches please use "diff -u" format if your version of diff supports
it, otherwise use "diff -c4". Make sure your do the diff against a
clean version of the source and let me know exactly what version you
used.

237
docs/textdocs/DIAGNOSIS.txt Normal file
View File

@ -0,0 +1,237 @@
DIAGNOSING YOUR SAMBA SERVER
============================
This file contains a list of tests you can perform to validate your
Samba server. It also tells you what the likely cause of the problem
is if it fails any one of these steps. If it passes all these tests
then it is probably working fine.
You should do ALL the tests, in the order shown. I have tried to
carefully choose them so later tests only use capabilities verified in
the earlier tests.
I would welcome additions to this set of tests. Please mail them to
samba-bugs@anu.edu.au
If you send me an email saying "it doesn't work" and you have not
followed this test procedure then you should not be surprised if I
ignore your email.
ASSUMPTIONS
-----------
In all of the tests I assume you have a Samba server called BIGSERVER
and a PC called ACLIENT. I also assume the PC is running windows for
workgroups with a recent copy of the microsoft tcp/ip stack. The
procedure is similar for other types of clients.
I also assume you know the name of a available share in your
smb.conf. I will assume this share is called "tmp". You can add a
"tmp" share like by adding the following to smb.conf:
[tmp]
comment = temporary files
path = /tmp
read only = yes
THESE TESTS ASSUME VERSION 1.9.15 OR LATER OF THE SAMBA SUITE. SOME
COMMANDS SHOWN DID NOT EXIST IN EARLIER VERSIONS
TEST 1:
-------
run the command "testparm". If it reports any errors then your
smb.conf configuration file is faulty.
TEST 2:
-------
run the command "ping BIGSERVER" from the PC and "ping ACLIENT" from
the unix box. If you don't get a valid response then your TCP/IP
software is not correctly installed.
Note that you will need to start a "dos prompt" window on the PC to
run ping.
If you get a message saying "host not found" or similar then your DNS
software or /etc/hosts file is not correctly setup. It is possible to
run samba without DNS entries for the server and client, but I assume
you do have correct entries for the remainder of these tests.
TEST 3:
-------
run the command "smbclient -L BIGSERVER -U%" on the unix box. You
should get a list of available shares back.
If you get a error message containing the string "Bad password" then
you probably have either an incorrect "hosts allow", "hosts deny" or
"valid users" line in your smb.conf, or your guest account is not
valid. Check what your guest account is using "testparm" and
temporarily remove any "hosts allow", "hosts deny", "valid users" or
"invalid users" lines.
If you get a "connection refused" response then the smbd server could
not be run. If you installed it in inetd.conf then you probably edited
that file incorrectly. If you installed it as a daemon then check that
it is running, and check that the netbios-ssn port is in a LISTEN
state using "netstat -a".
If you get a "session request failed" then the server refused the
connection. If it says "your server software is being unfriendly" then
its probably because you have invalid command line parameters to smbd,
or a similar fatal problem with the initial startup of smbd. Also
check your config file for syntax errors with "testparm".
TEST 4:
-------
run the command "nmblookup -B BIGSERVER __SAMBA__". You should get the
IP address of your Samba server back.
If you don't then nmbd is incorrectly installed. Check your inetd.conf
if yu run it from there, or that the daemon is running and listening
to udp port 137.
One common problem is that many inetd implementations can't take many
parameters on the command line. If this is the case then create a
one-line script that contains the right parameters and run that from
inetd.
TEST 5:
-------
run the command "nmblookup -B ACLIENT '*'"
You should get the PCs IP address back. If you don't then the client
software on the PC isn't installed correctly, or isn't started, or you
got the name of the PC wrong. Note that you probably won't get a "node
status response" from the PC due to a bug in the microsoft netbios
nameserver implementation (it responds to the wrong port number).
TEST 6:
-------
run the command "nmblookup -d 2 '*'"
This time we are trying the same as the previous test but are trying
it via a broadcast to the default broadcast address. A number of
Netbios/TCPIP hosts on the network should respond, although Samba may
not catch all of the responses in the short time it listens. You
should see "got a positive name query response" messages from several
hosts.
If this doesn't give a similar result to the previous test then
nmblookup isn't correctly getting your broadcast address through its
automatic mechanism. In this case you should experiment with the -B
option which allows you to manually specify the broadcast address,
overriding the automatic detection. You should try different broadcast
addresses until your find the one that works. It will most likely be
something like a.b.c.255 as microsoft tcpip stacks only listen on 1's
based broadcast addresses. If you get stuck then ask your local
networking guru for help (and show them this paragraph).
If you find you do need the -B option (ie. the automatic detection
doesn't work) then you should add the -B option with the right
broadcast address for your network to the command line of nmbd in
inetd.conf or in the script you use to start nmbd as a daemon. Once
you do this go back to the "nmblookup __SAMBA__ -B BIGSERVER" test to
make sure you have it running properly.
If your PC and server aren't on the same subnet then you will need to
use the -B option to set the broadcast address to the that of the PCs
subnet.
TEST 7:
-------
run the command "smbclient '\\BIGSERVER\TMP'". You should then be
prompted for a password. You should use the password of the account
you are logged into the unix box with. If you want to test with
another account then add the -U <accountname> option to the command
line.
Once you enter the password you should get the "smb>" prompt. If you
don't then look at the error message. If it says "invalid network
name" then the service "tmp" is not correctly setup in your smb.conf.
If it says "bad password" then the likely causes are:
- you have shadow passords (or some other password system) but didn't
compile in support for them in smbd
- your "valid users" configuration is incorrect
- you have a mixed case password and you haven't enabled the "password
level" option at a high enough level
- the "path =" line in smb.conf is incorrect. Check it with testparm
Once connected you should be able to use the commands "dir" "get"
"put" etc. Type "help <command>" for instructions. You should
especially check that the amount of free disk space shown is correct
when you type "dir".
TEST 8:
-------
On the PC type the command "net view \\BIGSERVER". You will need to do
this from within a "dos prompt" window. You should get back a list of
available shares on the server.
If you get a "network name not found" or similar error then netbios
name resolution is not working. This is usually caused by a problem in
nmbd. To overcome it you could do one of the following (you only need
to choose one of them):
- fixup the nmbd installation
- add the IP address of BIGSERVER to the "wins server" box in the
advanced tcp/ip setup on the PC.
- enable windows name resolution via DNS in the advanced section of
the tcp/ip setup
- add BIGSERVER to your lmhosts file on the PC.
If you get a "invalid network name" or "bad password error" then the
same fixes apply as they did for the "smbclient -L" test above. In
particular, make sure your "hosts allow" line is correct (see the man
pages)
TEST 9:
--------
run the command "net use x: \\BIGSERVER\TMP". You should be prompted
for a password then you should get a "command completed successfully"
message. If not then your PC software is incorrectly installed or your
smb.conf is incorrect. make sure your "hosts allow" and other config
lines in smb.conf are correct.
It's also possible that the server can't work out what user name to
connect you as. To see if this is the problem add the line "user =
USERNAME" to the [tmp] section of smb.conf where "USERNAME" is the
username corresponding to the password you typed. If you find this
fixes things you may need the username mapping option.
TEST 10:
--------
From file manager try to browse the server. Your samba server should
appear in the browse list of your local workgroup (or the one you
specified in the Makefile). You should be able to double click on the
name of the server and get a list of shares. If you get a "invalid
password" error when you do then you are probably running WinNT and it
is refusing to browse a server that has no encrypted password
capability and is in user level security mode.
Still having troubles?
----------------------
Try the mailing list or newsgroup, or use the tcpdump-smb utility to
sniff the problem.

69
docs/textdocs/DNIX.txt Normal file
View File

@ -0,0 +1,69 @@
DNIX has a problem with seteuid() and setegid(). These routines are
needed for Samba to work correctly, but they were left out of the DNIX
C library for some reason.
For this reason Samba by default defines the macro NO_EID in the DNIX
section of includes.h. This works around the problem in a limited way,
but it is far from ideal, some things still won't work right.
To fix the problem properly you need to assemble the following two
functions and then either add them to your C library or link them into
Samba.
put this in the file setegid.s:
.globl _setegid
_setegid:
moveq #47,d0
movl #100,a0
moveq #1,d1
movl 4(sp),a1
trap #9
bccs 1$
jmp cerror
1$:
clrl d0
rts
put this in the file seteuid.s:
.globl _seteuid
_seteuid:
moveq #47,d0
movl #100,a0
moveq #0,d1
movl 4(sp),a1
trap #9
bccs 1$
jmp cerror
1$:
clrl d0
rts
after creating the above files you then assemble them using
as seteuid.s
as setegid.s
that should produce the files seteuid.o and setegid.o
then you need to add these to the LIBSM line in the DNIX section of
the Samba Makefile. Your LIBSM line will then look something like this:
LIBSM = setegid.o seteuid.o -ln
You should then remove the line:
#define NO_EID
from the DNIX section of includes.h
Then recompile and try it out!
Note that this file was derived from an email from Peter Olsson
<pol@leissner.se>. I don't have DNIX myself, so you're probably better
off contacting Peter if you have problems.
Andrew

68
docs/textdocs/DOMAIN.txt Normal file
View File

@ -0,0 +1,68 @@
Samba now supports domain logons and network logon scripts. The
support is still experimental, but it seems to work.
The support is also not complete. Samba does not yet support the
sharing of the SAM database with other systems yet, or remote
administration. Support for these kind of things should be added
sometime in the future.
The domain support only works for WfWg and Win95 clients. Support for
NT and OS/2 clients is still being worked on.
Using these features you can make your clients verify their logon via
the Samba server and make clients run a batch file when they logon to
the network. The latter is particularly useful.
To use domain logons you need to do the following:
1) Setup nmbd and smbd and configure the smb.conf so that Samba is
acting as the master browser. See INSTALL.txt and BROWSING.txt for
details.
2) create a share called [netlogon] in your smb.conf. This share should
be readable by all users, and probably should not be writeable. This
share will hold your network logon scripts.
For example I have used:
[netlogon]
path = /data/dos/netlogon
writeable = no
guest ok = yes
3) in the [global] section of smb.conf set the following:
domain logons = yes
logon script = %U.bat
the choice of batch file is, of course, up to you. The above would
give each user a separate batch file as the %U will be changed to
their username automatically. The other standard % macros may also be
used. You can make the btch files come from a subdirectory by using
soemthing like:
logon script = scripts\%U.bat
4) create the batch files to be run when the user logs in. If the batch
file doesn't exist then no batch file will be run.
In the batch files you need to be careful to use DOS style cr/lf line
endings. If you don't then DOS may get confused. I suggest you use a
DOS editor to remotely edit the files if you don't know how to produce
DOS style files under unix.
5) Use smbclient with the -U option for some users to make sure that
the \\server\NETLOGON share is available, the batch files are visible
and they are readable by the users.
6) you will probabaly find that your clients automatically mount the
\\SERVER\NETLOGON share as drive z: while logging in. You can put some
useful programs there to execute from the batch files.
NOTE: You must be using "security = user" or "security = server" for
domain logons to work correctly. Share level security won't work
correctly.

View File

@ -0,0 +1,333 @@
LanManager / Samba Password Encryption.
---------------------------------------
With the development of LanManager compatible password encryption for
Samba, it is now able to validate user connections in exactly the same
way as a LanManager or Windows NT server.
This document describes how the SMB password encryption algorithm
works and what issues there are in choosing whether you want to use
it. You should read it carefully, especially the part about security
and the "PROS and CONS" section.
How does it work ?
------------------
LanManager encryption is somewhat similar to UNIX password
encryption. The server uses a file containing a hashed value of a
users password. This is created by taking the users paintext
password, capitalising it, and either truncating to 14 bytes (or
padding to 14 bytes with null bytes). This 14 byte value is used as
two 56 bit DES keys to encrypt a 'magic' eight byte value, forming a
16 byte value which is stored by the server and client. Let this value
be known as the *hashed password*.
When a client (LanManager, Windows for WorkGroups, Windows 95 or
Windows NT) wishes to mount a Samba drive (or use a Samba resource) it
first requests a connection and negotiates the protocol that the client
and server will use. In the reply to this request the Samba server
generates and appends an 8 byte, random value - this is stored in the
Samba server after the reply is sent and is known as the *challenge*.
The challenge is different for every client connection.
The client then uses the hashed password (16 byte value described
above), appended with 5 null bytes, as three 56 bit DES keys, each of
which is used to encrypt the challenge 8 byte value, forming a 24 byte
value known as the *response*.
In the SMB call SMBsessionsetupX (when user level security is
selected) or the call SMBtconX (when share level security is selected)
the 24 byte response is returned by the client to the Samba server.
The Samba server then reproduces the above calculation, using it's own
stored value of the 16 byte hashed password (read from the smbpasswd
file - described later) and the challenge value that it kept from the
negotiate protocol reply. It then checks to see if the 24 byte value it
calculates matches the 24 byte value returned to it from the client.
If these values match exactly, then the client knew the correct
password (or the 16 byte hashed value - see security note below) and
is this allowed access. If not then the client did not know the
correct password and is denied access.
Note that the Samba server never knows or stores the cleartext of the
users password - just the 16 byte hashed function derived from it. Also
note that the cleartext password or 16 byte hashed value are never
transmitted over the network - thus increasing security.
IMPORTANT NOTE ABOUT SECURITY
-----------------------------
The unix and SMB password encryption techniques seem similar on the
surface. This similarity is, however, only skin deep. The unix scheme
typically sends clear text passwords over the nextwork when logging
in. This is bad. The SMB encryption scheme never sends the cleartext
password over the network but it does store the 16 byte hashed value
on disk. This is also bad. Why? Because the 16 byte hashed value is a
"password equivalent". You cannot derive the users password from it,
but it could potentially be used in a modified client to gain access
to a server. This would require considerable technical knowledge on
behalf of the attacker but is perfectly possible. You should thus
treat the smbpasswd file as though it contained the cleartext
passwords of all your users. Its contents must be kept secret, and the
file should be protected accordingly.
Ideally we would like a password scheme which neither requires plain
text passwords on the net or on disk. Unfortunately this is not
available as Samba is stuck with being compatible with other SMB
systems (WinNT, WfWg, Win95 etc).
PROS AND CONS
-------------
There are advantages and disadvantages to both schemes.
Advantages of SMB Encryption:
-----------------------------
- plain text passwords are not passed across the network. Someone using
a network sniffer cannot just record passwords going to the SMB server.
- WinNT doesn't like talking to a server that isn't using SMB
encrypted passwords. It will refuse to browse the server if the server
is also in user level security mode. It will insist on promting the
user for the password on each connection, which is very annoying. The
only things you can do to stop this is to use SMB encryption.
Advantages of non-encrypted passwords:
--------------------------------------
- plain text passwords are not kept on disk.
- uses same password file as other unix services such as login and
ftp
- you are probably already using other services (such as telnet and
ftp) which send plain text passwords over the net, so not sending them
for SMB isn't such a big deal.
- the SMB encryption code in Samba is new and has only had limited
testing. We have tried hard to make it secure but in any new
implementation of a password scheme there is the possability of an
error.
The smbpasswd file.
-------------------
In order for Samba to participate in the above protocol it must
be able to look up the 16 byte hashed value given a user name.
Unfortunately, as the UNIX password value is also a one way hash
function (ie. it is impossible to retrieve the cleartext of the users
password given the UNIX hash of it) then a separate password file
containing this 16 byte value must be kept. To minimise problems with
these two password files, getting out of sync, the UNIX /etc/passwd and
the smbpasswd file, a utility, mksmbpasswd.sh, is provided to generate
a smbpasswd file from a UNIX /etc/passwd file.
To generate the smbpasswd file from your /etc/passwd file use the
following command :-
cat /etc/passwd | mksmbpasswd.sh >/usr/local/samba/private/smbpasswd
If you are running on a system that uses NIS, use
ypcat passwd | mksmbpasswd.sh >/usr/local/samba/private/smbpasswd
The mksmbpasswd.sh program is found in the Samba source directory. By
default, the smbpasswd file is stored in :-
/usr/local/samba/private/smbpasswd
The owner of the /usr/local/samba/private directory should be set to
root, and the permissions on it should be set to :-
r-x------
The command
chmod 500 /usr/local/samba/private
will do the trick. Likewise, the smbpasswd file inside the private
directory should be owned by root and the permissions on is should be
set to
rw-------
by the command :-
chmod 600 smbpasswd.
The format of the smbpasswd file is
username:uid:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:Long name:user home dir:user shell
Although only the username, uid, and XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
sections are significant and are looked at in the Samba code.
It is *VITALLY* important that there by 32 'X' characters between the
two ':' characters - the smbpasswd and Samba code will fail to validate
any entries that do not have 32 characters between ':' characters.
When the password file is created all users have password entries
consisting of 32 'X' characters. By default this disallows any access
as this user. When a user has a password set, the 'X' characters change
to 32 ascii hexadecimal digits (0-9, A-F). These are an ascii
representation of the 16 byte hashed value of a users password.
To set a user to have no password (not recommended), edit the file
using vi, and replace the first 11 characters with the asci text
NO PASSWORD
Eg. To clear the password for user bob, his smbpasswd file entry would
look like :
bob:100:NO PASSWORDXXXXXXXXXXXXXXXXXXXXX:Bob's full name:/bobhome:/bobshell
If you are allowing users to use the smbpasswd command to set their own
passwords, you may want to give users NO PASSWORD initially so they do
not have to enter a previous password when changing to their new
password (not recommended).
Note : This file should be protected very carefully. Anyone with
access to this file can (with enough knowledge of the protocols) gain
access to your SMB server. The file is thus more sensitive than a
normal unix /etc/passwd file.
The smbpasswd Command.
----------------------
The smbpasswd command maintains the 32 byte password field in
the smbpasswd file. If you wish to make it similar to the unix passwd
or yppasswd programs, install it in /usr/local/samba/bin (or your main
Samba binary directory) and make it setuid root.
Note that if you do not do this then the root user will have to set all
users passwords.
To set up smbpasswd as setuid root, change to the Samba binary install
directory and then type (as root) :
chown root smbpasswd
chmod 4555 smbpasswd
If smbpasswd is installed as setuid root then you would use it as
follows.
smbpasswd
Old SMB password: <type old alue here - just hit return if there is NO PASSWORD>
New SMB Password: < type new value >
Repeat New SMB Password: < re-type new value >
If the old value does not match the current value stored for that user,
or the two new values do not match each other, then the password will
not be changed.
If invoked by an ordinary user it will only allow the user to change
his or her own Samba password.
If run by the root user smbpasswd may take an optional argument,
specifying the user name whose SMB password you wish to change. Note
that when run as root smbpasswd does not prompt for or check the old
password value, thus allowing root to set passwords for users who have
forgotten their passwords.
smbpasswd is designed to work in the same way and be familiar to UNIX
users who use the passwd or yppasswd commands.
NOTE. As smbpasswd is designed to be installed as setuid root I would
appreciate it if everyone examined the source code to look for
potential security flaws. A setuid program, if not written properly can
be an open door to a system cracker. Please help make this program
secure by reporting all problems to me (the author, Jeremy Allison).
My email address is :-
jra@vantive.com
Setting up Samba to support LanManager Encryption.
--------------------------------------------------
This is a very brief description on how to setup samba to support
password encryption. More complete instructions will probably be added
later.
1) get and compile the libdes libraries. the source is available from
nimbus.anu.edu.au in pub/tridge/libdes/libdes.tar.92-10-13.gz
2) enable the encryption stuff in the Samba makefile, making sure you
point it to the libdes library and include file (it needs des.h)
The entries you need to uncomment are the four lines after the comment :-
# This is for SMB encrypted (lanman) passwords.
Note that you may have to change the variable DES_BASE to
point at the place where you installed the DES library.
3) compile and install samba as usual
4) f your system can't compile the module getsmbpass.c then remove the
-DSMBGETPASS define from the Makefile.
5) enable encrypted passwords in smb.conf by adding the line
"encrypt passwords = yes" in the [global] section
6) create the initial smbpasswd password file in the place you
specified in the Makefile. A simple way to do this based on your
existing Makefile (assuming it is in a reasonably standard format) is
like this:
cat /etc/passwd | mksmbpasswd.sh > /usr/local/samba/private/smbpasswd
Change ownership of private and smbpasswd to root.
chown -R root /usr/local/samba/private
Set the correct permissions on /usr/local/samba/private
chmod 500 /usr/local/samba/private
Set the correct permissions on /usr/local/samba/private/smbpasswd
chmod 600 /usr/local/samba/private/smbpasswd
note that the mksmbpasswd.sh script is in the samba source directory.
If this fails then you will find that you will need entries that look
like this:
# SMB password file.
tridge:148:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:Andrew Tridgell:/home/tridge:/bin/tcsh
note that the uid and username fields must be right. Also, you must get
the number of X's right (there should be 32).
If you wish, install the smbpasswd program as suid root.
chown root /usr/local/samba/bin/smbpasswd
chmod 4555 /usr/local/samba/bin/smbpasswd
7) set the passwords for users using the smbpasswd command. For
example, as root you could do "smbpasswd tridge"
8) try it out!
Note that you can test things using smbclient, as it also now supports
encryption.
NOTE TO USA Sites that Mirror Samba
-----------------------------------
The DES library is considered a munition in the USA. Under US Law it is
illegal to export this software, or to put it in a freely available ftp
site.
Please do not mirror the DES directory from the site on nimbus.anu.edu.au
Thank you,
Jeremy Allison.

202
docs/textdocs/HINTS.txt Normal file
View File

@ -0,0 +1,202 @@
Here are some random hints that you may find useful. These really
should be incorporated in the main docs someday.
----------------------
HINT: Always test your smb.conf with testparm before using it
If your smb.conf file is invalid then samba will fail to load. Run
testparm over it before you install it just to make sure there aren't
any basic syntax or logical errors.
----------------------
HINT: Try printing with smbclient first
If you have problems printing, test with smbclient first. Just connect using
"smbclient '\\server\printer' -P" and use the "print" command.
Once this works, you know that Samba is setup correctly for printing,
and you should be able to get it to work from your PCs.
This particularly helps in getting the "print command" right.
----------------------
HINT: Mount cdroms with conv=binary
Some OSes (notably Linux) default to auto detection of file type on
cdroms and do cr/lf translation. This is a very bad idea when use with
Samba. It causes all sorts of stuff ups.
To overcome this problem use conv=binary when mounting the cdrom
before exporting it with Samba.
----------------------
HINT: Convert between unix and dos text formats
Jim barry has written an excellent drag-and-drop cr/lf converter for
windows. Just drag your file onto the icon and it converts the file.
Get it from
ftp://nimbus.anu.edu.au/pub/tridge/samba/contributed/fixcrlf.zip
----------------------
HINT: Use the "username map" option
If the usernames used on your PCs don't match those used on the unix
server then you will find the "username map" option useful.
-----------------------
HINT: Use "security = user" in [global]
If you have the same usernames on the unix box and the PCs or have
mapped them with the "username map" option then choose "security =
user" in the [global] section of smb.conf.
This will mean your password is checked only when you first connect,
and subsequent connections to printers, disks etc will go more
smoothly and much faster.
The main problem with "security = user" if you use WfWg is that you
will ONLY be able to connect as the username that you log into WfWg
with. This is because WfWg silently ignores the password field in the
connect drive dialog box if the server is in user security mode.
------------------------
HINT: Make your printers not "guest ok"
If your printers are not "guest ok" and you are using "security =
user" and have matching unix and PC usernames then you will attach to
the printer without trouble as your own username. This will mean you
will be able to delete print jobs (in 1.8.06 and above) and printer
accounting will be possible.
-----------------------
HINT: Use a sensible "guest" account
Even if all your services are not available to "guest" you will need a
guest account. This is because the browsing is done as guest. In many
cases setting "guest account = ftp" will do the trick. Using the
default guest account or "guest account = nobody" will give problems on
many unixes. If in doubt create another account with minimal
privilages and use it instead. Your users don't need to know the
password of the guest account.
-----------------------
HINT: Use the latest TCP/IP stack from microsoft if you use Windows
for workgroups.
The early TCP/IP stacks had lots of bugs.
Microsoft has released an incremental upgrade to their TCP/IP 32-Bit
VxD drivers. The latest release can be found on their ftp site at
ftp.microsoft.com, located in /peropsys/windows/public/tcpip/wfwt32.exe.
There is an update.txt file there that describes the problems that were
fixed. New files include WINSOCK.DLL, TELNET.EXE, WSOCK.386, VNBT.386,
WSTCP.386, TRACERT.EXE, NETSTAT.EXE, and NBTSTAT.EXE.
-----------------------
HINT: nmbd can act as a "WINS" server
By default SMB clients use broadcasts to find shares. Recent clients
(such as WfWg) can use a "wins" server instead, whcih reduces your
broadcast traffic and allows you to find names across routers.
Just point your WfWg, Win95 and NT clients at the Samba box in the WINS option.
Note: nmbd does not support all WINS operations. Anyone out there have
a spec they could send me?
-----------------------
HINT: you may need to delete your .pwl files when you change password.
WfWg does a lousy job with passwords. I find that if I change my
password on either the unix box or the PC the safest thing to do is to
delete the .pwl files in the windows directory. The PC will complain about not finding the files, but will soon get over it, allowing you to enter the new password.
If you don't do this you may find that WfWg remembers and uses the old
password, even if you told it a new one.
Often WfWg will totally ignore a password you give it in a dialog box.
----------------------
HINT: Using MS Access
Here are some notes on running MS-Access on a Samba drive from Stefan
Kjellberg <stefank@esi.com.au>
1. Opening a database in 'exclusive' mode does NOT work. Samba ignores
r/w/share modes on file open.
2. Make sure that you open the database as 'shared' and to 'lock modified
records'
3. Of course locking must be enabled for the particular share (smb.conf)
---------------------
HINT: password cacheing in WfWg
Here is a hint from michael@ecel.uwa.edu.au (Michael Simmons):
In case people where not aware. There is a program call admincfg.exe
on the last disk (disk 8) of the WFW 3.11 disk set. To install it
type EXPAND A:\ADMINCFG.EX_ C:\WINDOWS\ADMINCFG.EXE Then add an icon
for it via the "Progam Manager" "New" Menu. This program allows you
to control how WFW handles passwords. ie disable Password Caching etc
for use with "security = user"
--------------------
HINT: file descriptor limits
If you have problems with the limits on the number of open files you
can edit local.h to fix it.
--------------------
HINT: HPUX initgroups() problem
here is a hint from Frank Wales [frank@arcglade.demon.co.uk]:
HP's implementation of supplementary groups is, er, non-standard (for
hysterical reasons). There are two group files, /etc/group and
/etc/logingroup; the system maps UIDs to numbers using the former, but
initgroups() reads the latter. Most system admins who know the ropes
symlink /etc/group to /etc/logingroup (hard link doesn't work for reasons
too stupid to go into here). initgroups() will complain if one of the
groups you're in in /etc/logingroup has what it considers to be an invalid
ID, which means outside the range [0..UID_MAX], where UID_MAX is (I think)
60000 currently on HP-UX. This precludes -2 and 65534, the usual 'nobody'
GIDs.
Perhaps you could suggest to users that, if they encounter this problem,
they make sure that the programs that are failing to initgroups() be
run as users not in any groups with GIDs outside the allowed range.
This is documented in the HP manual pages under setgroups(2) and passwd(4).
---------------------
HINT: Patch your SCO system
If you run SCO Unix then you may need to get important TCP/IP patches
for Samba to work correctly. Try
Paul_Davis@mindlink.bc.ca writes:
I was having problems with Accpac using 1.9.02 on SCO Unix. One
posting function reported corrupted data. After installing uod385a,
the problem went away (a restore from backup and then another
run-thru).
It appears that the uod385a update for SCO may be fairly important for
a lot of different DOS and Windows software under Samba.
uod385a can be found at ftp.sco.com /SLS/uod385a.Z and uod385a.ltr.Z.

View File

@ -0,0 +1,27 @@
Please see the readme and the man page for general info.
1) Follow the samba installation instructions.
2) If all goes well, test it out by creating a share on your PC (called
backup for example) then doing something like,
./smbtar -s mypc -t /dev/rmt/0ubn -x backup
substituting whatever your tape drive is for the -t option, or set your
tape environmental variable.
If all does not go well, feel free to mail the author (poultenr@logica.co.uk)
about bug reports / help / money / pizza / etc.
3) Read the man page and the NOTES file for more information
4) Work smbtar into your usual nightly backup scheme (presuming you
have one :-}).
NOTE:
If you have problems with smbtar then it's probably best to contact the
author Ricky Poulten (poultenr@logica.co.uk).

96
docs/textdocs/PROJECTS Normal file
View File

@ -0,0 +1,96 @@
Samba Projects Directory
========================
>>>>> NOTE: THIS FILE IS NOW VERY OUT OF DATE <<<<<
This is a list of who's working on what in Samba. It's not guaranteed
to be uptodate or accurate but I hope it will help us getting
coordinated.
If you are working on something to do with Samba and you aren't here
then please let me know! Also, if you are listed below and you have
any corrections or updates then please let me know.
Email contact:
samba-bugs@anu.edu.au
========================================================================
Documentation and FAQ
Docs and FAQ files for the Samba suite of software.
Contact Karl.Auer@anu.edu.au
Mark Preston is now working on a set of formatted docs for Samba.
Contact mpreston@sghms.ac.uk
Docs are currently up to date with version, 1.7.07. FAQ being added to
as questions arise.
Status last updated 27th September 1994
========================================================================
========================================================================
Netbeui support
This aims to produce patches so that Samba can be used with clients
that do not have TCP/IP. It will try to remain as portable as possible.
Contact Brian.Onn@Canada.Sun.COM (Brian Onn)
The project is just startup up.
Status last updated 4th October 1994
========================================================================
========================================================================
Smbfs
A mountable smb filesystem for Linux using the userfs userspace filesystem
Contact lendecke@namu01.gwdg.de (Volker Lendecke)
Currently this is at version 0.2. It works but is really only for
people with some knowledge and experience of Linux kernel hacking.
Status last updated 23rd August 1994
========================================================================
========================================================================
Nmbd
Aims to produce a complete rfc1001/1002 implementation. The current
nmbd is a partial implementation.
Contact Fabrice Cetre (cetre@ifhpserv.insa-lyon.fr)
Status last updated 23rd August 1994
========================================================================
========================================================================
Admin Tool
Aims to produce a nice smb.conf editor and other useful tools for
administering a Samba system.
Contact: Steve Brown (steve@unicorn.dungeon.com)
In the design phase.
Status last updated 4th September 1994
========================================================================
========================================================================
Lanman Client.
Contact: john@amanda.xs4all.nl (John Stewart)
Aims to produce a reliable LANMAN Client implementation for LINUX,
and possibly other variations of UNIX. Project ably started by
Tor Lillqvist; tml@hemuli.tte.vtt.fi
Status last updated 17th January 1995
========================================================================

View File

@ -0,0 +1,42 @@
NOTE ABOUT PASSWORDS
====================
Unix systems use a wide variety of methods for checking the validity
of a password. This is primarily controlled with the Makefile defines
mentioned in the Makefile.
Also note that some clients (notably WfWg) uppercase the password
before sending it. The server tries the password as it receives it and
also after lowercasing it.
The Samba server can also be configured to try different
upper/lowercase combinations. This is controlled by the [global]
parameter "password level". A level of N means to try all combinations
up to N uppercase characters in the password. A high value can chew a
fair bit of CPU time and can lower the security of your system. Do not
use this options unless you really need it - the time taken for
password checking can become so high that clients time out.
If you do use the "password level" option then you might like to use
-DUFC_CRYPT in your Makefile. On some machine this makes password
checking _much_ faster. This is also useful if you use the @group
syntax in the user= option.
If your site uses AFS (the Andrew File System), you can use the AFS section
in the Makefile. This will first attempt to authenticate a username and
password to AFS. If that succeeds, then the associated AFS rights will be
granted. Otherwise, the password checking routine falls back to whatever
Unix password checking method you are using. Note that the AFS code is
only written and tested for AFS 3.3 and later.
SECURITY = SERVER
=================
Samba can use a remote server to do it's username/password
validation. This allows you to have one central machine (for example a
NT box) control the passwords for the Unix box.
See the section on "security =" in smb.conf(5) for details.

View File

@ -0,0 +1,79 @@
=============================================================================
Basic DCE/DFS Support for SAMBA 1.9.13
Jim Doyle <doyle@oec.com> 06-02-95
=============================================================================
Functionality:
--------------
Per-instance authentication for DCE/DFS.
Missing Functionality in this Implementation:
---------------------------------------------
* No automatic refresh of credentials
To do so would not be that hard.. One could simply
stash the clear-text key in memory, spawn a key management
thread to wake up right before credentials expire and
refresh the login context.
* No UNIX Signals support (SIGCLD, SIGPIPE, SIGHUP, SIGBUS, SIGSEGV)
There is no support for signal processing in Samba daemons
that need to authenticate with DCE. The explanation for this
is that the smbd is linked against thread-safe libraries in
order to be able to use DCE authentication mechanisms.
Because smbd uses signal() and fork(), it represents the
worst case scenario for DCE portability. In order
to properly support signals in a forked server environment,
some rework of smbd is needed in order to properly
construct, shutdown and reconstruct asynchronous signal
handling threads and synchronous signal traps across the
parent and child. I have not had contiguous time to work
on it, I expect it to be a weeks worth of work to cleanly
integrate thread-safe signal handing into the code and
test it. Until I can get to this task, I will leave it up
to someone adventurous enough to engineer it and negotiate
with Andrew to integrate the changes into the mainline branch.
The lack of full signal support means that you cannot
rely upon SIGHUP-ing the parent daemon to refresh
the configuration data. Likewise, you cannot take advantage
of the builtin SIGBUS/SIGSEGV traps to diagnose failures.
You will have to halt Samba in order to make changes
and then have them take effect.
The SMBD server as it stands is suitable to use if you
already have experience with configuring and running
SAMBA.
Tested Platforms:
-----------------
HP-UX 9.05 / HP-UX DCE 1.2.1
AIX 3.2.5 / AIX DCE/6000 1.3
DEC OSF-1 3.0 / DEC DCE 1.3
Building:
---------
- Uncomment the the appropriate block in the Makefile
for the platform you wish to build on.
- Samples of Samba server configuration files for our
DFS environment are included in samples.dcedfs/
Bugs, Suggestions, etc..
--------------------------
Please post them to the mailing list.
That way I will see them and they will become part of
the archives so others can share the knowledge.

124
docs/textdocs/README.jis Normal file
View File

@ -0,0 +1,124 @@
$B!|(B samba $BF|K\8lBP1~$K$D$$$F(B
1. $BL\E*(B
$BF|K\8lBP1~$O!"(B
(1) MS-Windows $B>e$G!"4A;z%U%!%$%kL>$r$I$&$7$F$b07$&I,MW$N$"$k%"%W%j%1!<%7%g%s$,$A$c(B
$B$s$HF0:n$9$k!#Nc$($P!"(BMS-WORD 5 $B$J$I$O!"%$%s%9%H!<%k;~$K4A;z$N%U%!%$%kL>$r>!<j(B
$B$K$D$1$F$7$^$$$^$9!#$3$&$$$C$?>l9g$K$A$c$s$HBP1~$G$-$k$h$&$K$9$k!#(B
(2) UNIX $B$O!":G6a$G$O$[$H$s$I$N$b$N$,(B 8 bits $B$N%U%!%$%kL>$r%5%]!<%H$7$F$$$^$9$,!"(B
$BCf$K$O!"$3$l$r%5%]!<%H$7$F$$$J$$$b$N$b$"$j$^$9!#$3$N$h$&$J>l9g$G$b!"(B(1)$B$NL\E*(B
$B$,K~B-$G$-$k$h$&$K$9$k!#(B
$B$rL\E*$H$7$F$$$^$9!#$=$N$?$a!"F|K\8lBP1~$O!"I,MW:G>.8B$7$+9T$J$C$F$*$j$^$;$s!#(B
2. $BMxMQJ}K!(B
(1) $BDI2C$7$?%Q%i%a!<%?(B
smb.conf $B%U%!%$%k$N(B global $B%;%/%7%g%s$K0J2<$N%Q%i%a!<%?$r@_Dj$G$-$k$h$&$K$7$^$7$?!#(B
[global]
....
coding system = <$B%3!<%I7O(B>
$B$3$3$G;XDj$5$l$?%3!<%I7O$,(B UNIX $B>e$N%U%!%$%k%7%9%F%`$N%U%!%$%kL>$N%3!<%I$K$J$j$^$9!#(B
$B@_Dj$G$-$k$b$N$O!"<!$N$h$&$K$J$C$F$$$^$9!#(B
sjis: SHIFT JIS (MS $B4A;z%3!<%I(B)
euc: EUC $B%3!<%I(B
hex: 7 bits $B$N(B ASCII $B%3!<%I0J30$N%3!<%I$r0J2<$N7A<0$GI=$9J}<0$G$9!#Nc$($P!"(B
'$B%*%U%#%9(B' $B$H$$$&L>A0$O!"(B':83:49:83:74:83:42:83:58' $B$N$h$&$K!"(B':' $B$N8e$K#27e(B
$B$N(B16$B?J?t$rB3$1$k7A<0$K$J$j$^$9!#(B
$B$3$3$G!"(B':' $B$rB>$NJ8;z$KJQ99$7$?$$>l9g$O!"(Bhex $B$N8e$m$K$=$NJ8;z$r;XDj$7$^$9!#(B
$BNc$($P!"(B@$B$rJQ$o$j$K;H$$$?$$>l9g$O!"(B'hex@'$B$N$h$&$K;XDj$7$^$9!#(B
JIS $B%3!<%I$K$D$$$F$O!"0J2<$NI=$r;2>H$7$F2<$5$$!#(B
$B(#(!(!(!(((!(!(!(!(((!(!(!(!(((!(!(!(!(((!(!(!(!(((!(!(!(!(((!(!(!(!(!(!(!(!(!($(B
$B(";XDj(B $B("4A;z3+;O("4A;z=*N;("%+%J3+;O("%+%J=*N;("1Q?t3+;O("Hw9M(B $B("(B
$B('(!(!(!(+(!(!(!(!(+(!(!(!(!(+(!(!(!(!(+(!(!(!(!(+(!(!(!(!(+(!(!(!(!(!(!(!(!(!()(B
$B("(Bjis7 $B("(B\E$B $B("(B\E(J $B("(B0x0e $B("(B0x0f $B("(B\E(J $B("(Bjis 7$BC10LId9f(B $B("(B
$B("(Bjunet $B("(B\E$B $B("(B\E(J $B("(B\E(I $B("(B\E(J $B("(B\E(J $B("(B7bits $B%3!<%I(B $B("(B
$B("(Bjis8 $B("(B\E$B $B("(B\E(J $B("(B-- $B("(B-- $B("(B\E(J $B("(Bjis 8$BC10LId9f(B $B("(B
$B("(Bj7bb $B("(B\E$B $B("(B\E(B $B("(B0x0e $B("(B0x0f $B("(B\E(B $B("(B $B("(B
$B("(Bj7bj $B("(B\E$B $B("(B\E(J $B("(B0x0e $B("(B0x0f $B("(B\E(J $B("(Bjis7$B$HF1$8(B $B("(B
$B("(Bj7bh $B("(B\E$B $B("(B\E(H $B("(B0x0e $B("(B0x0f $B("(B\E(H $B("(B $B("(B
$B("(Bj7@b $B("(B\E$@ $B("(B\E(B $B("(B0x0e $B("(B0x0f $B("(B\E(B $B("(B $B("(B
$B("(Bj7@j $B("(B\E$@ $B("(B\E(J $B("(B0x0e $B("(B0x0f $B("(B\E(J $B("(B $B("(B
$B("(Bj7@h $B("(B\E$@ $B("(B\E(H $B("(B0x0e $B("(B0x0f $B("(B\E(H $B("(B $B("(B
$B("(Bj8bb $B("(B\E$B $B("(B\E(B $B("(B-- $B("(B-- $B("(B\E(B $B("(B $B("(B
$B("(Bj8bj $B("(B\E$B $B("(B\E(J $B("(B-- $B("(B-- $B("(B\E(J $B("(Bjis8$B$HF1$8(B $B("(B
$B("(Bj8bh $B("(B\E$B $B("(B\E(H $B("(B-- $B("(B-- $B("(B\E(H $B("(B $B("(B
$B("(Bj8@b $B("(B\E@@ $B("(B\E(B $B("(B-- $B("(B-- $B("(B\E(B $B("(B $B("(B
$B("(Bj8@j $B("(B\E$@ $B("(B\E(J $B("(B-- $B("(B-- $B("(B\E(J $B("(B $B("(B
$B("(Bj8@h $B("(B\E$@ $B("(B\E(H $B("(B-- $B("(B-- $B("(B\E(H $B("(B $B("(B
$B("(Bjubb $B("(B\E$B $B("(B\E(B $B("(B\E(I $B("(B\E(B $B("(B\E(B $B("(B $B("(B
$B("(Bjubj $B("(B\E$B $B("(B\E(J $B("(B\E(I $B("(B\E(J $B("(B\E(J $B("(Bjunet$B$HF1$8(B $B("(B
$B("(Bjubh $B("(B\E$B $B("(B\E(H $B("(B\E(I $B("(B\E(H $B("(B\E(H $B("(B $B("(B
$B("(Bju@b $B("(B\E$@ $B("(B\E(B $B("(B\E(I $B("(B\E(B $B("(B\E(B $B("(B $B("(B
$B("(Bju@j $B("(B\E$@ $B("(B\E(J $B("(B\E(I $B("(B\E(J $B("(B\E(J $B("(B $B("(B
$B("(Bju@h $B("(B\E$@ $B("(B\E(H $B("(B\E(I $B("(B\E(H $B("(B\E(H $B("(B $B("(B
$B(&(!(!(!(*(!(!(!(!(*(!(!(!(!(*(!(!(!(!(*(!(!(!(!(*(!(!(!(!(*(!(!(!(!(!(!(!(!(!(%(B
$B$$$:$l$N>l9g$b!"$9$G$KB8:_$7$F$$$kL>A0$KBP$7$F$O!"4A;z$N3+;O=*N;%7!<%1%s%9$O!"0J2<(B
$B$N$b$N$rG'<1$7$^$9!#(B
$B4A;z$N;O$^$j(B: \E$B $B$+(B \E$@
$B4A;z$N=*$j(B: \E(J $B$+(B \E(B $B$+(B \E(H
(2) smbclient $B$N%*%W%7%g%s(B
$B%/%i%$%"%s%H%W%m%0%i%`$G$b!"4A;z$d2>L>$r4^$s$@%U%!%$%k$r07$($k$h$&$K!"<!$N%*%W%7%g%s(B
$B$rDI2C$7$^$7$?!#(B
-t <$B%?!<%_%J%k%3!<%I7O(B>
$B$3$3$G!"(B<$B%?!<%_%J%k%3!<%I7O(B>$B$K;XDj$G$-$k$b$N$O!">e$N(B<$B%3!<%I7O(B>$B$HF1$8$b$N$G$9!#(B
(3) $B%G%U%)%k%H(B
$B%G%U%)%k%H$N%3!<%I7O$O!"%3%s%Q%$%k;~$K7h$^$j$^$9!#(B
3. $B%3%s%Q%$%k;~$N@_Dj(B
Makefile $B$K@_Dj$9$k9`L\$r0J2<$K<($7$^$9!#(B
(1) KANJI $B%U%i%0(B
$B%3%s%Q%$%k%*%W%7%g%s$K(B -DKANJI=\"$B%3!<%I7O(B\" $B$r;XDj$7$^$9!#$3$N%3!<%I7O$O(B 2. $B$G;X(B
$BDj$9$k$b$N$HF1$8$G$9!#Nc$($P!"(B-DKANJI=\"euc\" $B$r(BFLAGSM $B$K@_Dj$9$k$H(B UNIX $B>e$N%U%!(B
$B%$%kL>$O!"(BEUC $B%3!<%I$K$J$j$^$9!#$3$3$G;XDj$7$?%3!<%I7O$O!"%5!<%P5Z$S%/%i%$%"%s%H(B
$B%W%m%0%i%`$N%G%U%)%k%H$KCM$J$j$^$9!#(B
3. $B@)8B;v9`(B
(1) $B4A;z%3!<%I(B
smbd $B$rF0:n$5$;$k%[%9%H$N(B UNIX $B$,%5%]!<%H$7$F$$$J$$4A;z%3!<%I$O!"MxMQ$G$-$J$$$3$H$,(B
$B$"$j$^$9!#JQ$JF0:n$r$9$k$h$&$J$i(B hex $B$N;XDj$r$9$k$N$,NI$$$G$7$g$&!#(B
(2) smbclient $B%3%^%s%I(B
$B%7%U%H%3!<%I$J$I$N4X78$G!"4A;z$d2>L>$r4^$s$@%U%!%$%kL>$N(B ls $B$NI=<($,Mp$l$k$3$H$,$"$j(B
$B$^$9!#(B
(3) $B%o%$%k%I%+!<%I$K$D$$$F(B
$B$A$c$s$H$7$?%9%Z%C%/$,$h$/$o$+$i$J$+$C$?$N$G$9$,!"0l1~!"(BDOS/V $B$NF0:n$HF1$8F0:n$r9T$J(B
$B$&$h$&$K$J$C$F$$$^$9!#(B
4. $B>c32Ey$N%l%]!<%H$K$D$$$F(B
$BF|K\8l$N%U%!%$%kL>$K4X$7$F!"J8;z2=$1Ey$N>c32$,$"$l$P!";d$K%l%]!<%H$7$FD:$1$l$P9,$$$G(B
$B$9!#$?$@$7!"%*%j%8%J%k$+$i$NLdBjE@$d<ALd$K$D$$$F$O!"%*%j%8%J%k$N:n<T$XD>@\Ld$$9g$o$;$k(B
$B$+!"$b$7$/$O%a!<%j%s%0%j%9%H$J$I$X%l%]!<%H$9$k$h$&$K$7$F2<$5$$!#(B
5. $B$=$NB>(B
hex $B7A<0$NJQ49J}K!$O!"(B
$BBgLZ!wBgDM!&C^GH(B <ohki@gssm.otsuka.tsukuba.ac.jp>$B;a(B
$B$,:n$i$l$?%3!<%I$rMxMQ$7$F$$$^$9!#(B
1994$BG/(B10$B7n(B28$BF|(B $BBh#1HG(B
1995$BG/(B 8$B7n(B16$BF|(B $BBh#2HG(B
$BF#ED(B $B?r(B fujita@ainix.isac.co.jp

View File

@ -0,0 +1,15 @@
This is version 1.4 of my small extension to samba that allows PC shares
to be backed up directly to a UNIX tape. It only has been tested under
Solaris 2.3, Linux 1.1.59 and DG/UX 5.4r3.10 with version 1.9.13 of samba.
See the file INSTALL for installation instructions, and
the man page and NOTES file for some basic usage. Please let me know if you
have any problems getting it to work under your flavour of Unix.
This is only (yet another) intermediate version of sambatar.
This version also comes with an extra gift, zen.bas, written in
microsoft qbasic by a colleague. It is (apparently) based on a 70s
British sci-fi series known as Blake's 7. If you have any questions
about this program, or any suggestions (e.g. what about servillan.bas
?), feel free to mail the author (of zen.bas) greenm@lilhd.logica.com.

12
docs/textdocs/SCO.txt Normal file
View File

@ -0,0 +1,12 @@
There is an annoying TCPIP bug in SCO Unix. This causes orruption when
transferring files with Samba.
Geza Makay (makayg@math.u-szeged.hu) sends this information:
The patch you need is UOD385 Connection Drivers SLS. It is available from
SCO (ftp.sco.com, directory SLS, files uod385a.Z and uod385a.ltr.Z).
You do not need anything else but the above patch. It installs in seconds,
and corrected the Excel problem. We also had some other minor problems (not
only with Samba) that disappeared by installing this patch.

View File

@ -0,0 +1,40 @@
Intro
-----
sambatar is just a small extension to the smbclient program distributed with
samba. A basic front end shell script, smbtar, is provided as an interface
to the smbclient extensions.
Extensions
----------
This release adds the following extensions to smbclient,
tar [c|x] filename
creates or restores from a tar file. The tar file may be a tape
or a unix tar file. tar's behaviour is modified with the newer and tarmode
commands.
tarmode [full|inc|reset|noreset]
With no arguments, tarmode prints the current tar mode (by default full,
noreset). In full mode, every file is backed up during a tar command.
In incremental, only files with the dos archive bit set are backed up.
The archive bit is reset if in reset mode, or left untouched if in noreset.
In reset mode, the share has to be writable, which makes sambatar even
less secure. An alternative might be to use tarmode inc noreset which
would implement an "expanding incremental" backup (which some may prefer
anyway).
setmode <setmode string> filename
This is a "freebie" - nothing really to do with sambatar. This
is a crude attrib like command (only the other way around). Setmode string
is a combination of +-rhsa. So for example -rh would reset the read only
bit on filename.
newer filename
This is in fact part of the 1.9.13 samba distribution, but comes
into its own with sambatar. This causes tar (or get, mget, etc) to
only copy files newer than the specified file name. Could be used
against the previous nights (or whatever) log file to implement incremental
backups.

272
docs/textdocs/Speed.txt Normal file
View File

@ -0,0 +1,272 @@
This file tries to outline the ways to improve the speed of a Samba server.
Andrew Tridgell
January 1995
COMPARISONS
-----------
The Samba server uses TCP to talk to the client. Thus if you are
trying to see if it performs well you should really compare it to
programs that use the same protocol. The most readily available
programs for file transfer that use TCP are ftp or another TCP based
SMB server.
If you want to test against something like a NT or WfWg server then
you will have to disable all but TCP on either the client or
server. Otherwise you may well be using a totally different protocol
(such as Netbeui) and comparisons may not be valid.
Generally you should find that Samba performs similarly to ftp at raw
transfer speed. It should perform quite a bit faster than NFS,
although this very much depends on your system.
Several people have done comparisons between Samba and Novell, NFS or
WinNT. In some cases Samba performed the best, in others the worst. I
suspect the biggest factor is not Samba vs some other system but the
hardware and drivers used on the various systems. Given similar
hardware Samba should certainly be competitive in speed with other
systems.
SOCKET OPTIONS
--------------
There are a number of socket options that can greatly affect the
performance of a TCP based server like Samba.
The socket options that Samba uses are settable both on the command
line with the -O option, or in the smb.conf file.
The "socket options" section of the smb.conf manual page describes how
to set these and gives recommendations.
Getting the socket options right can make a big difference to your
performance, but getting them wrong can degrade it by just as
much. The correct settings are very dependent on your local network.
The socket option TCP_NODELAY is the one that seems to make the
biggest single difference for most networks. Many people report that
adding "socket options = TCP_NODELAY" doubles the read performance of
a Samba drive. The best explanation I have seen for this is that the
Microsoft TCP/IP stack is slow in sending tcp ACKs.
READ SIZE
---------
The option "read size" affects the overlap of disk reads/writes with
network reads/writes. If the amount of data being transferred in
several of the SMB commands (currently SMBwrite, SMBwriteX and
SMBreadbraw) is larger than this value then the server begins writing
the data before it has received the whole packet from the network, or
in the case of SMBreadbraw, it begins writing to the network before
all the data has been read from disk.
This overlapping works best when the speeds of disk and network access
are similar, having very little effect when the speed of one is much
greater than the other.
The default value is 16384, but very little experimentation has been
done yet to determine the optimal value, and it is likely that the best
value will vary greatly between systems anyway. A value over 65536 is
pointless and will cause you to allocate memory unnecessarily.
MAX XMIT
--------
At startup the client and server negotiate a "maximum transmit" size,
which limits the size of nearly all SMB commands. You can set the
maximum size that Samba will negotiate using the "max xmit = " option
in smb.conf.
It defaults to 65536 bytes (the maximum), but it is possible that some
clients may perform better with a smaller transmit unit. Trying values
of less than 2048 is likely to cause severe problems.
In most cases the default is the best option.
LOCKING
-------
By default Samba does not implement strict locking on each read/write
call (although it did in previous versions). If you enable strict
locking (using "strict locking = yes") then you may find that you
suffer a severe performance hit on some systems.
The performance hit will probably be greater on NFS mounted
filesystems, but could be quite high even on local disks.
SHARE MODES
-----------
Some people find that opening files is very slow. This is often
because of the "share modes" code needed to fully implement the dos
share modes stuff. You can disable this code using "share modes =
no". This will gain you a lot in opening and closing files but will
mean that (in some cases) the system won't force a second user of a
file to open the file read-only if the first has it open
read-write. For many applications that do their own locking this
doesn't matter, but for some it may.
LOG LEVEL
---------
If you set the log level (also known as "debug level") higher than 2
then you may suffer a large drop in performance. This is because the
server flushes the log file after each operation, which can be very
expensive.
WIDE LINKS
----------
The "wide links" option is now enabled by default, but if you disable
it (for better security) then you may suffer a performance hit in
resolving filenames. The performance loss is lessened if you have
"getwd cache = yes", which is now the default.
READ RAW
--------
The "read raw" operation is designed to be an optimised, low-latency
file read operation. A server may choose to not support it,
however. and Samba makes support for "read raw" optional, with it
being enabled by default.
In some cases clients don't handle "read raw" very well and actually
get lower performance using it than they get using the conventional
read operations.
So you might like to try "read raw = no" and see what happens on your
network. It might lower, raise or not affect your performance. Only
testing can really tell.
WRITE RAW
---------
The "write raw" operation is designed to be an optimised, low-latency
file write operation. A server may choose to not support it,
however. and Samba makes support for "write raw" optional, with it
being enabled by default.
Some machines may find "write raw" slower than normal write, in which
case you may wish to change this option.
READ PREDICTION
---------------
Samba can do read prediction on some of the SMB commands. Read
prediction means that Samba reads some extra data on the last file it
read while waiting for the next SMB command to arrive. It can then
respond more quickly when the next read request arrives.
This is disabled by default. You can enable it by using "read
prediction = yes".
Note that read prediction is only used on files that were opened read
only.
Read prediction should particularly help for those silly clients (such
as "Write" under NT) which do lots of very small reads on a file.
Samba will not read ahead more data than the amount specified in the
"read size" option. It always reads ahead on 1k block boundaries.
MEMORY MAPPING
--------------
Samba supports reading files via memory mapping them. One some
machines this can give a large boost to performance, on others it
makes not difference at all, and on some it may reduce performance.
To enable you you have to recompile Samba with the -DUSE_MMAP=1 option
on the FLAGS line of the Makefile.
Note that memory mapping is only used on files opened read only, and
is not used by the "read raw" operation. Thus you may find memory
mapping is more effective if you disable "read raw" using "read raw =
no".
SLOW CLIENTS
------------
One person has reported that setting the protocol to COREPLUS rather
than LANMAN2 gave a dramatic speed improvement (from 10k/s to 150k/s).
I suspect that his PC's (386sx16 based) were asking for more data than
they could chew. I suspect a similar speed could be had by setting
"read raw = no" and "max xmit = 2048", instead of changing the
protocol. Lowering the "read size" might also help.
SLOW LOGINS
-----------
Slow logins are almost always due to the password checking time. Using
the lowest practical "password level" will improve things a lot. You
could also enable the "UFC crypt" option in the Makefile.
CLIENT TUNING
-------------
Often a speed problem can be traced to the client. The client (for
example Windows for Workgroups) can often be tuned for better TCP
performance.
See your client docs for details. In particular, I have heard rumours
that the WfWg options TCPWINDOWSIZE and TCPSEGMENTSIZE can have a
large impact on performance.
Also note that some people have found that setting DefaultRcvWindow in
the [MSTCP] section of the SYSTEM.INI file under WfWg to 3072 gives a
big improvement. I don't know why.
My own experience wth DefaultRcvWindow is that I get much better
performance with a large value (16384 or larger). Other people have
reported that anything over 3072 slows things down enourmously. One
person even reported a speed drop of a factor of 30 when he went from
3072 to 8192. I don't know why.
It probably depends a lot on your hardware, and the type of unix box
you have at the other end of the link.
MY RESULTS
----------
Some people want to see real numbers in a document like this, so here
they are. I have a 486sx33 client running WfWg 3.11 with the 3.11b
tcp/ip stack. It has a slow IDE drive and 20Mb of ram. It has a SMC
Elite-16 ISA bus ethernet card. The only WfWg tuning I've done is to
set DefaultRcvWindow in the [MSTCP] section of system.ini to 16384. My
server is a 486dx3-66 running Linux. It also has 20Mb of ram and a SMC
Elite-16 card. You can see my server config in the examples/tridge/
subdirectory of the distribution.
I get 490k/s on reading a 8Mb file with copy.
I get 441k/s writing the same file to the samba server.
Of course, there's a lot more to benchmarks than 2 raw throughput
figures, but it gives you a ballpark figure.
I've also tested Win95 and WinNT, and found WinNT gave me the best
speed as a samba client. The fastest client of all (for me) is
smbclient running on another linux box. Maybe I'll add those results
here someday ...
COMMENTS
--------
If you've read this far then please give me some feedback! Which of
the above suggestions worked for you?
Mail the samba mailing list or samba-bugs@anu.edu.au

376
docs/textdocs/Support.txt Normal file
View File

@ -0,0 +1,376 @@
The Samba Consultants List
==========================
This is a list of people who are prepared to install and support Samba.
Note that in most countries nobody should admit to "supplying" Samba, since
there is then an implied warranty with possibly onerous legal obligations.
Just downloading and installing it isn't supply in this sense, but advertising
"run our Samba for best results" may be so.
Being on this list does not imply any sort of endorsement by anyone, it is just
provided in the hope that it will be useful.
If you want to be added to the list, or want your entry modified then
contact the address below. They are currently listed in the
order that they were received. If it gets too big we may organise it
by region. Please make sure to include a header line giving the region
and country, eg CANBERRA - AUSTRALIA.
You can contact the maintainers at samba-bugs@anu.edu.au
------------------------------------------------------------------------------
BRISBANE - AUSTRALIA
Brett Worth
Select Computer Technology - Brisbane
431 Logan Road
Stones Corner QLD 4120
E-Mail: brett@sct.com.au
------------------------------------------------------------------------------
------------------------------------------------------------------------------
CANBERRA - AUSTRALIA
Paul Blackman (ictinus@lake.canberra.edu.au, Ph. 06 2012518) is
available for consultation. Paul's Samba background is with
Solaris 2.3/4 and WFWG/Win95 machines. Paul is also the maintainer
of the SAMBA Web Pages.
------------------------------------------------------------------------------
------------------------------------------------------------------------------
READING - ENGLAND
Philip Hands | E-Mail: info@hands.com
Philip Hands Computing Ltd. | Tel: +44 1734 476287 Fax: 1734 474655
Unit 1, Cherry Close, Caversham, Reading RG4 8UP UK
Samba experience: SVR4,SVR3.2 & Linux <--> WfWg, W3.1, OS2 and MS-LanMan
------------------------------------------------------------------------------
------------------------------------------------------------------------------
ILLONOIS - USA
Information One, Inc.
736 Hinman Ave, Suite 2W
Evanston, IL 60202
708-328-9137 708-328-0117 FAX
info@info1.com
Providing custom Internet and networking solutions.
------------------------------------------------------------------------------
------------------------------------------------------------------------------
Olympic Peninsula Consulting; 1241 Lansing Ave W., Bremerton, WA 98312-4343
telephone 1+ 360 792 6938; mailto:opc@aa.net; http://www.aa.net/~opc;
Unix Systems and TCP/IP Network design, programming, and administration.
------------------------------------------------------------------------------
------------------------------------------------------------------------------
SolutionS R Us has been in business for 3+ years providing viable 3rd
party support in system/network administration. With our own Linux
distribution which we're constantly improving to make it the best and
using it to provide total solutions for companies which are open to
using Linux.
Mauro DePalma <mauro@sru.com>
------------------------------------------------------------------------------
------------------------------------------------------------------------------
BIELEFELD - GERMANY
I am located in Bielefeld/Germany and have been doing Unix consultancy
work for the past 8 years throughout Germany and the rest of Europe. I
can be contacted by email at <jpm@mens.de> or via phone at +49 521
9225922 or telefax at +49 521 9225924.
------------------------------------------------------------------------------
------------------------------------------------------------------------------
CANBERRA - AUSTRALIA
Ben Elliston
Faculty of Information Sciences and Engineering
University of Canberra AUSTRALIA
E-mail: ben@ise.canberra.edu.au (Uni)
------------------------------------------------------------------------------
------------------------------------------------------------------------------
PALERMO - ITALY
Francesco Cardinale
E-Mail: cardinal@palermo.italtel.it
Samba experience: SVR3.2, SOLARIS, ULTRIX, LINUX <--> DOS LAN-MAN, WFW
------------------------------------------------------------------------------
------------------------------------------------------------------------------
SYDNEY - AUSTRALIA
John Terpstra - Aquasoft (jht@aquasoft.com.au)
Business: +612 524 4040
Home: +612 540 3154
Shoephone: +612 414 334422 (aka 0414 334422)
------------------------------------------------------------------------------
------------------------------------------------------------------------------
ONTARIO - CANADA
Strata Software Limited, Kanata Ontario CANADA
Tel: +1 (613) 591-1922 Fax: +1 (613) 591-3485
Email: sales@strataware.com WWW: http://www.strataware.com/
Strata Software Limited is a software development and consulting group
specializing in data communications (TCP/IP and OSI), X.400, X.500 and
LDAP, and X.509-based security. We have Samba experience with Windows NT,
Windows 95, and Windows for Workgroups clients with Linux, Unixware
(SVR4), and HP-UX servers.
------------------------------------------------------------------------------
-----------------------------------------------------------------------
SYDNEY - AUSTRALIA
We are a Unix & Windows developer with a consulting & support component.
In business since 1981 with experience on Sun, hp, sgi, IBM rs6000 plus
Windows, NT and Win95, Using Samba since September 94.
CodeSmiths, 22 Darley Road, MANLY 2095 NSW; 977 1979; fax: 977 2116
philm@esi.com.au (Australia; New South Wales; SYDNEY; North East)
-----------------------------------------------------------------------
------------------------------------------------------------------------------
EDINBUGH - SCOTLAND
Charlie Hussey email charlie@edina.demon.co.uk
Edina Software Limited tel 0131 657 1129
4 James Street fax 0131 669 9092
Edinburgh EH15 2DS
SAMBA experience: SCO UNIX <=> WfWg
------------------------------------------------------------------------------
------------------------------------------------------------------------------
LONDON - ENGLAND
Mark H. Preston,
Network Analyst, | Email : mpreston@sghms.ac.uk
Computer Unit, | Tel : +44 (0)181 725-5434
St. George's Hospital Med School, | Fax : +44 (0)181 725-3583
London SW17 ORE. | WWW : http://www.sghms.ac.uk
Samba Experience:
Server: Solaris 2.3 & 2.4, Irix 5.2 & 5.3
Client: WinNT, Win95, WfWg, Win3.1, Ms-LanMan, DHCP support
------------------------------------------------------------------------------
------------------------------------------------------------------------------
SYDNEY - AUSTRALIA
Pacific ESI has used and installed Samba since 1.6 on a range
of machines running SunOS, BSD/OS, SCO/UNIX, HP/UX, and Solaris,
and WfWG and Windows95. The largest system worked on to date
involved an Australia wide network of machines with PCs and SUNs
at the various nodes. The in-house testing site is a wide area
network with three sites, remotely connected with PPP and with
SUN servers at each site to all of which are connected several
PCs running mainly WfWG.
Stefan Kjellberg Pacific Engineering Systems
International
info@eram.esi.com.au Voice:+61-2-9063377
... Fax:+61-2-9063468
------------------------------------------------------------------------------
------------------------------------------------------------------------------
CHANTILLY - USA
Intelligent Decisions, Inc.
ATTN: Richard Bullington
14121 Parke Long Ct. #104
Chantilly, VA 22021
U.S.A.
(703) 803-8070
rbullington@intdec.com
Samba experience: Linux, DEC ULTRIX <=> WFWG 3.11, Windows NT 3.5
Specializing in World Wide Web related UNIX-to-PC connectivity.
------------------------------------------------------------------------------
------------------------------------------------------------------------------
FORT COLLINS, CO - USA
Granite Computing Solutions
ATTN: Brian Grossman
Box 270103
Fort Collins, CO 80527-0103
U.S.A.
(970) 225-2370
granite@fortnet.org
Information services, including WfWG, NT, Apple <=> Unix interoperability.
Our standard advertisement says:
> Unix workstations, servers and custom systems <
>> WWW and Unix education <<
>>> Enterprise and departmental computing solutions <<<
>>> Backup & restore <<<
>> Software forensics <<
> Data translation <
------------------------------------------------------------------------------
----------------------------------------------------------
Adelaide, Australia
NS Computer Software and Services P/L
PO Box 86
Ingle Farm
SA 5098
Contact: Richard Sharpe
Ph: +61-8-281-0063 (08-281-0063) AH
FAX:+61-8-250-2080 (08-250-2080)
Experience with: ULTRIX, Digital UNIX, SunOS, WfW 3.11, Win95, WNT 3.51
----------------------------------------------------------
----------------------------------------------------------
TECTONIC LIMITED
WESTWOOD
78 LOUGHBOROUGH ROAD
QUORN
LEICESTERSHIRE
LE12 8DX
TELEPHONE 01509-620922
FAX 01509-620933
CONTACT DAVID ROBINSON
WE ARE UNIX ORIENTATED BUT ALSO SPECIALISE IN PC TO UNIX COMMUNICATIONS, WE
KNOW AND UNDERSTAND PC-NFS, (HENCE OUR INTEREST IN SAMBA).
WE SUPPORT SUNOS, SOLARIS 1.X AND 2.X, HP-UX 9.0 AND 10.0, OSF (or DEC UNIX,
whichever you prefer), WinNT, WfWG and Win95.
WE ARE ALREADY TALKING TO A COUPLE OF VERY LARGE SAMBA USERS HERE IN THE UK.
WE WOULD LIKE TO SUPPORT THEM (AND MANY MORE), WOULD YOU PLEASE CONTACT ME ON:
david@tectonic.demon.co.uk
----------------------------------------------------------
----------------------------------------------------------
MIAMI, FL - USA
Swaney & Associates, Inc.
ATTN: Stephen Swaney
2543 Lincoln Avenue
Miami, Florida 33133
U.S.A
(305) 860-0570
Specializing in:
High Availability system & networks
UNIX to PC connectivity
Market Data systems
Messaging Systems (Sendmail & Microsoft Exchange)
----------------------------------------------------------
------------------------------------------------------------------------------
NEW JERSEY - USA
William J. Maggio
LAN & Computer Integrators, Inc.
242 Old New Brunswick Road Email: bmaggio@lci.com
Suite 440 Voice: 908-981-1991
Piscataway, NJ 08855 Fax : 908-981-1858
Specializing in Internet connectivity and security, Sun integration and
high speed, enterprise network design and deployment.
------------------------------------------------------------------------------
FAREHAM - ENGLAND
High Field Technology Ltd
Little Park Farm Road, Segensworth West,
Fareham, Hants PO15 5SJ, UK.
sales@hft.co.uk tel +44 148 957 0111 fax +44 148 957 0555
Company skills: Real time hardware and software systems
Samba experience: BSD/OS, Linux, LynxOS <==> WFWG, NT
------------------------------------------------------------------------------
-----------------------------------------------------------------------
QUEBEC - CANADA
Dataden Computer Systems
Attn: Danny Arseneau
arseneau@parkmed.com
895 2nd Avenue
Ile Bizard, Quebec
Canada, H9C 1K3
Tel: (514)891-2293
Fax: (514)696-0848
Dataden is company that specializes in Unix--TCP/IP networking.
We have over 15 years of experience. We have been installing,
configuring and maintaining Samba for clients for 1-1/2 years now. We
have samba installations on Linx, SunOS and DEC OSF. Our biggest site
has 4 Suns and 3 Linux servers running Samba which are serving a network
of about 50 PC's running WFWg and Win95.
-----------------------------------------------------------------------
-----------------------------------------------------------------------
CALIFORNIA - USA
Ron Halstead
Open Systems Consulting
3098-4 Lakemont Drive
San Ramon, CA 94583 (San Francisco Bay Area)
(510) 735-7529
halstead@ix.netcom.com
-----------------------------------------------------------------------
-----------------------------------------------------------------------
MELBOURNE - AUSTRALIA
Michael Ciavarella
Cybersoruce Pty Ltd.
8/140 Queen Street
Melbourne VIC 3000
Phone: +61-3-9642-5997
Fax: +61-3-9642-5998
Email: mikec@cyber.com.au
WWW: http://www.cyber.com.au
Cybersource specialises in TCP/IP network integration and Open Systems
administration. Cybersource is an Australian-owned and operated
company, with clients including some of Australia's largest financial,
petrochemical and state government organisations.
-----------------------------------------------------------------------
-----------------------------------------------------------------------
SOUTHERN CALIFORNIA - USA
Michael St. Laurent
Serving Los Angeles and Orange Counties. Please contact via email.
rowl@earthlink.net
Michael St. Laurent
Hartwell Corporation
------------------------------------------------------------------------------
WASHINGTON DC METRO - USA
Asset Software, Inc. has been running Samba since the 1.6 release on various
platforms, including SunOS 4.x, Solaris 2.x, IRIX 4.x and 5.x, Linux 1.1x,
1.2x, and 1.3x, and BSD UNIX 4.3 and above. We specialize in small office
network solutions and provide services to enhance a small office's
operations. Primarily a custom software operation, our vast knowledge of
Windows, DOS, Unix, Windows NT, MacOS, and OS/2 enable us to provide quality
technical assistance to the small office environment at a reasonable price.
Our upcoming multi-mailbox mail client, IQ Mail, enables users with more
than one mailbox to send and retrieve their mail from a single, consistent
mail client running in Windows.
David J. Fenwick Asset Software, Inc.
President djf@assetsw.com
------------------------------------------------------------------------------

220
docs/textdocs/UNIX-SMB.txt Normal file
View File

@ -0,0 +1,220 @@
This is a short document that describes some of the issues that
confront a SMB implementation on unix, and how Samba copes with
them. They may help people who are looking at unix<->PC
interoperability.
It was written to help out a person who was writing a paper on unix to
PC connectivity.
Andrew Tridgell
April 1995
Usernames
=========
The SMB protocol has only a loose username concept. Early SMB
protocols (such as CORE and COREPLUS) have no username concept at
all. Even in later protocols clients often attempt operations
(particularly printer operations) without first validating a username
on the server.
Unix security is based around username/password pairs. A unix box
should not allow clients to do any substantive operation without some
sort of validation.
The problem mostly manifests itself when the unix server is in "share
level" security mode. This is the default mode as the alternative
"user level" security mode usually forces a client to connect to the
server as the same user for each connected share, which is
inconvenient in many sites.
In "share level" security the client normally gives a username in the
"session setup" protocol, but does not supply an accompanying
password. The client then connects to resources using the "tree
connect" protocol, and supplies a password. The problem is that the
user on the PC types the username and the password in different
contexts, unaware that they need to go together to give access to the
server. The username is normally the one the user typed in when they
"logged onto" the PC (this assumes Windows for Workgroups). The
password is the one they chose when connecting to the disk or printer.
The user often chooses a totally different username for their login as
for the drive connection. Often they also want to access different
drives as different usernames. The unix server needs some way of
divining the correct username to combine with each password.
Samba tries to avoid this problem using several methods. These succeed
in the vast majority of cases. The methods include username maps, the
service%user syntax, the saving of session setup usernames for later
validation and the derivation of the username from the service name
(either directly or via the user= option).
File Ownership
==============
The commonly used SMB protocols have no way of saying "you can't do
that because you don't own the file". They have, in fact, no concept
of file ownership at all.
This brings up all sorts of interesting problems. For example, when
you copy a file to a unix drive, and the file is world writeable but
owned by another user the file will transfer correctly but will
receive the wrong date. This is because the utime() call under unix
only succeeds for the owner of the file, or root, even if the file is
world writeable. For security reasons Samba does all file operations
as the validated user, not root, so the utime() fails. This can stuff
up shared development diectories as programs like "make" will not get
file time comparisons right.
There are several possible solutions to this problem, including
username mapping, and forcing a specific username for particular
shares.
Passwords
=========
Many SMB clients uppercase passwords before sending them. I have no
idea why they do this. Interestingly WfWg uppercases the password only
if the server is running a protocol greater than COREPLUS, so
obviously it isn't just the data entry routines that are to blame.
Unix passwords are case sensitive. So if users use mixed case
passwords they are in trouble.
Samba can try to cope with this by either using the "password level"
option which causes Samba to try the offered password with up to the
specified number of case changes, or by using the "password server"
option which allows Samba to do it's validation via another machine
(typically a WinNT server).
Samba also doesn't support the password encryption method used by SMB
clients. This is because the spec isn't sufficiently detailed for an
implementation (although Jeremy Allison is working on it, to try and
work it out). Also, there is a fundamental problem with what we
understand so far in the algorithm, as it seems that the server would
need to store somewhere on disk a reversibly encrypted (effectively
plaintext) copy of the users password in order to use the
algorithm. This goes against the unix policy that "even the super-user
doesn't know your password" which comes from the use of a one-way hash
function.
Locking
=======
The locking calls available under a DOS/Windows environment are much
richer than those available in unix. This means a unix server (like
Samba) choosing to use the standard fcntl() based unix locking calls
to implement SMB locking has to improvise a bit.
One major problem is that dos locks can be in a 32 bit (unsigned)
range. Unix locking calls are 32 bits, but are signed, giving only a 31
bit range. Unfortunately OLE2 clients use the top bit to select a
locking range used for OLE semaphores.
To work around this problem Samba compresses the 32 bit range into 31
bits by appropriate bit shifting. This seems to work but is not
ideal. In a future version a separate SMB lockd may be added to cope
with the problem.
It also doesn't help that many unix lockd daemons are very buggy and
crash at the slightest provocation. They normally go mostly unused in
a unix environment because few unix programs use byte range
locking. The stress of huge numbers of lock requests from dos/windows
clients can kill the daemon on some systems.
The second major problem is the "opportunistic locking" requested by
some clients. If a client requests opportunistic locking then it is
asking the server to notify it if anyone else tries to do something on
the same file, at which time the client will say if it is willing to
give up it's lock. Unix has no simple way of implementing
opportunistic locking, and currently Samba has no support for it.
Deny Modes
==========
When a SMB client opens a file it asks for a particular "deny mode" to
be placed on the file. These modes (DENY_NONE, DENY_READ, DENY_WRITE,
DENY_ALL, DENY_FCB and DENY_DOS) specify what actions should be
allowed by anyone else who tries to use the file at the same time. If
DENY_READ is placed on the file, for example, then any attempt to open
the file for reading should fail.
Unix has no equivalent notion. To implement these Samba uses lock
files based on the files inode and placed in a separate lock
directory. These are clumsy and consume processing and file resources,
so they are optional and off by default.
Trapdoor UIDs
=============
A SMB session can run with several uids on the one socket. This
happens when a user connects to two shares with different
usernames. To cope with this the unix server needs to switch uids
within the one process. On some unixes (such as SCO) this is not
possible. This means that on those unixes the client is restricted to
a single uid.
Port numbers
============
There is a convention that clients on sockets use high "unprivilaged"
port numbers (>1000) and connect to servers on low "privilaged" port
numbers. This is enforced in Unix as non-root users can't open a
socket for listening on port numbers less than 1000.
Most PC based SMB clients (such as WfWg and WinNT) don't follow this
convention completely. The main culprit is the netbios nameserving on
udp port 137. Name query requests come from a source port of 137. This
is a problem when you combine it with the common firewalling technique
of not allowing incoming packets on low port numbers. This means that
these clients can't query a netbios nameserver on the other side of a
low port based firewall.
The problem is more severe with netbios node status queries. I've
found that WfWg, Win95 and WinNT3.5 all respond to netbios node status
queries on port 137 no matter what the source port was in the
request. This works between machines that are both using port 137, but
it means it's not possible for a unix user to do a node status request
to any of these OSes unless they are running as root. The answer comes
back, but it goes to port 137 which the unix user can't listen
on. Interestingly WinNT3.1 got this right - it sends node status
responses back to the source port in the request.
Protocol Complexity
===================
There are many "protocol levels" in the SMB protocol. It seems that
each time new functionality was added to a Microsoft operating system,
they added the equivalent functions in a new protocol level of the SMB
protocol to "externalise" the new capabilities.
This means the protocol is very "rich", offering many ways of doing
each file operation. This means SMB servers need to be complex and
large. It also means it is very difficult to make them bug free. It is
not just Samba that suffers from this problem, other servers such as
WinNT don't support every variation of every call and it has almost
certainly been a headache for MS developers to support the myriad of
SMB calls that are available.
There are about 65 "top level" operations in the SMB protocol (things
like SMBread and SMBwrite). Some of these include hundreds of
sub-functions (SMBtrans has at least 120 sub-functions, like
DosPrintQAdd and NetSessionEnum). All of them take several options
that can change the way they work. Many take dozens of possible
"information levels" that change the structures that need to be
returned. Samba supports all but 2 of the "top level" functions. It
supports only 8 (so far) of the SMBtrans sub-functions. Even NT
doesn't support them all.
Samba currently supports up to the "NT LM 0.12" protocol, which is the
one preferred by Win95 and WinNT3.5. Luckily this protocol level has a
"capabilities" field which specifies which super-duper new-fangled
options the server suports. This helps to make the implementation of
this protocol level much easier.
There is also a problem with the SMB specications. SMB is a X/Open
spec, but the X/Open book is far from ideal, and fails to cover many
important issues, leaving much to the imagination.

56
docs/textdocs/WinNT.txt Normal file
View File

@ -0,0 +1,56 @@
There are some particular issues with Samba and Windows NT
=====================================================================
One of the most annoying problems with WinNT is that NT refuses to
connect to a server that is in user level security mode and that
doesn't support password encryption unless it first prompts the user
for a password.
This means even if you have the same password on the NT box and the
Samba server you will get prompted for a password. Entering the
correct password will get you connected.
The other major ramification of this feature of NT is that it can't
browse a user level non-encrypted server unless it already has a
connection open. This is because there is no spot for a password
prompt in the browser window. It works fine if you already have a
drive mounted (for example, one auto mounted on startup).
Samba should support encrypted passwords soon, which will solve this
problem.
=====================================================================
=====================================================================
When you mount a printer using the print manager in NT you may find
the following info from Matthew Harrell <harrell@leech.nrl.navy.mil>
useful:
------------
I noticed in your change-log you noted that some people were
still unable to use print manager under NT. If this is the same problem
that I encountered, it's caused by the length of time it takes NT to
determine if the printer is ready.
The problem occurs when you double-click on a printer to connect it to
the NT machine. Because it's unable to determine if the printer is ready
in the short span of time it has, it assumes it isn't and gives some
strange error about not having enough resources (I forget what the error
is). A solution to this that seems to work fine for us is to click
once on the printer, look at the bottom of the window and wait until
it says it's ready, then clilck on "OK".
By the way, this problem probably occurs in our group because the
Samba server doesn't actually have the printers - it queues them to
remote printers either on other machines or using their own network
cards. Because of this "middle layer", it takes an extra amount of
time for the NT machine to get verification that the printer queue
actually exists.
I hope this helped in some way...
-----------
=====================================================================

6
examples/README Normal file
View File

@ -0,0 +1,6 @@
This directory contains example config files for Samba. If you have an
interesting config file, then please send it in for inclusion in the
package.
Send it to: Andrew.Tridgell@anu.edu.au

4
examples/dce-dfs/README Normal file
View File

@ -0,0 +1,4 @@
this is a sample configuration file from Jim Doyle <doyle@oec.com> who
did the DCE/DFS patches for Samba. It shows how to make DCE/DFS shares
available.

42
examples/dce-dfs/smb.conf Normal file
View File

@ -0,0 +1,42 @@
[global]
printing = bsd
printcap name = /etc/printcap
load printers = no
guest account = guest
log file = /usr/local/samba/var/log.%m
log level = 8
password level = 8
[homes]
comment = Home Directories
browseable = no
read only = no
create mode = 0750
[test]
comment = test stuff
path = /dept/mis/home/testacct
valid users = testacct
public = no
writable = yes
[namespace]
comment = DCE-DFS Global Root
path = /...
public = no
writable = yes
[oecdfs]
comment = Corporate Cell
path = /.../corp.boston.oec.com/fs
browseable = no
read only = no
create mode = 0750
[develdfs]
comment = Technology Development Cell
path = /.../devel.boston.oec.com/fs
browseable = no
read only = no
create mode = 0750

View File

@ -0,0 +1,47 @@
Here's something that Paul Blackman sent me that may be useful:
-------------------
I created this script to do a few things that smbstatus doesn't at the
moment. Perhaps you might want to include these. Sorry I haven't
added things at source level, script was quick&easy.
*******
#!/bin/csh
if ($1 == "-p") then
smbstatus -p |sort -u
else if ($1 == "-c") then
echo There are `smbstatus -p |sort -u |grep -n -v z |grep -c :` unique
smbd processes running.
else if ($1 == "-l") then
echo `date '+ %d/%m/%y %H:%M:%S'` `smbstatus -p |sort -u |grep -n -v z
|grep -c :` >>$2
else
smbstatus |sort +3 -4 -u
endif
******
The '-p' option was just to show unique PIDs.
The more important ones are the '-c' and '-l' options '-c' just counts
the number of unique smbd's, While '-l' logs this count with date and
time to a log file specified on the command line. I'm using '-l' at
the moment with cron to give me an idea of usage/max connections etc.
I was also thinking of doing a log for individual/specified services.
The default (last) option was to show unique PIDs with user names.
Unfortunately this still lists all file locks etc. This would be
better with a 'no locked files' option from smbstatus (or is there one
that I didn't see)
Cheers,
~^ MIME OK ^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~
o | Paul Blackman ictinus@lake.canberra.edu.au
o | Co-operative Research ------------------------
o _ | Centre For Freshwater Ecology. Ph. (Aus) 06 2012518
-- (") o | University of Canberra, Australia. Fax. " 06 2015038
\_|_-- |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | "Spend a little love and get high"
_/ \_ | - Lenny Kravitz
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~ SAMBA Web Pages: http://samba.canberra.edu.au/pub/samba/samba.html ~~~~~

45
examples/misc/wall.perl Normal file
View File

@ -0,0 +1,45 @@
#!/usr/local/bin/perl
#
#@(#) smb-wall.pl Description:
#@(#) A perl script which allows you to announce whatever you choose to
#@(#) every PC client currently connected to a Samba Server...
#@(#) ...using "smbclient -M" message to winpopup service.
#@(#) Default usage is to message every connected PC.
#@(#) Alternate usage is to message every pc on the argument list.
#@(#) Hacked up by Keith Farrar <farrar@parc.xerox.com>
#
#=============================================================================
$smbstatus = "/usr/local/bin/smbstatus";
$smbclient = "/usr/local/bin/smbclient";
print STDOUT "\nEnter message for Samba clients of this host\n";
print STDOUT "(terminated with single '.' or end of file):\n";
while ( <STDIN> ) {
/^\.$/ && last;
push(@message, $_);
}
if ( $ARGV[0] ne "" ) {
$debug && print STDOUT "Was given args: \n\t @ARGV\n";
foreach $client ( @ARGV ) {
$pcclient{$client} = $client;
}
} else {
open( PCLIST, "$smbstatus | /bin/awk '/^[a-z]/ {print $5}' | /bin/sort | /bin/uniq|");
while ( <PCLIST> ) {
/^[a-z]+[a-z0-9A-Z-_]+.+/ || next;
($share, $user, $group, $pid, $client, @junk) = split;
$pcclient{$client} = $client;
}
close(PCLIST);
}
foreach $pc ( keys(%pcclient) ) {
print STDOUT "Sending message ";
$debug && print STDOUT " <@message> \n";
print STDOUT "To <$pc>\n";
open(SENDMSG,"|$smbclient -M $pc") || next;
print SENDMSG @message;
close(SENDMSG);
}

77
examples/printing/smbprint Executable file
View File

@ -0,0 +1,77 @@
#!/bin/sh -x
# This script is an input filter for printcap printing on a unix machine. It
# uses the smbclient program to print the file to the specified smb-based
# server and service.
# For example you could have a printcap entry like this
#
# smb:lp=/dev/null:sd=/usr/spool/smb:sh:if=/usr/local/samba/smbprint
#
# which would create a unix printer called "smb" that will print via this
# script. You will need to create the spool directory /usr/spool/smb with
# appropriate permissions and ownerships for your system.
# Set these to the server and service you wish to print to
# In this example I have a WfWg PC called "lapland" that has a printer
# exported called "printer" with no password.
#
# Script further altered by hamiltom@ecnz.co.nz (Michael Hamilton)
# so that the server, service, and password can be read from
# a /usr/var/spool/lpd/PRINTNAME/.config file.
#
# In order for this to work the /etc/printcap entry must include an
# accounting file (af=...):
#
# cdcolour:\
# :cm=CD IBM Colorjet on 6th:\
# :sd=/var/spool/lpd/cdcolour:\
# :af=/var/spool/lpd/cdcolour/acct:\
# :if=/usr/local/etc/smbprint:\
# :mx=0:\
# :lp=/dev/null:
#
# The /usr/var/spool/lpd/PRINTNAME/.config file should contain:
# server=PC_SERVER
# service=PR_SHARENAME
# password="password"
#
# E.g.
# server=PAULS_PC
# service=CJET_371
# password=""
#
# Debugging log file, change to /dev/null if you like.
#
logfile=/tmp/smb-print.log
# logfile=/dev/null
#
# The last parameter to the filter is the accounting file name.
# Extract the directory name from the file name.
# Concat this with /.config to get the config file.
#
eval acct_file=\$$#
spool_dir=`dirname $acct_file`
config_file=$spool_dir/.config
# Should read the following variables set in the config file:
# server
# service
# password
eval `cat $config_file`
#
# Some debugging help, change the >> to > if you want to same space.
#
echo "server $server, service $service" >> $logfile
(
# NOTE You may wish to add the line `echo translate' if you want automatic
# CR/LF translation when printing.
# echo translate
echo "print -"
cat
) | /usr/local/samba/bin/smbclient "\\\\$server\\$service" $password -U $server -N -P >> $logfile

View File

@ -0,0 +1,52 @@
#!/bin/sh
#
# @(#) smbprint.sysv version 1.0 Ross Wakelin <r.wakelin@march.co.uk>
#
# Version 1.0 13 January 1995
# modified from the original smbprint (bsd) script
#
# this script is a System 5 printer interface script. It
# uses the smbclient program to print the file to the specified smb-based
# server and service.
#
# To add this to your lp system, copy this file into your samba directory
# (the example here is /opt/samba), modify the server and service variables
# and then execute the following command (as root)
#
# lpadmin -punixprintername -v/dev/null -i/opt/samba/smbprint
#
# where unixprintername is the name that the printer will be known as
# on your unix box.
#
# the script smbprint will be copied into your printer administration
# directory (/usr/lib/lp or /etc/lp) as a new interface
# (interface/unixprintername)
# Then you have to enable unixprintername and accept unixprintername
#
# This script will then be called by the lp service to print the files
# This script will have 6 or more parameters passed to it by the lp service.
# The first five will contain details of the print job, who queued it etc,
# while parameters 6 onwards are a list of files to print. We just
# cat these at the samba client.
#
# Set these to the server and service you wish to print to
# In this example I have a WfWg PC called "lapland" that has a printer
# exported called "printer" with no password.
#
# clear out the unwanted parameters
shift;shift;shift;shift;shift
# now the argument list is just the files to print
server=admin
service=hplj2
password=""
(
# NOTE You may wish to add the line `echo translate' if you want automatic
# CR/LF translation when printing.
echo translate
echo "print -"
cat $*
) | /opt/samba/smbclient "\\\\$server\\$service" $password -N -P > /dev/null
exit $?

2
examples/simple/README Normal file
View File

@ -0,0 +1,2 @@
This is the "original" sample config file.

165
examples/simple/smb.conf Normal file
View File

@ -0,0 +1,165 @@
; Configuration file for smbd.
; ============================================================================
; For the format of this file and comprehensive descriptions of all the
; configuration option, please refer to the man page for smb.conf(5).
;
; The following configuration should suit most systems for basic usage and
; initial testing. It gives all clients access to their home directories and
; allows access to all printers specified in /etc/printcap.
;
; Things you need to check:
; --------------------------
;
; 1: Check the path to your printcap file. If you are using a system that does
; not use printcap (eg., Solaris), create a file containing lines of the
; form
;
; printername|printername|printername|
;
; where each "printername" is the name of a printer you want to provide
; access to. Then alter the "printcap =" entry to point to the new file.
;
; If using Solaris, the following command will generate a suitable printcap
; file:
;
; lpc status | grep ":" | sed s/:/\|/ > myprintcap
;
; 2: Make sure the "print command" entry is correct for your system. This
; command should submit a file (represented by %s) to a printer
; (represented by %p) for printing and should REMOVE the file after
; printing.
;
; One most systems the default will be OK, as long as you get "printing ="
; right.
;
; It is also a good idea to use an absolute path in the print command
; as there is no guarantee the search path will be set correctly.
;
; 3: Make sure the "printing =" option is set correctly for your system.
; Possible values are "sysv", "bsd" or "aix".
;
; 4: Make sure the "lpq command" entry is correct for your system. The default
; may not work for you.
;
; 5: Make sure that the user specified in "guest account" exists. Typically
; this will be a user that cannot log in and has minimal privileges.
; Often the "nobody" account doesn't work (very system dependant).
;
; 6: You should consider the "security =" option. See a full description
; in the main documentation and the smb.conf(5) manual page
;
; 7: Look at the "hosts allow" option, unless you want everyone on the internet
; to be able to access your files.
;
[global]
printing = bsd
printcap name = /etc/printcap
load printers = yes
guest account = pcguest
; This next option sets a separate log file for each client. Remove
; it if you want a combined log file.
log file = /usr/local/samba/log.%m
; You will need a world readable lock directory and "share modes=yes"
; if you want to support the file sharing modes for multiple users
; of the same files
; lock directory = /usr/local/samba/var/locks
; share modes = yes
[homes]
comment = Home Directories
browseable = no
read only = no
create mode = 0750
[printers]
comment = All Printers
browseable = no
printable = yes
public = no
writable = no
create mode = 0700
; you might also want this one
; [tmp]
; comment = Temporary file space
; path = /tmp
; read only = no
; public = yes
;
; Other examples.
;
; A private printer, usable only by fred. Spool data will be placed in fred's
; home directory. Note that fred must have write access to the spool directory,
; wherever it is.
;[fredsprn]
; comment = Fred's Printer
; valid users = fred
; path = /homes/fred
; printer = freds_printer
; public = no
; writable = no
; printable = yes
;
; A private directory, usable only by fred. Note that fred requires write
; access to the directory.
;[fredsdir]
; comment = Fred's Service
; path = /usr/somewhere/private
; valid users = fred
; public = no
; writable = yes
; printable = no
;
; A publicly accessible directory, but read only, except for people in
; the staff group
;[public]
; comment = Public Stuff
; path = /usr/somewhere/public
; public = yes
; writable = no
; printable = no
; write list = @staff
;
; a service which has a different directory for each machine that connects
; this allows you to tailor configurations to incoming machines. You could
; also use the %u option to tailor it by user name.
; The %m gets replaced with the machine name that is connecting.
;[pchome]
; comment = PC Directories
; path = /usr/pc/%m
; public = no
; writeable = yes
;
;
; A publicly accessible directory, read/write to all users. Note that all files
; created in the directory by users will be owned by the default user, so
; any user with access can delete any other user's files. Obviously this
; directory must be writable by the default user. Another user could of course
; be specified, in which case all files would be owned by that user instead.
;[public]
; path = /usr/somewhere/else/public
; public = yes
; only guest = yes
; writable = yes
; printable = no
;
;
; The following two entries demonstrate how to share a directory so that two
; users can place files there that will be owned by the specific users. In this
; setup, the directory should be writable by both users and should have the
; sticky bit set on it to prevent abuse. Obviously this could be extended to
; as many users as required.
;[myshare]
; comment = Mary's and Fred's stuff
; path = /usr/somewhere/shared
; valid users = mary fred
; public = no
; writable = yes
; printable = no
; create mask = 0765

8
examples/tridge/README Normal file
View File

@ -0,0 +1,8 @@
This is the configuration I use at home. I have 2 client PCs, one
running Win95, one running alternately WfWg and NTAS3.5. My server is
a 486dx2-66 Linux box.
Note that I use the %a and %m macros to load smb.conf extensions
particular to machines and architectures. This gives me a lot of
flexibility in how I handle each of the machines.

101
examples/tridge/smb.conf Normal file
View File

@ -0,0 +1,101 @@
[global]
config file = /usr/local/samba/smb.conf.%m
status = yes
security = user
encrypt passwords = yes
server string = Tridge (%v,%h)
load printers = yes
log level = 1
log file = /usr/local/samba/var/log.%m
guest account = pcguest
hosts allow = 192.0.2. localhost
password level = 2
auto services = tridge susan
message command = csh -c '/usr/bin/X11/xedit -display :0 %s;rm %s' &
read prediction = yes
socket options = TCP_NODELAY
valid chars = ö:Ö å:Å ä:Ä
share modes = yes
locking = yes
strict locking = yes
keepalive = 30
include = /usr/local/samba/lib/smb.conf.%m
include = /usr/local/samba/lib/smb.conf.%a
[uniprint]
comment = University Printing
path = /home/susan/print
user = susan
postscript = yes
print ok = yes
print command = xmenu -heading "%s" OK&
[testprn]
comment = Test printer
path = /tmp
user = susan
print ok = yes
print command = cp %s /tmp/smb.%U.prn
lpq command = cat /tmp/xxyz
[amd]
comment = amd area
path = /mount
force user = tridge
read only = no
[homes]
browseable = no
guest ok = no
read only = no
create mask = 0755
[printers]
browseable = no
comment = Printer in Printcap
guest ok = no
path = /tmp
read only = no
print ok = yes
[dos]
browseable = yes
comment = Dos Files
force group = samba
create mode = 0775
path = /home/tridge/dos
copy = homes
[msoffice]
browseable = yes
comment = Microsoft Office
force group = samba
create mode = 0775
path = /data/msoffice
read only = yes
[root]
comment = Root Dir
copy = dos
path = /
dont descend = /proc ./proc /etc
[tmp]
comment = tmp files
copy = dos
path = /tmp
read only = no
[cdrom]
comment = Tridge's CdRom
path = /mount/cdrom
read only = yes
locking = no
[data]
comment = Data Partition
path = /data
read only = yes
guest ok = yes

View File

@ -0,0 +1,14 @@
#log level = 4
#readraw = no
#writeraw = no

View File

@ -0,0 +1,21 @@
;log level = 4
;readraw = no
;writeraw = no
;password level = 4
;mangled map = (;1 )
;protocol = lanman1
;user = susan
;getwd cache = no

View File

@ -0,0 +1,14 @@
#log level = 4
#readraw = no
#writeraw = no

View File

@ -0,0 +1,14 @@
;protocol = LANMAN2
log level = 2

1872
source3/change-log Normal file

File diff suppressed because it is too large Load Diff

4534
source3/client/client.c Normal file

File diff suppressed because it is too large Load Diff

1713
source3/client/clitar.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,80 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
SMB Byte handling
Copyright (C) Andrew Tridgell 1992-1995
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
This file implements macros for machine independent short and
int manipulation
*/
#undef CAREFUL_ALIGNMENT
/* we know that the 386 can handle misalignment and has the "right"
byteorder */
#ifdef __i386__
#define CAREFUL_ALIGNMENT 0
#endif
#ifndef CAREFUL_ALIGNMENT
#define CAREFUL_ALIGNMENT 1
#endif
#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
#define PVAL(buf,pos) ((unsigned)CVAL(buf,pos))
#define SCVAL(buf,pos,val) (CVAL(buf,pos) = (val))
#if CAREFUL_ALIGNMENT
#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8)
#define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16)
#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
#define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16))
#define SVALS(buf,pos) ((int16)SVAL(buf,pos))
#define IVALS(buf,pos) ((int32)IVAL(buf,pos))
#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((uint16)(val)))
#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32)(val)))
#define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16)(val)))
#define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32)(val)))
#else
/* this handles things for architectures like the 386 that can handle
alignment errors */
/*
WARNING: This section is dependent on the length of int16 and int32
being correct
*/
#define SVAL(buf,pos) (*(uint16 *)((char *)(buf) + (pos)))
#define IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos)))
#define SVALS(buf,pos) (*(int16 *)((char *)(buf) + (pos)))
#define IVALS(buf,pos) (*(int32 *)((char *)(buf) + (pos)))
#define SSVAL(buf,pos,val) SVAL(buf,pos)=((uint16)(val))
#define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32)(val))
#define SSVALS(buf,pos,val) SVALS(buf,pos)=((int16)(val))
#define SIVALS(buf,pos,val) IVALS(buf,pos)=((int32)(val))
#endif
/* now the reverse routines - these are used in nmb packets (mostly) */
#define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
#define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16)))
#define RSVAL(buf,pos) SREV(SVAL(buf,pos))
#define RIVAL(buf,pos) IREV(IVAL(buf,pos))
#define RSSVAL(buf,pos,val) SSVAL(buf,pos,SREV(val))
#define RSIVAL(buf,pos,val) SIVAL(buf,pos,IREV(val))

61
source3/include/charset.h Normal file
View File

@ -0,0 +1,61 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
Character set handling
Copyright (C) Andrew Tridgell 1992-1995
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef 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[(char)(c)]
#define tolower(c) lower_char_map[(char)(c)]
#define isupper(c) (((char)(c)) != tolower(c))
#define islower(c) (((char)(c)) != toupper(c))
#define isdoschar(c) (dos_char_map[(char)(c)] != 0)
#define isspace(c) ((c)==' ' || (c) == '\t')
#endif

17
source3/include/clitar.h Normal file
View File

@ -0,0 +1,17 @@
#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;
};

1154
source3/include/includes.h Normal file

File diff suppressed because it is too large Load Diff

130
source3/include/kanji.h Normal file
View File

@ -0,0 +1,130 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
Kanji Extensions
Copyright (C) Andrew Tridgell 1992-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.
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>
*/
#ifndef _KANJI_H_
#define _KANJI_H_
#ifdef KANJI
/* 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))
#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) (const char *str, BOOL overwrite);
extern char* (*_unix_to_dos) (const char *str, BOOL overwrite);
#define unix_to_dos (*_unix_to_dos)
#define dos_to_unix (*_dos_to_unix)
extern char *sj_strtok (char *s1, const char *s2);
extern char *sj_strchr (const char *s, int c);
extern char *sj_strrchr (const char *s, int c);
extern char *sj_strstr (const char *s1, const char *s2);
#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);
#else
#define unix_to_dos(x,y) (x)
#define dos_to_unix(x,y) (x)
#endif /* not KANJI */
#endif /* _KANJI_H_ */

167
source3/include/local.h Normal file
View File

@ -0,0 +1,167 @@
/* 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
/* separators for lists */
#define LIST_SEP " \t,;:\n\r"
#ifndef LOCKDIR
#define LOCKDIR "/tmp/samba"
#endif
/* this is where browse lists are kept in the lock dir */
#define SERVER_LIST "browse.dat"
/* the print command on the server, %s is replaced with the filename */
/* note that the -r removes the file after printing - you'll run out */
/* of disk pretty quickly if you don't. This command is only used as */
/* the default - it can be overridden in the configuration file. */
#define PRINT_COMMAND "lpr -r %s"
/* the lpq command on the server. the printername is passed as an argument */
#ifndef LPQ_COMMAND
#define LPQ_COMMAND "lpq -P"
#endif
/* 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"
/* we have two time standards - local and GMT. This will try to sort them out.
*/
#define LOCAL_TO_GMT 1
#define GMT_TO_LOCAL (-1)
/* 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 (10)
#define SHARE_MODES_CHECK (10)
#define SHARE_MODES_CLEAN (300)
#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
#endif

184
source3/include/nameserv.h Normal file
View File

@ -0,0 +1,184 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
NBT netbios header - version 2
Copyright (C) Andrew Tridgell 1994-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.
*/
#define MAX_DGRAM_SIZE 576
#define MIN_DGRAM_SIZE 12
#define NMB_PORT 137
#define DGRAM_PORT 138
#define SMB_PORT 139
enum name_source {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};
/* a netbios name structure */
struct nmb_name {
char name[17];
char scope[64];
int name_type;
};
/* 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;
time_t death_time;
struct in_addr ip;
BOOL unique;
enum name_source source;
};
/* this is used by the list of domains */
struct domain_record
{
struct domain_record *next;
struct domain_record *prev;
fstring name;
time_t lastannounce_time;
int announce_interval;
struct in_addr bcast_ip;
};
/* this is used to hold the list of servers in my domain */
struct server_record
{
struct server_record *next;
struct server_record *prev;
fstring name;
fstring comment;
uint32 servertype;
time_t death_time;
};
/* 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;
};
/* this defines a list of network interfaces */
struct net_interface {
struct net_interface *next;
struct in_addr ip;
struct in_addr bcast;
struct in_addr netmask;
};
/* prototypes */
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);
BOOL send_packet(struct packet_struct *p);
struct packet_struct *receive_packet(int fd,enum packet_type type,int timeout);
void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope);
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 name_status(int fd,char *name,int name_type,BOOL recurse,
struct in_addr to_ip,char *master,char *rname,
void (*fn)());
BOOL send_mailslot_reply(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);
char *namestr(struct nmb_name *n);

1006
source3/include/smb.h Normal file

File diff suppressed because it is too large Load Diff

241
source3/include/trans2.h Normal file
View File

@ -0,0 +1,241 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
SMB transaction2 handling
Copyright (C) Jeremy Allison 1994
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_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))
/* 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

View File

@ -0,0 +1 @@
#define VERSION "1.9.16alpha1"

48
source3/include/vt_mode.h Normal file
View File

@ -0,0 +1,48 @@
/* 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__ */

389
source3/lib/access.c Normal file
View File

@ -0,0 +1,389 @@
/*
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 Andrew.Tridgell@anu.edu.au
*/
#include "includes.h"
#include "loadparm.h"
#define ALLOW_PURE_ADDRESSES
extern int DEBUGLEVEL;
#ifndef INADDR_NONE
#define INADDR_NONE ((unsigned long)~0)
#endif
#define FROM_ADDRLEN (4*3+3+1)
#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. */
BOOL allow_access(char *deny_list,char *allow_list,struct from_host *client);
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);
static int matchname(char *remotehost,struct in_addr addr);
BOOL fromhost(int sock,struct from_host *f);
/* Size of logical line buffer. */
#define BUFLEN 2048
/* return true if access should be allowed to a service*/
BOOL check_access(int snum)
{
extern int Client;
extern struct from_host Client_info;
char *denyl,*allowl;
BOOL ret = False;
denyl = lp_hostsdeny(snum);
if (denyl) denyl = strdup(denyl);
allowl = lp_hostsallow(snum);
if (allowl) allowl = strdup(allowl);
fromhost(Client,&Client_info);
if ((!denyl || *denyl==0) && (!allowl || *allowl==0))
ret = True;
if (!ret)
{
if (!fromhost(Client,&Client_info))
DEBUG(0,("ERROR: Can't get from_host info\n"));
else
{
if (allow_access(denyl,allowl,&Client_info))
{
if (snum >= 0)
DEBUG(2,("Allowed connection from %s (%s) to %s\n",
Client_info.name,Client_info.addr,
lp_servicename(snum)));
ret = True;
}
else
if (snum >= 0)
DEBUG(0,("Denied connection from %s (%s) to %s\n",
Client_info.name,Client_info.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,struct from_host *client)
{
/* 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)
{
struct from_host *client = (struct from_host *) 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->addr)) == 0)
if (client->name[0] != 0)
match = string_match(tok, client->name);
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 (!(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"));
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)
{
unsigned long net;
unsigned long mask;
unsigned long 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);
}
/* fromhost - find out what is at the other end of a socket */
BOOL fromhost(int sock,struct from_host *f)
{
static struct sockaddr sa;
struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
struct hostent *hp;
int length = sizeof(sa);
static char addr_buf[FROM_ADDRLEN];
static char name_buf[MAXHOSTNAMELEN];
BOOL takeAddressAsHostname = False;
if (getpeername(sock, &sa, &length) < 0)
{
DEBUG(0,("getpeername failed\n"));
return(False);
}
f->sin = sockin;
f->addr = strcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
/* 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",addr_buf));
#ifdef ALLOW_PURE_ADDRESSES
takeAddressAsHostname = True;
#else
return(False);
#endif
}
/* Save the host name. A later gethostbyxxx() call may clobber it. */
f->name = StrnCpy(name_buf,
takeAddressAsHostname? f->addr : hp->h_name,
sizeof(name_buf) - 1);
/*
* Verify that the host name does not belong to someone else. If host
* name verification fails, pretend that the host name lookup failed.
*/
if (!takeAddressAsHostname && !matchname(f->name, sockin->sin_addr))
{
DEBUG(0,("Matchname failed\n"));
return(False);
}
return(True);
}
/* matchname - determine if host name matches IP address */
static int 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 (Bad);
}
/*
* 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 (Bad);
}
/* 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 (Good);
}
/*
* 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 (Bad);
}

126
source3/lib/charcnv.c Normal file
View File

@ -0,0 +1,126 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
Character set conversion Extensions
Copyright (C) Andrew Tridgell 1992-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.
*/
#include "includes.h"
extern int DEBUGLEVEL;
static char cvtbuf[1024];
static 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 = 1;
}
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 initiso() {
if (!mapsinited) initmaps();
update_map("\241\255\242\233\243\234\244\236\245\235\246\272\247\025\250\251");
update_map("\251\273\252\246\253\256\254\252\255\274\256\310\257\257\260\370");
update_map("\261\361\262\375\263\264\264\265\265\266\266\024\267\371\270\267");
update_map("\271\270\272\247\273\275\274\254\275\253\276\276\277\250\200\277");
update_map("\301\300\302\301\303\302\304\216\305\217\306\222\307\200\310\303");
update_map("\311\220\312\305\313\306\314\307\315\315\316\317\317\320\320\311");
update_map("\321\245\322\321\323\322\324\323\325\324\326\231\327\312\330\325");
update_map("\331\326\332\327\333\330\334\232\335\313\336\314\337\341\340\205");
update_map("\341\240\342\203\343\331\344\204\345\206\346\221\347\207\350\212");
update_map("\351\202\352\210\353\211\354\215\355\241\356\214\357\213\360\316");
update_map("\361\244\362\225\363\242\364\223\365\332\366\224\367\366\370\362");
update_map("\371\227\372\243\373\226\374\201\375\304\376\263\377\230");
}
/*
* Convert unix to dos
*/
char *
unix2dos_format(char *str,BOOL overwrite)
{
char *p;
char *dp;
if (!mapsinited) initmaps();
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 (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")) {
initiso();
return def;
} else {
DEBUG(0,("unrecognized character set\n"));
}
return def;
}

111
source3/lib/charset.c Normal file
View File

@ -0,0 +1,111 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
Character set handling
Copyright (C) Andrew Tridgell 1992-1995
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define CHARSET_C
#include "includes.h"
extern int DEBUGLEVEL;
char xx_dos_char_map[256];
char xx_upper_char_map[256];
char xx_lower_char_map[256];
char *dos_char_map = NULL;
char *upper_char_map = NULL;
char *lower_char_map = NULL;
static void add_dos_char(int lower, int upper)
{
DEBUG(6,("Adding chars 0%o 0%o\n",lower,upper));
if (lower) dos_char_map[(char)lower] = 1;
if (upper) dos_char_map[(char)upper] = 1;
if (lower && upper) {
lower_char_map[(char)upper] = (char)lower;
upper_char_map[(char)lower] = (char)upper;
}
}
/****************************************************************************
initialise the charset arrays
****************************************************************************/
void charset_initialise(void)
{
int i;
dos_char_map = &xx_dos_char_map[128];
upper_char_map = &xx_upper_char_map[128];
lower_char_map = &xx_lower_char_map[128];
for (i= -128;i<=127;i++) {
dos_char_map[(char)i] = 0;
}
for (i=0;i<=127;i++) {
if (isalnum((char)i) || strchr("._^$~!#%&-{}()@'`",(char)i))
add_dos_char(i,0);
}
for (i= -128;i<=127;i++) {
char c = (char)i;
upper_char_map[i] = lower_char_map[i] = c;
if (isupper(c)) lower_char_map[c] = tolower(c);
if (islower(c)) upper_char_map[c] = toupper(c);
}
/* valid for all DOS PC */
add_dos_char(142,0); /* A trema */
add_dos_char(143,0); /* A o */
add_dos_char(144,0); /* E ' */
add_dos_char(146,0); /* AE */
add_dos_char(153,0); /* O trema */
add_dos_char(154,0); /* U trema */
add_dos_char(165,0); /* N tilda */
add_dos_char(128,0); /* C cedille */
add_dos_char(156,0); /* Pound */
add_dos_char(183,0); /* A ` (WIN)*/
add_dos_char(157,0); /* Phi (WIN)*/
add_dos_char(212,0); /* E` (WIN)*/
}
/*******************************************************************
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(*t) || (*t)=='-') {
sscanf(t,"%i:%i",&i1,&i2);
add_dos_char(i1,i2);
} else {
sscanf(t,"%c:%c",&c1,&c2);
add_dos_char(c1,c2);
}
}
free(extra_chars);
}

86
source3/lib/fault.c Normal file
View File

@ -0,0 +1,86 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
Critical Fault handling
Copyright (C) Andrew Tridgell 1992-1995
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef LINUX
#define __KERNEL__
#endif
#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
}

166
source3/lib/getsmbpass.c Normal file
View File

@ -0,0 +1,166 @@
/* Copyright (C) 1992, 1993, 1994 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, const 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, const 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

895
source3/lib/kanji.c Normal file
View File

@ -0,0 +1,895 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
Kanji Extensions
Copyright (C) Andrew Tridgell 1992-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.
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>
*/
#ifdef KANJI
#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, const 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 (const char *s1, const char *s2)
{
register 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 (const 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 (const char *s, int c)
{
register 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 (register int hi, register 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 (register int hi, register 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 (const char *from, BOOL overwrite)
{
register 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 (const char *from, BOOL overwrite)
{
register 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 (register int hi, register 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 (register int hi, register 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 (const char *from, BOOL overwrite)
{
register char *out;
register 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 (const char *from, BOOL overwrite)
{
register char *out;
register 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 (const char *from, BOOL overwrite)
{
register char *out;
register 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 (const char *from, BOOL overwrite)
{
register char *out;
register 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 (const char *from, BOOL overwrite)
{
register char *out;
register 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 (const char *from, BOOL overwrite)
{
register char *out;
register 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 (const 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 (const 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 (const 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 (const 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) (const char *str, BOOL overwrite) = sj_to_sj;
char* (*_unix_to_dos) (const 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);
}
#else
int kanji_dummy_procedure(void)
{return 0;}
#endif /* KANJI */

299
source3/lib/md4.c Normal file
View File

@ -0,0 +1,299 @@
#ifdef SMB_PASSWD
/*
This code is from rfc1186.
*/
/*
** ********************************************************************
** md4.c -- Implementation of MD4 Message Digest Algorithm **
** Updated: 2/16/90 by Ronald L. Rivest **
** (C) 1990 RSA Data Security, Inc. **
** ********************************************************************
*/
/*
** To use MD4:
** -- Include md4.h in your program
** -- Declare an MDstruct MD to hold the state of the digest
** computation.
** -- Initialize MD using MDbegin(&MD)
** -- For each full block (64 bytes) X you wish to process, call
** MDupdate(&MD,X,512)
** (512 is the number of bits in a full block.)
** -- For the last block (less than 64 bytes) you wish to process,
** MDupdate(&MD,X,n)
** where n is the number of bits in the partial block. A partial
** block terminates the computation, so every MD computation
** should terminate by processing a partial block, even if it
** has n = 0.
** -- The message digest is available in MD.buffer[0] ...
** MD.buffer[3]. (Least-significant byte of each word
** should be output first.)
** -- You can print out the digest using MDprint(&MD)
*/
/* Implementation notes:
** This implementation assumes that ints are 32-bit quantities.
** If the machine stores the least-significant byte of an int in the
** least-addressed byte (e.g., VAX and 8086), then LOWBYTEFIRST
** should be set to TRUE. Otherwise (e.g., SUNS), LOWBYTEFIRST
** should be set to FALSE. Note that on machines with LOWBYTEFIRST
** FALSE the routine MDupdate modifies has a side-effect on its input
** array (the order of bytes in each word are reversed). If this is
** undesired a call to MDreverse(X) can reverse the bytes of X back
** into order after each call to MDupdate.
*/
#define TRUE 1
#define FALSE 0
/* Compile-time includes
*/
#include <stdio.h>
#include "md4.h"
#define uchar unsigned char
#define int16 unsigned short
#define uint32 unsigned int
#include "byteorder.h"
/* Compile-time declarations of MD4 "magic constants".
*/
#define I0 0x67452301 /* Initial values for MD buffer */
#define I1 0xefcdab89
#define I2 0x98badcfe
#define I3 0x10325476
#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */
#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */
/* C2 and C3 are from Knuth, The Art of Programming, Volume 2
** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley.
** Table 2, page 660.
*/
#define fs1 3 /* round 1 shift amounts */
#define fs2 7
#define fs3 11
#define fs4 19
#define gs1 3 /* round 2 shift amounts */
#define gs2 5
#define gs3 9
#define gs4 13
#define hs1 3 /* round 3 shift amounts */
#define hs2 9
#define hs3 11
#define hs4 15
/* Compile-time macro declarations for MD4.
** Note: The "rot" operator uses the variable "tmp".
** It assumes tmp is declared as unsigned int, so that the >>
** operator will shift in zeros rather than extending the sign bit.
*/
#define f(X,Y,Z) ((X&Y) | ((~X)&Z))
#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z))
#define h(X,Y,Z) (X^Y^Z)
#define rot(X,S) (tmp=X,(tmp<<S) | (tmp>>(32-S)))
#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s)
#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s)
#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s)
/* MDprint(MDp)
** Print message digest buffer MDp as 32 hexadecimal digits.
** Order is from low-order byte of buffer[0] to high-order byte of
** buffer[3].
** Each byte is printed with high-order hexadecimal digit first.
** This is a user-callable routine.
*/
void
MDprint(MDp)
MDptr MDp;
{ int i,j;
for (i=0;i<4;i++)
for (j=0;j<32;j=j+8)
printf("%02x",(MDp->buffer[i]>>j) & 0xFF);
}
/* MDbegin(MDp)
** Initialize message digest buffer MDp.
** This is a user-callable routine.
*/
void
MDbegin(MDp)
MDptr MDp;
{ int i;
MDp->buffer[0] = I0;
MDp->buffer[1] = I1;
MDp->buffer[2] = I2;
MDp->buffer[3] = I3;
for (i=0;i<8;i++) MDp->count[i] = 0;
MDp->done = 0;
}
/* MDreverse(X)
** Reverse the byte-ordering of every int in X.
** Assumes X is an array of 16 ints.
** The macro revx reverses the byte-ordering of the next word of X.
*/
void MDreverse(X)
unsigned int *X;
{ register unsigned int t;
register unsigned int i;
for(i = 0; i < 16; i++) {
t = X[i];
SIVAL(X,i*4,t);
}
}
/* MDblock(MDp,X)
** Update message digest buffer MDp->buffer using 16-word data block X.
** Assumes all 16 words of X are full of data.
** Does not update MDp->count.
** This routine is not user-callable.
*/
static void
MDblock(MDp,X)
MDptr MDp;
unsigned int *X;
{
register unsigned int tmp, A, B, C, D;
MDreverse(X);
A = MDp->buffer[0];
B = MDp->buffer[1];
C = MDp->buffer[2];
D = MDp->buffer[3];
/* Update the message digest buffer */
ff(A , B , C , D , 0 , fs1); /* Round 1 */
ff(D , A , B , C , 1 , fs2);
ff(C , D , A , B , 2 , fs3);
ff(B , C , D , A , 3 , fs4);
ff(A , B , C , D , 4 , fs1);
ff(D , A , B , C , 5 , fs2);
ff(C , D , A , B , 6 , fs3);
ff(B , C , D , A , 7 , fs4);
ff(A , B , C , D , 8 , fs1);
ff(D , A , B , C , 9 , fs2);
ff(C , D , A , B , 10 , fs3);
ff(B , C , D , A , 11 , fs4);
ff(A , B , C , D , 12 , fs1);
ff(D , A , B , C , 13 , fs2);
ff(C , D , A , B , 14 , fs3);
ff(B , C , D , A , 15 , fs4);
gg(A , B , C , D , 0 , gs1); /* Round 2 */
gg(D , A , B , C , 4 , gs2);
gg(C , D , A , B , 8 , gs3);
gg(B , C , D , A , 12 , gs4);
gg(A , B , C , D , 1 , gs1);
gg(D , A , B , C , 5 , gs2);
gg(C , D , A , B , 9 , gs3);
gg(B , C , D , A , 13 , gs4);
gg(A , B , C , D , 2 , gs1);
gg(D , A , B , C , 6 , gs2);
gg(C , D , A , B , 10 , gs3);
gg(B , C , D , A , 14 , gs4);
gg(A , B , C , D , 3 , gs1);
gg(D , A , B , C , 7 , gs2);
gg(C , D , A , B , 11 , gs3);
gg(B , C , D , A , 15 , gs4);
hh(A , B , C , D , 0 , hs1); /* Round 3 */
hh(D , A , B , C , 8 , hs2);
hh(C , D , A , B , 4 , hs3);
hh(B , C , D , A , 12 , hs4);
hh(A , B , C , D , 2 , hs1);
hh(D , A , B , C , 10 , hs2);
hh(C , D , A , B , 6 , hs3);
hh(B , C , D , A , 14 , hs4);
hh(A , B , C , D , 1 , hs1);
hh(D , A , B , C , 9 , hs2);
hh(C , D , A , B , 5 , hs3);
hh(B , C , D , A , 13 , hs4);
hh(A , B , C , D , 3 , hs1);
hh(D , A , B , C , 11 , hs2);
hh(C , D , A , B , 7 , hs3);
hh(B , C , D , A , 15 , hs4);
MDp->buffer[0] += A;
MDp->buffer[1] += B;
MDp->buffer[2] += C;
MDp->buffer[3] += D;
}
/* MDupdate(MDp,X,count)
** Input: MDp -- an MDptr
** X -- a pointer to an array of unsigned characters.
** count -- the number of bits of X to use.
** (if not a multiple of 8, uses high bits of last byte.)
** Update MDp using the number of bits of X given by count.
** This is the basic input routine for an MD4 user.
** The routine completes the MD computation when count < 512, so
** every MD computation should end with one call to MDupdate with a
** count less than 512. A call with count 0 will be ignored if the
** MD has already been terminated (done != 0), so an extra call with
** count 0 can be given as a "courtesy close" to force termination
** if desired.
*/
void
MDupdate(MDp,X,count)
MDptr MDp;
unsigned char *X;
unsigned int count;
{ unsigned int i, tmp, bit, byte, mask;
unsigned char XX[64];
unsigned char *p;
/* return with no error if this is a courtesy close with count
** zero and MDp->done is true.
*/
if (count == 0 && MDp->done) return;
/* check to see if MD is already done and report error */
if (MDp->done)
{ printf("\nError: MDupdate MD already done."); return; }
/* Add count to MDp->count */
tmp = count;
p = MDp->count;
while (tmp)
{ tmp += *p;
*p++ = tmp;
tmp = tmp >> 8;
}
/* Process data */
if (count == 512)
{ /* Full block of data to handle */
MDblock(MDp,(unsigned int *)X);
}
else if (count > 512) /* Check for count too large */
{ printf("\nError: MDupdate called with illegal count value %d."
,count);
return;
}
else /* partial block -- must be last block so finish up */
{ /* Find out how many bytes and residual bits there are */
byte = count >> 3;
bit = count & 7;
/* Copy X into XX since we need to modify it */
for (i=0;i<=byte;i++) XX[i] = X[i];
for (i=byte+1;i<64;i++) XX[i] = 0;
/* Add padding '1' bit and low-order zeros in last byte */
mask = 1 << (7 - bit);
XX[byte] = (XX[byte] | mask) & ~( mask - 1);
/* If room for bit count, finish up with this block */
if (byte <= 55)
{ for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
MDblock(MDp,(unsigned int *)XX);
}
else /* need to do two blocks to finish up */
{ MDblock(MDp,(unsigned int *)XX);
for (i=0;i<56;i++) XX[i] = 0;
for (i=0;i<8;i++) XX[56+i] = MDp->count[i];
MDblock(MDp,(unsigned int *)XX);
}
/* Set flag saying we're done with MD computation */
MDp->done = 1;
}
}
/*
** End of md4.c
*/
#else
void md4_dummy() {;}
#endif

222
source3/lib/system.c Normal file
View File

@ -0,0 +1,222 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
Samba system utilities
Copyright (C) Andrew Tridgell 1992-1995
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
extern int DEBUGLEVEL;
/*
The idea is that this file will eventually have wrappers around all
important system calls in samba. The aim is twofold:
- 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
*/
/*******************************************************************
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(16,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));
}
/*******************************************************************
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()
********************************************************************/
int sys_rename(char *from, char *to)
{
#ifdef KANJI
pstring zfrom, zto;
strcpy (zfrom, dos_to_unix (from, False));
strcpy (zto, dos_to_unix (to, False));
return rename (zfrom, zto);
#else
return rename (from, to);
#endif /* KANJI */
}
/*******************************************************************
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
}

782
source3/lib/ufc.c Normal file
View File

@ -0,0 +1,782 @@
/*
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, 1992, 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;
}
ufc_long *_ufc_doit();
/*
* UNIX crypt function
*/
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)))
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)))
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

246
source3/lib/username.c Normal file
View File

@ -0,0 +1,246 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
Username handling
Copyright (C) Andrew Tridgell 1992-1995
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "loadparm.h"
extern int DEBUGLEVEL;
/****************************************************************************
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));
strcpy(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;
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);
if (allow_change)
strcpy(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);
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);
}

4510
source3/lib/util.c Normal file

File diff suppressed because it is too large Load Diff

936
source3/libsmb/nmblib.c Normal file
View File

@ -0,0 +1,936 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
NBT netbios library routines
Copyright (C) Andrew Tridgell 1994-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 "nameserv.h"
extern int DEBUGLEVEL;
int num_good_sends=0;
int num_good_receives=0;
static uint16 name_trn_id = 0;
BOOL CanRecurse = True;
extern pstring scope;
/*******************************************************************
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 are 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);
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) {
free(packet);
return(NULL);
}
num_good_receives++;
DEBUG(4,("%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(4,("%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)
{
strcpy(n->name,name);
strupper(n->name);
n->name_type = type;
strcpy(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) 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) 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);
}
/****************************************************************************
interpret a node status response
****************************************************************************/
static void interpret_node_status(char *p, char *master,char *rname)
{
int level = (master||rname)?4:0;
int numnames = CVAL(p,0);
DEBUG(level,("received %d names\n",numnames));
if (rname) *rname = 0;
if (master) *master = 0;
p += 1;
while (numnames--)
{
char qname[17];
int type;
fstring flags;
*flags = 0;
StrnCpy(qname,p,15);
type = CVAL(p,15);
p += 16;
if (p[0] & 0x80) strcat(flags,"<GROUP> ");
if ((p[0] & 0x60) == 0) strcat(flags,"B ");
if ((p[0] & 0x60) == 1) strcat(flags,"P ");
if ((p[0] & 0x60) == 2) strcat(flags,"M ");
if ((p[0] & 0x60) == 3) strcat(flags,"_ ");
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," ");
}
DEBUG(level,("\t%s (type=0x%x)\t%s\n",qname,type,flags));
p+=2;
}
DEBUG(level,("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;
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 = CanRecurse;
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 = 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;
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;
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 = CanRecurse;
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 = 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;
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);
}
/****************************************************************************
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(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];
bzero((char *)&p,sizeof(p));
dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
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 = fd;
p.timestamp = time(NULL);
p.packet_type = DGRAM_PACKET;
return(send_packet(&p));
}

202
source3/libsmb/smbencrypt.c Normal file
View File

@ -0,0 +1,202 @@
#ifdef SMB_PASSWD
/*
Unix SMB/Netbios implementation.
Version 1.9.
SMB parameters and setup
Copyright (C) Andrew Tridgell 1992-1995
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"
#include "loadparm.h"
#include "des.h"
#include "md4.h"
extern int DEBUGLEVEL;
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef int16
#define int16 unsigned short
#endif
#ifndef uint16
#define uint16 unsigned short
#endif
#ifndef uint32
#define uint32 unsigned int
#endif
#include "byteorder.h"
void str_to_key(uchar *str,uchar *key)
{
void des_set_odd_parity(des_cblock *);
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);
}
des_set_odd_parity((des_cblock *)key);
}
void D1(uchar *k, uchar *d, uchar *out)
{
des_key_schedule ks;
des_cblock deskey;
str_to_key(k,(uchar *)deskey);
des_set_key(deskey,ks);
des_ecb_encrypt(d, out, ks, DES_DECRYPT);
}
void E1(uchar *k, uchar *d, uchar *out)
{
des_key_schedule ks;
des_cblock deskey;
str_to_key(k,(uchar *)deskey);
des_set_key(deskey,ks);
des_ecb_encrypt(d, out, ks, DES_ENCRYPT);
}
void E_P16(uchar *p14,uchar *p16)
{
uchar sp7[7];
/* the following constant makes us compatible with other
implementations. Note that publishing this constant does not reduce the
security of the encryption mechanism */
uchar sp8[] = {0xAA,0xD3,0xB4,0x35,0xB5,0x14,0x4,0xEE};
uchar x[8];
memset(sp7,'\0',7);
D1(sp7, sp8, x);
E1(p14, x, p16);
E1(p14+7, x, p16+8);
}
void E_P24(uchar *p21, uchar *c8, uchar *p24)
{
E1(p21, c8, p24);
E1(p21+7, c8, p24+8);
E1(p21+14, c8, p24+16);
}
/*
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 i, len;
int16 wpwd[129];
MDstruct MD;
/* Password cannot be longer than 128 characters */
len = strlen(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);
MDbegin(&MD);
for(i = 0; i + 64 <= len; i += 64)
MDupdate(&MD,wpwd + (i/2), 512);
MDupdate(&MD,wpwd + (i/2),(len-i)*8);
SIVAL(p16,0,MD.buffer[0]);
SIVAL(p16,4,MD.buffer[1]);
SIVAL(p16,8,MD.buffer[2]);
SIVAL(p16,12,MD.buffer[3]);
}
/* 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);
}
#else
void smbencrypt_dummy(void){}
#endif

330
source3/locking/locking.c Normal file
View File

@ -0,0 +1,330 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
Locking functions
Copyright (C) Andrew Tridgell 1992-1995
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "loadparm.h"
extern int DEBUGLEVEL;
extern connection_struct Connections[];
extern files_struct Files[];
pstring share_del_pending="";
/****************************************************************************
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,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,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,F_SETLK,offset,count,F_UNLCK);
if (!ok) {
*eclass = ERRDOS;
*ecode = ERRlock;
return False;
}
return True; /* Did unlock */
}
/*******************************************************************
name a share file
******************************************************************/
static BOOL share_name(int cnum,struct stat *st,char *name)
{
strcpy(name,lp_lockdir());
standard_sub(cnum,name);
trim_string(name,"","/");
if (!*name) return(False);
name += strlen(name);
sprintf(name,"/share.%d.%d",(int)st->st_dev,(int)st->st_ino);
return(True);
}
/*******************************************************************
use the fnum to get the share file name
******************************************************************/
static BOOL share_name_fnum(int fnum,char *name)
{
struct stat st;
if (fstat(Files[fnum].fd,&st) != 0) return(False);
return(share_name(Files[fnum].cnum,&st,name));
}
/*******************************************************************
get the share mode of a file using the fnum
******************************************************************/
int get_share_mode_by_fnum(int cnum,int fnum,int *pid)
{
struct stat sbuf;
if (fstat(Files[fnum].fd,&sbuf) == -1) return(0);
return(get_share_mode(cnum,&sbuf,pid));
}
/*******************************************************************
get the share mode of a file using the files name
******************************************************************/
int get_share_mode_byname(int cnum,char *fname,int *pid)
{
struct stat sbuf;
if (stat(fname,&sbuf) == -1) return(0);
return(get_share_mode(cnum,&sbuf,pid));
}
/*******************************************************************
get the share mode of a file
********************************************************************/
int get_share_mode(int cnum,struct stat *sbuf,int *pid)
{
pstring fname;
int fd2;
char buf[16];
int ret;
time_t t;
*pid = 0;
if (!share_name(cnum,sbuf,fname)) return(0);
fd2 = open(fname,O_RDONLY,0);
if (fd2 < 0) return(0);
if (read(fd2,buf,16) != 16) {
close(fd2);
unlink(fname);
return(0);
}
close(fd2);
t = IVAL(buf,0);
ret = IVAL(buf,4);
*pid = IVAL(buf,8);
if (IVAL(buf,12) != LOCKING_VERSION) {
if (!unlink(fname)) DEBUG(2,("Deleted old locking file %s",fname));
*pid = 0;
return(0);
}
if (*pid && !process_exists(*pid)) {
ret=0;
*pid = 0;
}
if (! *pid) unlink(fname); /* XXXXX race, race */
if (*pid)
DEBUG(5,("Read share file %s mode 0x%X pid=%d\n",fname,ret,*pid));
return(ret);
}
/*******************************************************************
del the share mode of a file, if we set it last
********************************************************************/
void del_share_mode(int fnum)
{
pstring fname;
int fd2;
char buf[16];
time_t t=0;
int pid=0;
BOOL del = False;
if (!share_name_fnum(fnum,fname)) return;
fd2 = open(fname,O_RDONLY,0);
if (fd2 < 0) return;
if (read(fd2,buf,16) != 16)
del = True;
close(fd2);
if (!del) {
t = IVAL(buf,0);
pid = IVAL(buf,8);
}
if (!del)
if (IVAL(buf,12) != LOCKING_VERSION || !pid || !process_exists(pid))
del = True;
if (!del && t == Files[fnum].open_time && pid==(int)getpid())
del = True;
if (del) {
if (!unlink(fname))
DEBUG(2,("Deleted share file %s\n",fname));
else {
DEBUG(3,("Pending delete share file %s\n",fname));
if (*share_del_pending) DEBUG(0,("Share del clash!\n"));
strcpy(share_del_pending,fname);
}
}
}
/*******************************************************************
set the share mode of a file
********************************************************************/
BOOL set_share_mode(int fnum,int mode)
{
pstring fname;
int fd2;
char buf[16];
int pid = (int)getpid();
if (!share_name_fnum(fnum,fname)) return(False);
{
int old_umask = umask(0);
fd2 = open(fname,O_WRONLY|O_CREAT|O_TRUNC,0644);
umask(old_umask);
}
if (fd2 < 0) {
DEBUG(2,("Failed to create share file %s\n",fname));
return(False);
}
SIVAL(buf,0,Files[fnum].open_time);
SIVAL(buf,4,mode);
SIVAL(buf,8,pid);
SIVAL(buf,12,LOCKING_VERSION);
if (write(fd2,buf,16) != 16) {
close(fd2);
unlink(fname);
return(False);
}
write(fd2,Files[fnum].name,strlen(Files[fnum].name)+1);
close(fd2);
DEBUG(3,("Created share file %s with mode 0x%X pid=%d\n",fname,mode,pid));
return(True);
}
/*******************************************************************
cleanup any stale share files
********************************************************************/
void clean_share_files(void)
{
char *lockdir = lp_lockdir();
void *dir;
char *s;
if (!*lockdir) return;
dir = opendir(lockdir);
if (!dir) return;
while ((s=readdirname(dir))) {
char buf[16];
int pid;
int fd;
pstring lname;
int dev,inode;
if (sscanf(s,"share.%d.%d",&dev,&inode)!=2) continue;
strcpy(lname,lp_lockdir());
trim_string(lname,NULL,"/");
strcat(lname,"/");
strcat(lname,s);
fd = open(lname,O_RDONLY,0);
if (fd < 0) continue;
if (read(fd,buf,16) != 16) {
close(fd);
if (!unlink(lname))
printf("Deleted corrupt share file %s\n",s);
continue;
}
close(fd);
pid = IVAL(buf,8);
if (IVAL(buf,12) != LOCKING_VERSION || !process_exists(pid)) {
if (!unlink(lname))
printf("Deleted stale share file %s\n",s);
}
}
closedir(dir);
}

58
source3/md4.h Normal file
View File

@ -0,0 +1,58 @@
/*
This code is from rfc1186.
*/
/*
** ********************************************************************
** md4.h -- Header file for implementation of **
** MD4 Message Digest Algorithm **
** Updated: 2/13/90 by Ronald L. Rivest **
** (C) 1990 RSA Data Security, Inc. **
** ********************************************************************
*/
/* MDstruct is the data structure for a message digest computation.
*/
typedef struct {
unsigned int buffer[4]; /* Holds 4-word result of MD computation */
unsigned char count[8]; /* Number of bits processed so far */
unsigned int done; /* Nonzero means MD computation finished */
} MDstruct, *MDptr;
/* MDbegin(MD)
** Input: MD -- an MDptr
** Initialize the MDstruct prepatory to doing a message digest
** computation.
*/
extern void MDbegin();
/* MDupdate(MD,X,count)
** Input: MD -- an MDptr
** X -- a pointer to an array of unsigned characters.
** count -- the number of bits of X to use (an unsigned int).
** Updates MD using the first "count" bits of X.
** The array pointed to by X is not modified.
** If count is not a multiple of 8, MDupdate uses high bits of
** last byte.
** This is the basic input routine for a user.
** The routine terminates the MD computation when count < 512, so
** every MD computation should end with one call to MDupdate with a
** count less than 512. Zero is OK for a count.
*/
extern void MDupdate();
/* MDprint(MD)
** Input: MD -- an MDptr
** Prints message digest buffer MD as 32 hexadecimal digits.
** Order is from low-order byte of buffer[0] to high-order byte
** of buffer[3].
** Each byte is printed with high-order hexadecimal digit first.
*/
extern void MDprint();
/*
** End of md4.h
*/

2318
source3/nameserv.c Normal file

File diff suppressed because it is too large Load Diff

303
source3/nmbsync.c Normal file
View File

@ -0,0 +1,303 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
NBT netbios routines to synchronise browse lists
Copyright (C) Andrew Tridgell 1994-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 "loadparm.h"
#include "nameserv.h"
extern int DEBUGLEVEL;
struct server_record *add_server_entry(char *name,int servertype,
int ttl,char *comment,BOOL replace);
/****************************************************************************
call a remote api
****************************************************************************/
static BOOL call_remote_api(int fd,int cnum,int uid,int timeout,
char *inbuf,char *outbuf,
int prcnt,int drcnt,
int mprcnt,int mdrcnt,
int *rprcnt,int *rdrcnt,
char *param,char *data,
char **rparam,char **rdata)
{
char *p1,*p2;
/* send a SMBtrans command */
bzero(outbuf,smb_size);
set_message(outbuf,14,0,True);
CVAL(outbuf,smb_com) = SMBtrans;
SSVAL(outbuf,smb_tid,cnum);
SSVAL(outbuf,smb_uid,uid);
p1 = smb_buf(outbuf);
strcpy(p1,"\\PIPE\\LANMAN");
p1 = skip_string(p1,1);
p2 = p1 + prcnt;
if (prcnt > 0)
memcpy(p1,param,prcnt);
if (drcnt > 0)
memcpy(p2,data,drcnt);
SSVAL(outbuf,smb_vwv0,prcnt); /* param count */
SSVAL(outbuf,smb_vwv1,drcnt); /* data count */
SSVAL(outbuf,smb_vwv2,mprcnt); /* mprcnt */
SSVAL(outbuf,smb_vwv3,mdrcnt); /* mdrcnt */
SSVAL(outbuf,smb_vwv4,0); /* msrcnt */
SSVAL(outbuf,smb_vwv5,0); /* flags */
SSVAL(outbuf,smb_vwv9,prcnt); /* pscnt */
SSVAL(outbuf,smb_vwv10,smb_offset(p1,outbuf)); /* psoff */
SSVAL(outbuf,smb_vwv11,drcnt); /* dscnt */
SSVAL(outbuf,smb_vwv12,smb_offset(p2,outbuf)); /* dsoff */
CVAL(outbuf,smb_vwv13) = 0; /* suwcnt */
set_message(outbuf,14,PTR_DIFF(p2+drcnt,smb_buf(outbuf)),False);
send_smb(fd,outbuf);
if (receive_smb(fd,inbuf,timeout) &&
CVAL(inbuf,smb_rcls) == 0)
{
if (rparam)
*rparam = inbuf+4 + SVAL(inbuf,smb_vwv4);
if (rdata)
*rdata = inbuf+4 + SVAL(inbuf,smb_vwv7);
if (rprcnt)
*rprcnt = SVAL(inbuf,smb_vwv3);
if (rdrcnt)
*rdrcnt = SVAL(inbuf,smb_vwv6);
return(True);
}
return(False);
}
/*******************************************************************
synchronise browse lists with another browse server
******************************************************************/
void sync_browse_lists(char *name,int name_type,char *myname,
char *domain,struct in_addr ip)
{
char *protocol = "LM1.2X002";
char *service = "IPC$";
char *dev = "IPC";
int timeout=2000;
char *inbuf=NULL;
pstring outbuf;
char *p;
int len;
uint32 sesskey;
int cnum,uid;
BOOL ret;
int fd = open_socket_out(SOCK_STREAM, &ip, SMB_PORT);
if (fd < 0) {
DEBUG(3,("Failed to connect to %s at %s\n",name,inet_ntoa(ip)));
return;
}
if (!(inbuf = (char *)malloc(0xFFFF+1024))) return;
/* put in the destination name */
len = 4;
p = outbuf+len;
name_mangle(name,p,name_type);
len += name_len(p);
/* and my name */
p = outbuf+len;
name_mangle(myname,p,0x20);
len += name_len(p);
_smb_setlen(outbuf,len);
CVAL(outbuf,0) = 0x81;
send_smb(fd,outbuf);
receive_smb(fd,inbuf,5000);
bzero(outbuf,smb_size);
/* setup the protocol string */
set_message(outbuf,0,strlen(protocol)+2,True);
p = smb_buf(outbuf);
*p++ = 2;
strcpy(p,protocol);
CVAL(outbuf,smb_com) = SMBnegprot;
CVAL(outbuf,smb_flg) = 0x8;
SSVAL(outbuf,smb_flg2,0x1);
send_smb(fd,outbuf);
bzero(inbuf,smb_size);
ret = receive_smb(fd,inbuf,timeout);
if (!ret || CVAL(inbuf,smb_rcls) || SVAL(inbuf,smb_vwv0)) {
DEBUG(3,("%s rejected the protocol\n",name));
close(fd);
if (inbuf) free(inbuf);
return;
}
sesskey = IVAL(inbuf,smb_vwv6);
bzero(outbuf,smb_size);
set_message(outbuf,10,2,True);
CVAL(outbuf,smb_com) = SMBsesssetupX;
CVAL(outbuf,smb_vwv0) = 0xFF;
SSVAL(outbuf,smb_vwv2,0xFFFF);
SSVAL(outbuf,smb_vwv3,2);
SSVAL(outbuf,smb_vwv4,1);
SIVAL(outbuf,smb_vwv5,sesskey);
SSVAL(outbuf,smb_vwv7,1);
send_smb(fd,outbuf);
bzero(inbuf,smb_size);
ret = receive_smb(fd,inbuf,timeout);
if (!ret || CVAL(inbuf,smb_rcls)) {
DEBUG(3,("%s rejected session setup\n",name));
close(fd);
if (inbuf) free(inbuf);
return;
}
uid = SVAL(inbuf,smb_uid);
bzero(outbuf,smb_size);
set_message(outbuf,4,2 + (2 + strlen(name) + 1 + strlen(service)) +
1 + strlen(dev),True);
CVAL(outbuf,smb_com) = SMBtconX;
SSVAL(outbuf,smb_uid,uid);
SSVAL(outbuf,smb_vwv0,0xFF);
SSVAL(outbuf,smb_vwv3,1);
p = smb_buf(outbuf) + 1;
strcpy(p, "\\\\");
strcat(p, name);
strcat(p, "\\");
strcat(p,service);
p = skip_string(p,1);
strcpy(p,dev);
send_smb(fd,outbuf);
bzero(inbuf,smb_size);
ret = receive_smb(fd,inbuf,timeout);
if (!ret || CVAL(inbuf,smb_rcls)) {
DEBUG(3,("%s rejected IPC connect (%d,%d)\n",name,
CVAL(inbuf,smb_rcls),SVAL(inbuf,smb_err)));
close(fd);
if (inbuf) free(inbuf);
return;
}
cnum = SVAL(inbuf,smb_tid);
/* now I need to send a NetServerEnum */
{
fstring param;
uint32 *typep;
char *rparam,*rdata;
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,1); /* level 1 */
SSVAL(p,2,0xFFFF - 500); /* buf length */
p += 4;
typep = (uint32 *)p;
p += 4;
strcpy(p,domain);
strupper(p);
p = skip_string(p,1);
SIVAL(typep,0,0x80000000); /* domain list */
if (call_remote_api(fd,cnum,uid,timeout,inbuf,outbuf,
PTR_DIFF(p,param),0,
8,0xFFFF - 500,
NULL,NULL,
param,NULL,
&rparam,&rdata) && SVAL(rparam,0)==0)
{
int converter=SVAL(rparam,2);
int count=SVAL(rparam,4);
int i;
char *p2 = rdata;
for (i=0;i<count;i++) {
char *sname = p2;
uint32 type = IVAL(p2,18);
int comment_offset = IVAL(p2,22) & 0xFFFF;
char *comment = comment_offset?(rdata+comment_offset-converter):"";
add_server_entry(sname,type,lp_max_ttl(),comment,False);
p2 += 26;
}
}
SIVAL(typep,0,0xFFFFFFFF); /* server list */
if (call_remote_api(fd,cnum,uid,timeout,inbuf,outbuf,
PTR_DIFF(p,param),0,
8,0xFFFF - 500,
NULL,NULL,
param,NULL,
&rparam,&rdata) && SVAL(rparam,0)==0)
{
int converter=SVAL(rparam,2);
int count=SVAL(rparam,4);
int i;
p = rdata;
for (i=0;i<count;i++) {
char *sname = p;
uint32 type = IVAL(p,18);
int comment_offset = IVAL(p,22) & 0xFFFF;
char *comment = comment_offset?(rdata+comment_offset-converter):"";
add_server_entry(sname,type,lp_max_ttl(),comment,False);
p += 26;
}
}
}
/* close up */
bzero(outbuf,smb_size);
set_message(outbuf,0,0,True);
CVAL(outbuf,smb_com) = SMBtdis;
SSVAL(outbuf,smb_uid,uid);
SSVAL(outbuf,smb_tid,cnum);
send_smb(fd,outbuf);
receive_smb(fd,inbuf,1000);
close(fd);
if (inbuf) free(inbuf);
}

1891
source3/param/loadparm.c Normal file

File diff suppressed because it is too large Load Diff

335
source3/param/params.c Normal file
View File

@ -0,0 +1,335 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
Parameter loading utlities
Copyright (C) Karl Auer 1993,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.
*/
/**************************************************************************
PARAMS.C
Copyright (C) 1990, 1991, 1992, 1993, 1994 Karl Auer
This module provides for streamlines retrieval of information from a
Windows-like parameter files. There is a function which will search for
all sections in the file and call a specified function with each. There is
a similar function which will call a specified function for all parameters
in a section. The idea is that you pass the addresses of suitable functions
to a single function in this module which will then enumerate all sections,
and within each section all parameters, to your program.
Parameter files contain text lines (newline delimited) which consist of
either a section name in square brackets or a parameter name, delimited
from the parameter value by an equals sign. Blank lines or lines where the
first non-whitespace character is a colon are ignored. All whitespace in
section names and parameter names is compressed to single spaces. Leading
and trailing whitespace on parameter names and parameter values is stripped.
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. Parameter names may not start
with a square bracket, an equals sign or a semicolon, for obvious reasons.
A sample parameter file might look like this:
[things]
this=1
that=2
[other things]
the other = 3
**************************************************************************/
#include "includes.h"
#include "smb.h"
#include "params.h"
/* local variable pointing to passed filename */
static char *pszParmFile = NULL;
extern int DEBUGLEVEL;
/* local prototypes */
static BOOL enumerate_parameters(FILE *infile, PM_PARMFUNC pfunc);
static BOOL enumerate_sections(FILE *infile,
PM_SECFUNC sfunc, PM_PARMFUNC pfunc);
/* prototypes for local toolbox functions */
static void trimleft(char *psz);
static void trimright(char *psz);
static void collapse_spaces(char *psz);
static int firstnonwhite(char *psz);
/**************************************************************************
Identifies all parameters in the current section, calls the parameter
function for each. Ignores comment lines, stops and backs up in file when
a section is encountered. Returns True on success, False on error.
**************************************************************************/
static BOOL enumerate_parameters(FILE *fileIn, PM_PARMFUNC pfunc)
{
pstring szBuf;
char *pszTemp;
BOOL bRetval;
long lFileOffset;
int cTemp;
BOOL bParmFound;
bRetval = False;
bParmFound = False;
while (True)
{
/* first remember where we are */
if ((lFileOffset = ftell(fileIn)) >= 0L)
{
/* then get and check a line */
if (fgets_slash(szBuf, sizeof(szBuf)-1, fileIn) == NULL)
{
/* stop - return OK unless file error */
bRetval = !ferror(fileIn);
if (!bRetval)
DEBUG(0,( "Read error on configuration file (enumerating parameters)!\n"));
break;
}
else
/* if first non-white is a '[', stop (new section) */
if ((cTemp = firstnonwhite(szBuf)) == '[')
{
/* restore position to start of new section */
if (fseek(fileIn, lFileOffset, SEEK_SET) < 0L)
{
DEBUG(0,( "Seek error on configuration file!\n"));
break;
}
/* return success */
bRetval = True;
break;
}
else
/* if it's a semicolon or line is blank, ignore the line */
if (!cTemp || strchr(";#",cTemp))
{
continue;
}
else
/* if no equals sign and line contains non-whitespace */
/* then line is badly formed */
if ((pszTemp = strchr(szBuf, '=')) == NULL)
{
DEBUG(0,( "Ignoring badly formed line: %s", szBuf));
}
else
{
/* Note that we have found a parameter */
bParmFound = True;
/* cut line at the equals sign */
*pszTemp++ = '\0';
/* trim leading and trailing space from both halves */
trimright(szBuf);
trimleft(szBuf);
trimright(pszTemp);
trimleft(pszTemp);
/* process the parameter iff passed pointer not NULL */
if (pfunc != NULL)
if (!pfunc(szBuf, pszTemp))
break;
}
}
}
return (bRetval);
}
/***********************************************************************
Close up s by n chars, at offset start.
***********************************************************************/
static void closestr(char *s, int start, int n)
{
char *src;
char *dest;
int len;
if (n > 0)
if ((src = dest = s) != NULL)
{
len = strlen(s);
if (start >= 0 && start < len - n)
{
src += start + n;
dest += start;
while (*src)
*dest++ = *src++;
*dest = '\0';
}
}
}
/**************************************************************************
Identifies all sections in the parameter file, calls passed section_func()
for each, passing the section name, then calls enumerate_parameters().
Returns True on success, False on failure. Note that the section and
parameter names will have all internal whitespace areas collapsed to a
single space for processing.
**************************************************************************/
static BOOL enumerate_sections(FILE *fileIn,
PM_SECFUNC sfunc, PM_PARMFUNC pfunc)
{
pstring szBuf;
BOOL bRetval;
BOOL bSectionFound;
/* this makes sure we get include lines right */
enumerate_parameters(fileIn, pfunc);
bRetval = False;
bSectionFound = False;
while (True)
{
if (fgets_slash(szBuf, sizeof(szBuf)-1, fileIn) == NULL)
{
/* stop - return OK unless file error */
bRetval = !ferror(fileIn);
if (!bRetval)
DEBUG(0,( "Read error on configuration file (enumerating sections)!\n"));
break;
}
else
{
trimleft(szBuf);
trimright(szBuf);
if (szBuf[0] == '[')
{
closestr(szBuf, 0, 1);
if (strlen(szBuf) > 1)
if (szBuf[strlen(szBuf) - 1] == ']')
{
/* found a section - note the fact */
bSectionFound = True;
/* remove trailing metabracket */
szBuf[strlen(szBuf) - 1] = '\0';
/* remove leading and trailing whitespace from name */
trimleft(szBuf);
trimright(szBuf);
/* reduce all internal whitespace to one space */
collapse_spaces(szBuf);
/* process it - stop if the processing fails */
if (sfunc != NULL)
if (!sfunc(szBuf))
break;
if (!enumerate_parameters(fileIn, pfunc))
break;
}
}
}
}
return (bRetval);
}
/**************************************************************************
Process the passed parameter file.
Returns True if successful, else False.
**************************************************************************/
BOOL pm_process(char *pszFileName, PM_SECFUNC sfunc, PM_PARMFUNC pfunc)
{
FILE *fileIn;
BOOL bRetval;
bRetval = False;
/* record the filename for use in error messages one day... */
pszParmFile = pszFileName;
if (pszParmFile == NULL || strlen(pszParmFile) < 1)
DEBUG(0,( "No configuration filename specified!\n"));
else
if ((fileIn = fopen(pszParmFile, "r")) == NULL)
DEBUG(0,( "Unable to open configuration file \"%s\"!\n", pszParmFile));
else
{
DEBUG(2,( "Processing configuration file \"%s\"\n", pszParmFile));
bRetval = enumerate_sections(fileIn, sfunc, pfunc);
fclose(fileIn);
}
if (!bRetval)
DEBUG(0,("pm_process retuned false\n"));
return (bRetval);
}
/**************************************************************************
Strip all leading whitespace from a string.
**************************************************************************/
static void trimleft(char *psz)
{
char *pszDest;
pszDest = psz;
if (psz != NULL)
{
while (*psz != '\0' && isspace(*psz))
psz++;
while (*psz != '\0')
*pszDest++ = *psz++;
*pszDest = '\0';
}
}
/**************************************************************************
Strip all trailing whitespace from a string.
**************************************************************************/
static void trimright(char *psz)
{
char *pszTemp;
if (psz != NULL && psz[0] != '\0')
{
pszTemp = psz + strlen(psz) - 1;
while (isspace(*pszTemp))
*pszTemp-- = '\0';
}
}
/***********************************************************************
Collapse each whitespace area in a string to a single space.
***********************************************************************/
static void collapse_spaces(char *psz)
{
while (*psz)
if (isspace(*psz))
{
*psz++ = ' ';
trimleft(psz);
}
else
psz++;
}
/**************************************************************************
Return the value of the first non-white character in the specified string.
The terminating NUL counts as non-white for the purposes of this function.
Note - no check for a NULL string! What would we return?
**************************************************************************/
static int firstnonwhite(char *psz)
{
while (isspace(*psz) && (*psz != '\0'))
psz++;
return (*psz);
}

304
source3/passdb/smbpass.c Normal file
View File

@ -0,0 +1,304 @@
#ifdef SMB_PASSWD
/*
* Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
* Copyright (C) Andrew Tridgell 1992-1995 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"
#include "loadparm.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, 0666);
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(p,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(p,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;
}
#else
void
smbpass_dummy(void)
{
} /* To avoid compiler complaints */
#endif

383
source3/printing/pcap.c Normal file
View File

@ -0,0 +1,383 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
printcap parsing
Copyright (C) Karl Auer 1993,1994
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"
#include "loadparm.h"
#include "pcap.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) strcpy(comment,name);
strcpy(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);
}

859
source3/printing/printing.c Normal file
View File

@ -0,0 +1,859 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
printing routines
Copyright (C) Andrew Tridgell 1992-1995
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "loadparm.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 = 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
strcpy(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);
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;
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;
jobtime = mktime(t);
}
}
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);
strcpy(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);
}
/*******************************************************************
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)
{
strcpy(tmp,p+1);
strcpy(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)
{
strcpy(tmp,p+1);
strcpy(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;
strcpy(tmp,p+1);
strcpy(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)
{
strcpy(tmp,p+1);
strcpy(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);
}
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;
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)))
strcpy(buf->user,sesssetup_user);
}
#endif
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();
int lfd = -1;
*line = 0;
check_lpq_cache(snum);
if (!printername || !*printername)
{
DEBUG(6,("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);
}
strcpy(syscmd,lpq_command);
string_sub(syscmd,"%p",printername);
standard_sub(cnum,syscmd);
sprintf(outfile,"/tmp/lpq.%08x",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) {
lfd = file_lock(outfile,LPQ_LOCK_TIMEOUT);
if (lfd<0 ||
(!fstat(lfd,&sbuf) && (time(NULL) - sbuf.st_mtime)<cachetime)) {
DEBUG(3,("Using cached lpq output\n"));
dorun = False;
file_unlock(lfd); lfd = -1;
}
}
}
if (dorun) {
ret = smbrun(syscmd,outfile);
DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
}
lpq_cache_reset[snum] = False;
f = fopen(outfile,"r");
if (!f) {
if (lfd >= 0) file_unlock(lfd);
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 (lfd >= 0) file_unlock(lfd);
if (!cachetime)
unlink(outfile);
else
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);
strcpy(syscmd,lprm_command);
string_sub(syscmd,"%p",printername);
string_sub(syscmd,"%j",jobstr);
standard_sub(cnum,syscmd);
ret = smbrun(syscmd,NULL);
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);
strcpy(syscmd,lpstatus_command);
string_sub(syscmd,"%p",printername);
string_sub(syscmd,"%j",jobstr);
standard_sub(cnum,syscmd);
ret = smbrun(syscmd,NULL);
DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
lpq_reset(snum); /* queue has changed */
}

View File

@ -0,0 +1,74 @@
#!/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);
}
}
}

42
source3/script/installbin.sh Executable file
View File

@ -0,0 +1,42 @@
#!/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"
======================================================================
EOF
exit 0

35
source3/script/installman.sh Executable file
View File

@ -0,0 +1,35 @@
#!/bin/sh
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
exit 1
fi
fi
done
cp $SRCDIR../docs/*.1 $MANDIR/man1
cp $SRCDIR../docs/*.5 $MANDIR/man5
cp $SRCDIR../docs/*.8 $MANDIR/man8
cp $SRCDIR../docs/*.7 $MANDIR/man7
echo Setting permissions on man pages
chmod 0644 $MANDIR/man1/smbstatus.1
chmod 0644 $MANDIR/man1/smbclient.1
chmod 0644 $MANDIR/man1/smbrun.1
chmod 0644 $MANDIR/man1/testparm.1
chmod 0644 $MANDIR/man1/testprns.1
chmod 0644 $MANDIR/man1/smbtar.1
chmod 0644 $MANDIR/man5/smb.conf.5
chmod 0644 $MANDIR/man7/samba.7
chmod 0644 $MANDIR/man8/smbd.8
chmod 0644 $MANDIR/man8/nmbd.8
echo Man pages installed
exit 0

6
source3/script/mksmbpasswd.sh Executable file
View File

@ -0,0 +1,6 @@
#!/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) }
'

15
source3/script/revert.sh Executable file
View File

@ -0,0 +1,15 @@
#!/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

141
source3/script/smbtar Normal file
View File

@ -0,0 +1,141 @@
#!/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";;
*) # 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="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

View File

@ -0,0 +1,14 @@
#!/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")
}
}'

376
source3/smbd/chgpasswd.c Normal file
View File

@ -0,0 +1,376 @@
/* 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"
#include "loadparm.h"
extern int DEBUGLEVEL;
#ifdef ALLOW_CHANGE_PASSWORD
#define MINPASSWDLENGTH 5
#define BUFSIZE 512
static int findpty(char **slave)
{
int master;
#ifdef SVR4
extern char *ptsname();
#else
static char line[12] = "/dev/ptyXX";
void *dirp;
char *dpname;
#endif
#ifdef SVR4
if ((master = open("/dev/ptmx", O_RDWR)) >= 1) {
grantpt(master);
unlockpt(master);
*slave = ptsname(master);
return (master);
}
#else
dirp = OpenDir("/dev");
if (!dirp) return(-1);
while ((dpname = ReadDirName(dirp)) != NULL) {
if (strncmp(dpname, "pty", 3) == 0 && strlen(dpname) == 5) {
line[8] = dpname[3];
line[9] = dpname[4];
if ((master = open(line, O_RDWR)) >= 0) {
line[5] = 't';
*slave = line;
CloseDir(dirp);
return (master);
}
}
}
CloseDir(dirp);
#endif
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
setuid(0);
#endif
/* 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);
}
#ifdef SVR4
ioctl(slave, I_PUSH, "ptem");
ioctl(slave, I_PUSH, "ldterm");
#else
if (ioctl(slave,TIOCSCTTY,0) <0) {
DEBUG(3,("Error in ioctl call for slave pty\n"));
/* return(False); */
}
#endif
/* 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, True);
if (m < 0)
return False;
n += m;
buf[n] = 0;
{
pstring s1,s2;
strcpy(s1,buf);
strcpy(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 = 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))
strcpy(passwordprogram,PASSWD_PROGRAM);
strcpy(chatsequence,PASSWD_CHAT);
#else
strcpy(passwordprogram,lp_passwd_program());
strcpy(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

955
source3/smbd/dir.c Normal file
View File

@ -0,0 +1,955 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
Directory handling routines
Copyright (C) Andrew Tridgell 1992-1995
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "loadparm.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)
{
if (dirptrs[key].valid) {
if (lastused) dirptrs[key].lastused = lastused;
if (!dirptrs[key].ptr) {
if (dptrs_open >= MAXDIR)
dptr_idleoldest();
DEBUG(4,("Reopening dptr key %d\n",key));
if ((dirptrs[key].ptr = OpenDir(dirptrs[key].path)))
dptrs_open++;
}
return(dirptrs[key].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)
{
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(directory);
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(-1);
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);
}
/****************************************************************************
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;
*path = *pathreal = *filename = 0;
isrootdir = (strequal(Connections[cnum].dirpath,"./") ||
strequal(Connections[cnum].dirpath,".") ||
strequal(Connections[cnum].dirpath,"/"));
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;
strcpy(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;
strcpy(fname,filename);
*path = 0;
strcpy(path,Connections[cnum].dirpath);
strcat(path,"/");
strcpy(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 (((*mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0)
{
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(char *name)
{
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 (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)
{
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; entry->next; entry=entry->next) ;
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);
} 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

2779
source3/smbd/ipc.c Normal file

File diff suppressed because it is too large Load Diff

610
source3/smbd/mangle.c Normal file
View File

@ -0,0 +1,610 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
Name mangling
Copyright (C) Andrew Tridgell 1992-1995
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "loadparm.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)
{
int len;
char *dot_pos;
char *slash_pos = strrchr(fname,'/');
int l;
if (slash_pos) fname = slash_pos+1;
len = strlen(fname);
dot_pos = strchr(fname,'.');
DEBUG(5,("checking %s for 8.3\n",fname));
if (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 */
{
char *p = fname;
#ifdef KANJI
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++;
}
#endif /* KANJI */
}
/* 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],'.'))
{
strcpy(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! */
strcpy(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(int v)
{
v = v % 36;
if (v < 10)
return('0'+v);
else /* needed to work around a DEC C compiler bug */
return('A' + (v-10));
}
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++;
start++; /* Skip the ( */
if (!*start)
continue; /* Always check for the end. */
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 == '*') {
strcpy(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));
strcpy(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 (isdoschar(*p) && *p != '.')
extension[extlen++] = *p;
p++;
}
extension[extlen] = 0;
}
}
p = s;
while (*p && baselen < 5)
{
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;
}
#ifdef KANJI
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);
#endif
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)) {
if (!lp_manglednames(snum)) return(False);
/* mangle it into 8.3 */
push_mangled_name(OutName);
mangle_name_83(OutName);
}
return(True);
}

204
source3/smbd/message.c Normal file
View File

@ -0,0 +1,204 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
SMB messaging
Copyright (C) Andrew Tridgell 1992-1995
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
This file handles the messaging system calls for winpopup style
messages
*/
#include "includes.h"
#include "loadparm.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;
FILE *f;
int i;
if (! (*lp_msg_command()))
{
DEBUG(1,("no messaging command specified\n"));
msgpos = 0;
return;
}
/* put it in a temporary file */
sprintf(s,"/tmp/msg.XXXXXX");
strcpy(name,(char *)mktemp(s));
f = fopen(name,"w");
if (!f)
{
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++;
fputc(msgbuf[i++],f);
}
fclose(f);
/* run the command */
if (*lp_msg_command())
{
strcpy(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);
}
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;
strcpy(msgfrom,orig);
strcpy(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;
strcpy(msgfrom,orig);
strcpy(msgto,dest);
DEBUG(3,("%s SMBsendstrt (from %s to %s)\n",timestring(),orig,dest));
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);
}

1416
source3/smbd/password.c Normal file

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More