mirror of
https://github.com/samba-team/samba.git
synced 2025-03-24 10:50:22 +03:00
Initial version imported to CVS
(This used to be commit 291551d80711daab7b7581720bcd9a08d6096517)
This commit is contained in:
commit
0e8fd33987
339
COPYING
Normal file
339
COPYING
Normal 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
111
README
Normal 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
119
docs/THANKS
Normal 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
129
docs/announce
Normal 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
165
docs/history
Normal 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
175
docs/htmldocs/wfw_slip.htm
Normal 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
491
docs/manpages/nmbd.8
Normal 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
190
docs/manpages/samba.7
Normal 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
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
1133
docs/manpages/smbclient.1
Normal file
File diff suppressed because it is too large
Load Diff
407
docs/manpages/smbd.8
Normal file
407
docs/manpages/smbd.8
Normal 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
70
docs/manpages/smbrun.1
Normal 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
52
docs/manpages/smbstatus.1
Normal 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
167
docs/manpages/smbtar.1
Normal 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
104
docs/manpages/testparm.1
Normal 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
107
docs/manpages/testprns.1
Normal 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
26
docs/samba.lsm
Normal 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
145
docs/textdocs/BROWSING.txt
Normal 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
123
docs/textdocs/BUGS.txt
Normal 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
237
docs/textdocs/DIAGNOSIS.txt
Normal 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
69
docs/textdocs/DNIX.txt
Normal 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
68
docs/textdocs/DOMAIN.txt
Normal 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.
|
||||
|
||||
|
333
docs/textdocs/ENCRYPTION.txt
Normal file
333
docs/textdocs/ENCRYPTION.txt
Normal 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
202
docs/textdocs/HINTS.txt
Normal 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.
|
||||
|
||||
|
27
docs/textdocs/INSTALL.sambatar
Normal file
27
docs/textdocs/INSTALL.sambatar
Normal 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
96
docs/textdocs/PROJECTS
Normal 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
|
||||
========================================================================
|
42
docs/textdocs/Passwords.txt
Normal file
42
docs/textdocs/Passwords.txt
Normal 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.
|
||||
|
||||
|
79
docs/textdocs/README.DCEDFS
Normal file
79
docs/textdocs/README.DCEDFS
Normal 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
124
docs/textdocs/README.jis
Normal 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
|
||||
|
15
docs/textdocs/README.sambatar
Normal file
15
docs/textdocs/README.sambatar
Normal 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
12
docs/textdocs/SCO.txt
Normal 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.
|
||||
|
40
docs/textdocs/SMBTAR.notes
Normal file
40
docs/textdocs/SMBTAR.notes
Normal 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
272
docs/textdocs/Speed.txt
Normal 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
376
docs/textdocs/Support.txt
Normal 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
220
docs/textdocs/UNIX-SMB.txt
Normal 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
56
docs/textdocs/WinNT.txt
Normal 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
6
examples/README
Normal 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
4
examples/dce-dfs/README
Normal 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
42
examples/dce-dfs/smb.conf
Normal 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
|
||||
|
47
examples/misc/extra_smbstatus
Normal file
47
examples/misc/extra_smbstatus
Normal 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
45
examples/misc/wall.perl
Normal 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
77
examples/printing/smbprint
Executable 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
|
52
examples/printing/smbprint.sysv
Normal file
52
examples/printing/smbprint.sysv
Normal 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
2
examples/simple/README
Normal file
@ -0,0 +1,2 @@
|
||||
This is the "original" sample config file.
|
||||
|
165
examples/simple/smb.conf
Normal file
165
examples/simple/smb.conf
Normal 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
8
examples/tridge/README
Normal 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
101
examples/tridge/smb.conf
Normal 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
|
14
examples/tridge/smb.conf.WinNT
Normal file
14
examples/tridge/smb.conf.WinNT
Normal file
@ -0,0 +1,14 @@
|
||||
#log level = 4
|
||||
#readraw = no
|
||||
#writeraw = no
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
21
examples/tridge/smb.conf.fjall
Normal file
21
examples/tridge/smb.conf.fjall
Normal 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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
14
examples/tridge/smb.conf.lapland
Normal file
14
examples/tridge/smb.conf.lapland
Normal file
@ -0,0 +1,14 @@
|
||||
#log level = 4
|
||||
#readraw = no
|
||||
#writeraw = no
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
14
examples/tridge/smb.conf.vittjokk
Normal file
14
examples/tridge/smb.conf.vittjokk
Normal file
@ -0,0 +1,14 @@
|
||||
;protocol = LANMAN2
|
||||
log level = 2
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
1872
source3/change-log
Normal file
1872
source3/change-log
Normal file
File diff suppressed because it is too large
Load Diff
4534
source3/client/client.c
Normal file
4534
source3/client/client.c
Normal file
File diff suppressed because it is too large
Load Diff
1713
source3/client/clitar.c
Normal file
1713
source3/client/clitar.c
Normal file
File diff suppressed because it is too large
Load Diff
80
source3/include/byteorder.h
Normal file
80
source3/include/byteorder.h
Normal 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
61
source3/include/charset.h
Normal 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
17
source3/include/clitar.h
Normal 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
1154
source3/include/includes.h
Normal file
File diff suppressed because it is too large
Load Diff
130
source3/include/kanji.h
Normal file
130
source3/include/kanji.h
Normal 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
167
source3/include/local.h
Normal 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
184
source3/include/nameserv.h
Normal 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
1006
source3/include/smb.h
Normal file
File diff suppressed because it is too large
Load Diff
241
source3/include/trans2.h
Normal file
241
source3/include/trans2.h
Normal 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
|
||||
|
||||
|
||||
|
1
source3/include/version.h
Normal file
1
source3/include/version.h
Normal file
@ -0,0 +1 @@
|
||||
#define VERSION "1.9.16alpha1"
|
48
source3/include/vt_mode.h
Normal file
48
source3/include/vt_mode.h
Normal 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
389
source3/lib/access.c
Normal 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
126
source3/lib/charcnv.c
Normal 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
111
source3/lib/charset.c
Normal 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
86
source3/lib/fault.c
Normal 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
166
source3/lib/getsmbpass.c
Normal 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
895
source3/lib/kanji.c
Normal 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
299
source3/lib/md4.c
Normal 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
222
source3/lib/system.c
Normal 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
782
source3/lib/ufc.c
Normal 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
246
source3/lib/username.c
Normal 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
4510
source3/lib/util.c
Normal file
File diff suppressed because it is too large
Load Diff
936
source3/libsmb/nmblib.c
Normal file
936
source3/libsmb/nmblib.c
Normal 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
202
source3/libsmb/smbencrypt.c
Normal 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
330
source3/locking/locking.c
Normal 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
58
source3/md4.h
Normal 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
2318
source3/nameserv.c
Normal file
File diff suppressed because it is too large
Load Diff
303
source3/nmbsync.c
Normal file
303
source3/nmbsync.c
Normal 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
1891
source3/param/loadparm.c
Normal file
File diff suppressed because it is too large
Load Diff
335
source3/param/params.c
Normal file
335
source3/param/params.c
Normal 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
304
source3/passdb/smbpass.c
Normal 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
383
source3/printing/pcap.c
Normal 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
859
source3/printing/printing.c
Normal 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 */
|
||||
}
|
||||
|
||||
|
74
source3/script/addtosmbpass
Normal file
74
source3/script/addtosmbpass
Normal 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
42
source3/script/installbin.sh
Executable 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
35
source3/script/installman.sh
Executable 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
6
source3/script/mksmbpasswd.sh
Executable 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
15
source3/script/revert.sh
Executable 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
141
source3/script/smbtar
Normal 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
|
||||
|
||||
|
14
source3/script/updatesmbpasswd.sh
Executable file
14
source3/script/updatesmbpasswd.sh
Executable 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
376
source3/smbd/chgpasswd.c
Normal 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
955
source3/smbd/dir.c
Normal 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
2779
source3/smbd/ipc.c
Normal file
File diff suppressed because it is too large
Load Diff
610
source3/smbd/mangle.c
Normal file
610
source3/smbd/mangle.c
Normal 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
204
source3/smbd/message.c
Normal 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
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
Loading…
x
Reference in New Issue
Block a user