Add all the source files from the old CVS tree,
add the 5 missing chapters from the HOWTO
and add jht's Samba by Example book.
(This used to be commit 9fb5bcb93e
)
277
docs/Makefile.in
Normal file
@ -0,0 +1,277 @@
|
||||
#################################################################
|
||||
# Makefile.in for Samba Documentation
|
||||
# Authors:
|
||||
# James Moore <jmoore@php.net>
|
||||
# Gerald Carter <jerry@samba.org>
|
||||
# Jelmer Vernooij <jelmer@samba.org>
|
||||
#
|
||||
# Please see http://www.samba.org/samba/cvs.html
|
||||
# for information on getting the latest
|
||||
# source and documentation source files.
|
||||
#
|
||||
#
|
||||
|
||||
# Programs
|
||||
WGET = @WGET@
|
||||
XSLTPROC = @XSLTPROC@
|
||||
DVIPS = @DVIPS@
|
||||
CVS2CL = @CVS2CL@
|
||||
PNGTOPNM = @PNGTOPNM@
|
||||
EPSTOPNM = @EPSTOPNM@
|
||||
PNMTOPNG = @PNMTOPNG@
|
||||
PNMTOPS = @PNMTOPS@
|
||||
XMLTO = @XMLTO@
|
||||
PLUCKERBUILD = @PLUCKERBUILD@
|
||||
PDFLATEX = TEXINPUTS=xslt/latex:.: @PDFLATEX@
|
||||
LATEX = TEXINPUTS=xslt/latex:.: @LATEX@
|
||||
RM = @RM@
|
||||
ifndef DEBUG_LATEX
|
||||
PDFLATEX += --interaction nonstopmode
|
||||
LATEX += --interaction nonstopmode
|
||||
endif
|
||||
|
||||
# Paths
|
||||
OUTPUTDIR = output
|
||||
SRCDIR = @srcdir@
|
||||
MANDIR=$(OUTPUTDIR)/manpages
|
||||
EPSTOPDF = @EPSTOPDF@
|
||||
MANPROJDOC = manpages
|
||||
PROJDOC = projdoc
|
||||
MAKEINDEX = @MAKEINDEX@
|
||||
IMAGEPROJDIR = $(PROJDOC)/imagefiles
|
||||
GUIDEDOC = guide
|
||||
EXAMPLESDIR = examples
|
||||
DEVDOC = devdoc
|
||||
SMBDOTCONFDOC = smbdotconf
|
||||
PSDIR = $(OUTPUTDIR)
|
||||
PDFDIR = $(OUTPUTDIR)
|
||||
DVIDIR = $(OUTPUTDIR)
|
||||
TXTDIR = $(OUTPUTDIR)/textdocs
|
||||
FAQPROJDOC = faq
|
||||
FAQDIR = $(OUTPUTDIR)/faq
|
||||
HTMLDIR=$(OUTPUTDIR)/htmldocs
|
||||
PLUCKERDIR=$(OUTPUTDIR)/plucker
|
||||
|
||||
# Lists of files to process
|
||||
LATEX_FIGURES = xslt/figures/caution.pdf xslt/figures/important.pdf xslt/figures/note.pdf xslt/figures/tip.pdf xslt/figures/warning.pdf
|
||||
MANPAGES_SOURCES = $(wildcard $(MANPROJDOC)/*.?.xml)
|
||||
MANPAGES = $(patsubst $(MANPROJDOC)/%.xml,$(MANDIR)/%,$(MANPAGES_SOURCES)) $(MANDIR)/smb.conf.5
|
||||
MANPAGES_HTML = $(patsubst $(MANPROJDOC)/%.xml,$(HTMLDIR)/%.html,$(MANPAGES_SOURCES)) $(HTMLDIR)/smb.conf.5.html
|
||||
MANPAGES_PLUCKER = $(patsubst $(MANPROJDOC)/%.xml,$(PLUCKERDIR)/%.pdb,$(MANPAGES_SOURCES)) $(PLUCKERDIR)/smb.conf.5.pdb
|
||||
|
||||
PROJDOC_IMAGES_PNG = $(wildcard $(IMAGEPROJDIR)/*.png)
|
||||
PROJDOC_IMAGES_EPS=$(patsubst %.png,%.eps,$(wildcard $(IMAGEPROJDIR)/*.png))
|
||||
PROJDOC_DEPS = $(PROJDOC)/*.xml $(PROJDOC)/attributions.xml $(MANPROJDOC)/*.xml $(SMBDOTCONFDOC)/smb.conf.5.xml $(SMBDOTCONFDOC)/parameters.all.xml $(SMBDOTCONFDOC)/parameters.global.xml $(SMBDOTCONFDOC)/parameters.service.xml
|
||||
DEVDOC_DEPS = $(DEVDOC)/*.xml $(DEVDOC)/attributions.xml
|
||||
|
||||
all:
|
||||
@echo "Supported make targets:"
|
||||
@echo "release - Build the docs needed for a Samba release"
|
||||
@echo "pdf - Build PDF version of book"
|
||||
@echo "tex - Build Latex version of book"
|
||||
@echo "dvi - Build Device Independant File of book"
|
||||
@echo "ps - Build PostScript version of book"
|
||||
@echo "manpages - Build manpages"
|
||||
@echo "txt - Build plain text version of HOWTO Collection and Developers Guide"
|
||||
@echo -n "html-single - Build single file HTML version of HOWTO Collection"
|
||||
@echo " and developers guide"
|
||||
@echo "html - Build HTML version of HOWTO Collection and Developers Guide"
|
||||
@echo "htmlman - Build html version of manpages"
|
||||
@echo "htmlfaq - Build html version of the FAQ"
|
||||
@echo "plucker - Build HOWTO, Developers Guide, man pages, and FAQ in Plucker format for PDA"
|
||||
@echo "undocumented - Output list of undocumented smb.conf options"
|
||||
@echo "samples - Extract examples"
|
||||
@echo "files - Extract other files"
|
||||
@echo "everything - Build all of the above"
|
||||
|
||||
everything: manpages pdf html-single html htmlman htmlfaq txt ps
|
||||
|
||||
release: manpages htmlman html html-single htmlfaq pdf
|
||||
|
||||
# Global rules
|
||||
|
||||
pdf: $(PDFDIR) $(PDFDIR)/Samba-HOWTO-Collection.pdf $(PDFDIR)/Samba-Developers-Guide.pdf
|
||||
|
||||
dvi: $(DVIDIR) $(DVIDIR)/Samba-HOWTO-Collection.dvi $(DVIDIR)/Samba-Developers-Guide.dvi
|
||||
|
||||
ps: $(PSDIR) $(PSDIR)/Samba-HOWTO-Collection.ps $(PSDIR)/Samba-Developers-Guide.ps
|
||||
|
||||
txt: $(TXTDIR) $(TXTDIR)/Samba-HOWTO-Collection.txt $(TXTDIR)/Samba-Developers-Guide.txt
|
||||
|
||||
htmlman: $(HTMLDIR) $(MANPAGES_HTML) CSS
|
||||
|
||||
htmlfaq: $(HTMLDIR) CSS
|
||||
$(XSLTPROC) --stringparam base.dir "$(FAQDIR)/" --stringparam root.filename samba-faq xslt/html-chunk.xsl $(FAQPROJDOC)/sambafaq.xml
|
||||
html-single: $(HTMLDIR) CSS $(HTMLDIR)/Samba-HOWTO-Collection.html $(HTMLDIR)/Samba-Developers-Guide.html
|
||||
@if [ ! -d $(HTMLDIR)/images/ ]; then \
|
||||
mkdir $(HTMLDIR)/images/; \
|
||||
fi \
|
||||
&& cp -p projdoc/imagefiles/*png $(HTMLDIR)/images/
|
||||
|
||||
html: $(HTMLDIR) CSS Samba-HOWTO-Collection.xml $(HTMLDIR)/Samba-Developers-Guide.html
|
||||
$(XSLTPROC) -o "$(HTMLDIR)/" xslt/html-chunk.xsl Samba-HOWTO-Collection.xml
|
||||
@if [ ! -d $(HTMLDIR)/images/ ]; then \
|
||||
mkdir $(HTMLDIR)/images/; \
|
||||
fi \
|
||||
&& cp -p projdoc/imagefiles/*png $(HTMLDIR)/images/
|
||||
|
||||
manpages: $(MANDIR) $(MANPAGES)
|
||||
|
||||
tex: Samba-HOWTO-Collection.tex Samba-Developers-Guide.tex gpl.tex
|
||||
|
||||
plucker: html-single htmlman htmlfaq $(PLUCKERDIR) $(MANPAGES_PLUCKER) $(PLUCKERDIR)/Samba-Developers-Guide.pdb $(PLUCKERDIR)/Samba-HOWTO-Collection.pdb
|
||||
$(PLUCKERBUILD) -v -M2 --stayonhost --noimages --zlib-compression -H file:$(FAQDIR)/samba-faq.html -f samba-faq -p $(PLUCKERDIR)
|
||||
|
||||
Samba-HOWTO-Collection.xml: $(PROJDOC)/samba-doc.xml $(PROJDOC_DEPS)
|
||||
$(XSLTPROC) --stringparam noreference 1 --xinclude --output $@ xslt/expand-sambadoc.xsl $<
|
||||
|
||||
Samba-Guide.xml: $(GUIDEDOC)/guide-main.xml
|
||||
$(XSLTPROC) --stringparam noreference 1 --xinclude --output $@ xslt/expand-sambadoc.xsl $<
|
||||
|
||||
Samba-Developers-Guide.xml: $(DEVDOC)/dev-doc.xml $(DEVDOC_DEPS)
|
||||
$(XSLTPROC) --stringparam noreference 1 --xinclude --output $@ xslt/expand-sambadoc.xsl $<
|
||||
|
||||
$(PROJDOC)/attributions.xml: $(PROJDOC)/samba-doc.xml
|
||||
@echo > $@ # Make sure we don't get recursive dependencies, etc!
|
||||
$(XSLTPROC) --output $@ xslt/generate-attributions.xsl $<
|
||||
|
||||
$(DEVDOC)/attributions.xml: $(DEVDOC)/dev-doc.xml
|
||||
@echo > $@ # Make sure we don't get recursive dependencies, etc!
|
||||
$(XSLTPROC) --output $@ xslt/generate-attributions.xsl $<
|
||||
|
||||
clean:
|
||||
rm -f *.xml $(MANPAGES) $(TXTDIR)/*.txt $(PSDIR)/*.ps \
|
||||
$(PDFDIR)/*.pdf $(FAQDIR)/*.html $(HTMLDIR)/*html $(HTMLDIR)/samba.css
|
||||
rm -f xslt/figures/*pdf
|
||||
rm -f $(SMBDOTCONFDOC)/parameters.*.xml $(DVIDIR)/*.dvi
|
||||
rm -f samba-doc.* dev-doc.* $(PROJDOC)/changelog.xml $(PROJDOC)/attributions.xml $(DEVDOC)/attributions.xml
|
||||
rm -f Samba-HOWTO-Collection.*
|
||||
rm -f Samba-Developers-Guide.*
|
||||
rm -f Samba-Guide.*
|
||||
rm -f $(IMAGEPROJDIR)/*.eps $(MANPROJDOC)/smb.conf.5.xml
|
||||
rm -f $(PLUCKERDIR)/*.pdb
|
||||
|
||||
# Text files
|
||||
$(TXTDIR):
|
||||
mkdir $(TXTDIR)
|
||||
|
||||
$(TXTDIR)/%.txt: %.xml
|
||||
$(XMLTO) txt -o $(TXTDIR) $< > $@
|
||||
|
||||
# Tex files
|
||||
%.tex: %.xml
|
||||
$(XSLTPROC) --output $@ xslt/latex.xsl $<
|
||||
|
||||
gpl.tex:
|
||||
$(WGET) http://www.gnu.org/licenses/gpl.tex
|
||||
|
||||
latexfigures: $(LATEX_FIGURES)
|
||||
|
||||
# Adobe PDF files
|
||||
$(PDFDIR)/%.pdf: %.tex latexfigures gpl.tex
|
||||
-$(PDFLATEX) $<
|
||||
$(MAKEINDEX) `echo $< | sed -e 's/.tex//'`
|
||||
-$(PDFLATEX) $<
|
||||
-$(PDFLATEX) $<
|
||||
mv $(patsubst %.tex,%.pdf,$<) $@
|
||||
|
||||
epsimages: $(PROJDOC_IMAGES_EPS)
|
||||
|
||||
# DVI files
|
||||
$(DVIDIR)/%.dvi: %.tex epsimages gpl.tex
|
||||
-$(LATEX) $<
|
||||
$(MAKEINDEX) `echo $< | sed -e 's/.tex//'`
|
||||
-$(LATEX) $<
|
||||
-$(LATEX) $<
|
||||
mv $(patsubst %.tex,%.dvi,$<) $@
|
||||
|
||||
%.eps: %.png
|
||||
$(PNGTOPNM) $< | $(PNMTOPS) > $@
|
||||
|
||||
# PostScript files
|
||||
$(PSDIR)/%.ps: $(DVIDIR)/%.dvi
|
||||
$(DVIPS) -o $@ $<
|
||||
|
||||
xslt/figures/%.pdf: xslt/figures/%.eps
|
||||
$(EPSTOPDF) $<
|
||||
|
||||
# Single large HTML files
|
||||
|
||||
$(HTMLDIR):
|
||||
mkdir $(HTMLDIR)
|
||||
|
||||
$(PLUCKERDIR):
|
||||
mkdir $(PLUCKERDIR)
|
||||
|
||||
CSS: $(HTMLDIR) xslt/html/samba.css
|
||||
cp xslt/html/samba.css $(HTMLDIR)/
|
||||
|
||||
$(HTMLDIR)/Samba-HOWTO-Collection.html: Samba-HOWTO-Collection.xml $(PROJDOC_DEPS) $(PROJDOC_IMAGES_PNG)
|
||||
$(XSLTPROC) --output $@ xslt/html.xsl $<
|
||||
|
||||
$(HTMLDIR)/Samba-Developers-Guide.html: Samba-Developers-Guide.xml $(DEVDOC_DEPS)
|
||||
$(XSLTPROC) --output $@ xslt/html.xsl $<
|
||||
|
||||
$(HTMLDIR)/%.html: %.xml
|
||||
$(XSLTPROC) --output $@ xslt/html.xsl $<
|
||||
|
||||
$(PLUCKERDIR)/%.pdb: $(HTMLDIR)/%.html
|
||||
$(PLUCKERBUILD) -v -M1 --stayonhost --noimages --zlib-compression -H file:$< -f $(patsubst $(PLUCKERDIR)/%.pdb,%,$@) -p $(PLUCKERDIR)
|
||||
|
||||
%.xml: $(MANPROJDOC)/%.xml
|
||||
$(XSLTPROC) --stringparam noreference 1 --output $@ xslt/expand-sambadoc.xsl $<
|
||||
|
||||
# Manpages
|
||||
$(SMBDOTCONFDOC)/parameters.all.xml: $(SMBDOTCONFDOC)/generate-file-list.sh
|
||||
@cd $(SMBDOTCONFDOC) && \
|
||||
/bin/sh generate-file-list.sh >parameters.all.xml && \
|
||||
cd $(OUTPUTDIR)
|
||||
|
||||
$(SMBDOTCONFDOC)/parameters.global.xml: $(SMBDOTCONFDOC)/parameters.all.xml $(SMBDOTCONFDOC)/generate-context.xsl
|
||||
@cd $(SMBDOTCONFDOC) && \
|
||||
$(XSLTPROC) --xinclude \
|
||||
--param smb.context "'G'" \
|
||||
--output parameters.global.xml \
|
||||
generate-context.xsl parameters.all.xml && \
|
||||
cd $(OUTPUTDIR)
|
||||
|
||||
$(SMBDOTCONFDOC)/parameters.service.xml: $(SMBDOTCONFDOC)/parameters.all.xml $(SMBDOTCONFDOC)/generate-context.xsl
|
||||
@cd $(SMBDOTCONFDOC) && \
|
||||
$(XSLTPROC) --xinclude \
|
||||
--param smb.context "'S'" \
|
||||
--output parameters.service.xml \
|
||||
generate-context.xsl parameters.all.xml && \
|
||||
cd $(OUTPUTDIR)
|
||||
|
||||
smb.conf.5.xml: $(SMBDOTCONFDOC)/smb.conf.5.xml $(SMBDOTCONFDOC)/parameters.all.xml \
|
||||
$(SMBDOTCONFDOC)/parameters.global.xml $(SMBDOTCONFDOC)/parameters.service.xml
|
||||
$(XSLTPROC) --stringparam noreference 1 --xinclude --output $@ xslt/expand-sambadoc.xsl $<
|
||||
|
||||
$(MANDIR):
|
||||
mkdir $(MANDIR)
|
||||
|
||||
$(MANDIR)/%: %.xml
|
||||
$(XSLTPROC) --output $@ xslt/man.xsl $<
|
||||
|
||||
# Find undocumented parameters
|
||||
|
||||
undocumented: $(SMBDOTCONFDOC)/parameters.all.xml
|
||||
$(PERL) scripts/find_missing_doc.pl ../..
|
||||
|
||||
# Examples and the like
|
||||
|
||||
$(EXAMPLESDIR):
|
||||
mkdir $(EXAMPLESDIR)
|
||||
|
||||
files: $(PROJDOC)/samba-doc.xml $(PROJDOC)/attributions.xml $(EXAMPLESDIR)
|
||||
$(XSLTPROC) xslt/extract-smbfiles.xsl $< > /dev/null
|
||||
|
||||
samples: $(EXAMPLESDIR) Samba-HOWTO-Collection.xml
|
||||
$(XSLTPROC) xslt/extract-examples.xsl Samba-HOWTO-Collection.xml > /dev/null 2> examples/README
|
||||
for I in examples/*.conf; do { ./scripts/indent-smb.conf.pl < $$I > $$I.tmp; mv $$I.tmp $$I; } done
|
||||
|
||||
howto: $(PDFDIR)/Samba-HOWTO-Collection.pdf
|
||||
guide: $(PDFDIR)/Samba-Guide.pdf
|
||||
|
||||
%/changelog.xml: % $(wildcard %/CVS/*)
|
||||
$(CVS2CL) --stdout --xml $< | $(XSLTPROC) --output $@ xslt/genchangelog.xsl -
|
56
docs/configure.in
Normal file
@ -0,0 +1,56 @@
|
||||
AC_INIT(global.ent)
|
||||
|
||||
AC_PATH_PROG(XSLTPROC, xsltproc)
|
||||
if test "x$XSLTPROC" = x; then
|
||||
AC_MSG_ERROR("xsltproc is required")
|
||||
fi
|
||||
AC_PATH_PROG(PDFLATEX, pdflatex)
|
||||
if test "x$PDFLATEX" = x; then
|
||||
AC_MSG_ERROR("pdflatex is required")
|
||||
fi
|
||||
AC_PATH_PROG(MAKEINDEX, makeindex)
|
||||
if test "x$MAKEINDEX" = x; then
|
||||
AC_MSG_ERROR("makeindex is required")
|
||||
fi
|
||||
|
||||
PAPERSIZE=""
|
||||
DUPLICATE_ULINKS=""
|
||||
|
||||
DOCROP="0"
|
||||
|
||||
AC_ARG_ENABLE(crop,
|
||||
[ --enable-crop Whether to use a crop template],
|
||||
[ test "$withval" && DOCROP="1" ])
|
||||
|
||||
PAPERSIZE="a4paper"
|
||||
|
||||
AC_ARG_WITH(papersize,
|
||||
[ --with-papersize Specify papersize (a4paper,letter) ],
|
||||
[ test "$withval" && PAPERSIZE="$withval" ])
|
||||
|
||||
FONTSIZE="10.5"
|
||||
|
||||
AC_ARG_WITH(fontsize,
|
||||
[ --with-fontsize Specify the fontsize in points (default: 10.5) ],
|
||||
[ test "$withval" && FONTSIZE="$withval" ])
|
||||
|
||||
AC_PATH_PROG(RM, rm)
|
||||
AC_PATH_PROG(WGET, wget)
|
||||
AC_PATH_PROG(LATEX, latex)
|
||||
AC_PATH_PROG(DVIPS, dvips)
|
||||
AC_PATH_PROG(PNGTOPNM, pngtopnm)
|
||||
AC_PATH_PROG(PNMTOPS, pnmtops)
|
||||
AC_PATH_PROG(PERL, perl)
|
||||
AC_PATH_PROG(XMLTO, xmlto)
|
||||
AC_PATH_PROG(CVS2CL, cvs2cl)
|
||||
AC_PATH_PROG(PLUCKERBUILD, plucker-build, [echo -e 'No plucker-build utility was found, ignoring following options:\n'])
|
||||
AC_PATH_PROG(EPSTOPDF, epstopdf)
|
||||
|
||||
DOC_BUILD_DATE=`date '+%d-%m-%Y'`
|
||||
AC_SUBST(DOC_BUILD_DATE)
|
||||
AC_SUBST(PAPERSIZE)
|
||||
AC_SUBST(DUPLICATE_ULINKS)
|
||||
AC_SUBST(FONTSIZE)
|
||||
AC_SUBST(DOCROP)
|
||||
|
||||
AC_OUTPUT( Makefile settings.xsl )
|
1
docs/devel/.cvsignore
Normal file
@ -0,0 +1 @@
|
||||
attributions.xml
|
237
docs/devel/CodingSuggestions.xml
Normal file
@ -0,0 +1,237 @@
|
||||
<chapter id="CodingSuggestions">
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>Steve</firstname><surname>French</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Simo</firstname><surname>Sorce</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Andrew</firstname><surname>Bartlett</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Tim</firstname><surname>Potter</surname>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Martin</firstname><surname>Pool</surname>
|
||||
</author>
|
||||
</chapterinfo>
|
||||
|
||||
<title>Coding Suggestions</title>
|
||||
|
||||
<para>
|
||||
So you want to add code to Samba ...
|
||||
</para>
|
||||
|
||||
<para>
|
||||
One of the daunting tasks facing a programmer attempting to write code for
|
||||
Samba is understanding the various coding conventions used by those most
|
||||
active in the project. These conventions were mostly unwritten and helped
|
||||
improve either the portability, stability or consistency of the code. This
|
||||
document will attempt to document a few of the more important coding
|
||||
practices used at this time on the Samba project. The coding practices are
|
||||
expected to change slightly over time, and even to grow as more is learned
|
||||
about obscure portability considerations. Two existing documents
|
||||
<filename>samba/source/internals.doc</filename> and
|
||||
<filename>samba/source/architecture.doc</filename> provide
|
||||
additional information.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The loosely related question of coding style is very personal and this
|
||||
document does not attempt to address that subject, except to say that I
|
||||
have observed that eight character tabs seem to be preferred in Samba
|
||||
source. If you are interested in the topic of coding style, two oft-quoted
|
||||
documents are:
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<ulink url="http://lxr.linux.no/source/Documentation/CodingStyle">http://lxr.linux.no/source/Documentation/CodingStyle</ulink>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<ulink url="http://www.fsf.org/prep/standards_toc.html">http://www.fsf.org/prep/standards_toc.html</ulink>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
But note that coding style in Samba varies due to the many different
|
||||
programmers who have contributed.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Following are some considerations you should use when adding new code to
|
||||
Samba. First and foremost remember that:
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Portability is a primary consideration in adding function, as is network
|
||||
compatability with de facto, existing, real world CIFS/SMB implementations.
|
||||
There are lots of platforms that Samba builds on so use caution when adding
|
||||
a call to a library function that is not invoked in existing Samba code.
|
||||
Also note that there are many quite different SMB/CIFS clients that Samba
|
||||
tries to support, not all of which follow the SNIA CIFS Technical Reference
|
||||
(or the earlier Microsoft reference documents or the X/Open book on the SMB
|
||||
Standard) perfectly.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Here are some other suggestions:
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
|
||||
<listitem><para>
|
||||
use d_printf instead of printf for display text
|
||||
reason: enable auto-substitution of translated language text
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
use SAFE_FREE instead of free
|
||||
reason: reduce traps due to null pointers
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
don't use bzero use memset, or ZERO_STRUCT and ZERO_STRUCTP macros
|
||||
reason: not POSIX
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
don't use strcpy and strlen (use safe_* equivalents)
|
||||
reason: to avoid traps due to buffer overruns
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
don't use getopt_long, use popt functions instead
|
||||
reason: portability
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
explicitly add const qualifiers on parm passing in functions where parm
|
||||
is input only (somewhat controversial but const can be #defined away)
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
when passing a va_list as an arg, or assigning one to another
|
||||
please use the VA_COPY() macro
|
||||
reason: on some platforms, va_list is a struct that must be
|
||||
initialized in each function...can SEGV if you don't.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
discourage use of threads
|
||||
reason: portability (also see architecture.doc)
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
don't explicitly include new header files in C files - new h files
|
||||
should be included by adding them once to includes.h
|
||||
reason: consistency
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
don't explicitly extern functions (they are autogenerated by
|
||||
"make proto" into proto.h)
|
||||
reason: consistency
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
use endian safe macros when unpacking SMBs (see byteorder.h and
|
||||
internals.doc)
|
||||
reason: not everyone uses Intel
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Note Unicode implications of charset handling (see internals.doc). See
|
||||
pull_* and push_* and convert_string functions.
|
||||
reason: Internationalization
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Don't assume English only
|
||||
reason: See above
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Try to avoid using in/out parameters (functions that return data which
|
||||
overwrites input parameters)
|
||||
reason: Can cause stability problems
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Ensure copyright notices are correct, don't append Tridge's name to code
|
||||
that he didn't write. If you did not write the code, make sure that it
|
||||
can coexist with the rest of the Samba GPLed code.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Consider usage of DATA_BLOBs for length specified byte-data.
|
||||
reason: stability
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Take advantage of tdbs for database like function
|
||||
reason: consistency
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Don't access the SAM_ACCOUNT structure directly, they should be accessed
|
||||
via pdb_get...() and pdb_set...() functions.
|
||||
reason: stability, consistency
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Don't check a password directly against the passdb, always use the
|
||||
check_password() interface.
|
||||
reason: long term pluggability
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Try to use asprintf rather than pstrings and fstrings where possible
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Use normal C comments / * instead of C++ comments // like
|
||||
this. Although the C++ comment format is part of the C99
|
||||
standard, some older vendor C compilers do not accept it.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Try to write documentation for API functions and structures
|
||||
explaining the point of the code, the way it should be used, and
|
||||
any special conditions or results. Mark these with a double-star
|
||||
comment start / ** so that they can be picked up by Doxygen, as in
|
||||
this file.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Keep the scope narrow. This means making functions/variables
|
||||
static whenever possible. We don't want our namespace
|
||||
polluted. Each module should have a minimal number of externally
|
||||
visible functions or variables.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Use function pointers to keep knowledge about particular pieces of
|
||||
code isolated in one place. We don't want a particular piece of
|
||||
functionality to be spread out across lots of places - that makes
|
||||
for fragile, hand to maintain code. Instead, design an interface
|
||||
and use tables containing function pointers to implement specific
|
||||
functionality. This is particularly important for command
|
||||
interpreters.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Think carefully about what it will be like for someone else to add
|
||||
to and maintain your code. If it would be hard for someone else to
|
||||
maintain then do it another way.
|
||||
</para></listitem>
|
||||
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
The suggestions above are simply that, suggestions, but the information may
|
||||
help in reducing the routine rework done on new code. The preceeding list
|
||||
is expected to change routinely as new support routines and macros are
|
||||
added.
|
||||
</para>
|
||||
</chapter>
|
154
docs/devel/NetBIOS.xml
Normal file
@ -0,0 +1,154 @@
|
||||
<chapter id="netbios">
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>Luke</firstname><surname>Leighton</surname>
|
||||
</author>
|
||||
<pubdate>12 June 1997</pubdate>
|
||||
</chapterinfo>
|
||||
|
||||
<title>Definition of NetBIOS Protocol and Name Resolution Modes</title>
|
||||
|
||||
<sect1>
|
||||
<title>NETBIOS</title>
|
||||
|
||||
<para>
|
||||
NetBIOS runs over the following tranports: TCP/IP; NetBEUI and IPX/SPX.
|
||||
Samba only uses NetBIOS over TCP/IP. For details on the TCP/IP NetBIOS
|
||||
Session Service NetBIOS Datagram Service, and NetBIOS Names, see
|
||||
rfc1001.txt and rfc1002.txt.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
NetBEUI is a raw NetBIOS frame protocol implementation that allows NetBIOS
|
||||
datagrams to be sent out over the 'wire' embedded within LLC frames.
|
||||
NetBEUI is not required when using NetBIOS over TCP/IP protocols and it
|
||||
is preferable NOT to install NetBEUI if it can be avoided.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
IPX/SPX is also not required when using NetBIOS over TCP/IP, and it is
|
||||
preferable NOT to install the IPX/SPX transport unless you are using Novell
|
||||
servers. At the very least, it is recommended that you do not install
|
||||
'NetBIOS over IPX/SPX'.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
[When installing Windows 95, you will find that NetBEUI and IPX/SPX are
|
||||
installed as the default protocols. This is because they are the simplest
|
||||
to manage: no Windows 95 user-configuration is required].
|
||||
</para>
|
||||
|
||||
<para>
|
||||
NetBIOS applications (such as samba) offer their services (for example,
|
||||
SMB file and print sharing) on a NetBIOS name. They must claim this name
|
||||
on the network before doing so. The NetBIOS session service will then
|
||||
accept connections on the application's behalf (on the NetBIOS name
|
||||
claimed by the application). A NetBIOS session between the application
|
||||
and the client can then commence.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
NetBIOS names consist of 15 characters plus a 'type' character. This is
|
||||
similar, in concept, to an IP address and a TCP port number, respectively.
|
||||
A NetBIOS-aware application on a host will offer different services under
|
||||
different NetBIOS name types, just as a host will offer different TCP/IP
|
||||
services on different port numbers.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
NetBIOS names must be claimed on a network, and must be defended. The use
|
||||
of NetBIOS names is most suitable on a single subnet; a Local Area Network
|
||||
or a Wide Area Network.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
NetBIOS names are either UNIQUE or GROUP. Only one application can claim a
|
||||
UNIQUE NetBIOS name on a network.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
There are two kinds of NetBIOS Name resolution: Broadcast and Point-to-Point.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>BROADCAST NetBIOS</title>
|
||||
|
||||
<para>
|
||||
Clients can claim names, and therefore offer services on successfully claimed
|
||||
names, on their broadcast-isolated subnet. One way to get NetBIOS services
|
||||
(such as browsing: see ftp.microsoft.com/drg/developr/CIFS/browdiff.txt; and
|
||||
SMB file/print sharing: see cifs4.txt) working on a LAN or WAN is to make
|
||||
your routers forward all broadcast packets from TCP/IP ports 137, 138 and 139.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This, however, is not recommended. If you have a large LAN or WAN, you will
|
||||
find that some of your hosts spend 95 percent of their time dealing with
|
||||
broadcast traffic. [If you have IPX/SPX on your LAN or WAN, you will find
|
||||
that this is already happening: a packet analyzer will show, roughly
|
||||
every twelve minutes, great swathes of broadcast traffic!].
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>NBNS NetBIOS</title>
|
||||
|
||||
<para>
|
||||
rfc1001.txt describes, amongst other things, the implementation and use
|
||||
of, a 'NetBIOS Name Service'. NT/AS offers 'Windows Internet Name Service'
|
||||
which is fully rfc1001/2 compliant, but has had to take specific action
|
||||
with certain NetBIOS names in order to make it useful. (for example, it
|
||||
deals with the registration of <1c> <1d> <1e> names all in different ways.
|
||||
I recommend the reading of the Microsoft WINS Server Help files for full
|
||||
details).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The use of a WINS server cuts down on broadcast network traffic for
|
||||
NetBIOS name resolution. It has the effect of pulling all the broadcast
|
||||
isolated subnets together into a single NetBIOS scope, across your LAN
|
||||
or WAN, while avoiding the use of TCP/IP broadcast packets.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
When you have a WINS server on your LAN, WINS clients will be able to
|
||||
contact the WINS server to resolve NetBIOS names. Note that only those
|
||||
WINS clients that have registered with the same WINS server will be
|
||||
visible. The WINS server _can_ have static NetBIOS entries added to its
|
||||
database (usually for security reasons you might want to consider putting
|
||||
your domain controllers or other important servers as static entries,
|
||||
but you should not rely on this as your sole means of security), but for
|
||||
the most part, NetBIOS names are registered dynamically.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This provides some confusion for lots of people, and is worth mentioning
|
||||
here: a Browse Server is NOT a WINS Server, even if these services are
|
||||
implemented in the same application. A Browse Server _needs_ a WINS server
|
||||
because a Browse Server is a WINS client, which is _not_ the same thing].
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Clients can claim names, and therefore offer services on successfully claimed
|
||||
names, on their broadcast-isolated subnet. One way to get NetBIOS services
|
||||
(such as browsing: see ftp.microsoft.com/drg/developr/CIFS/browdiff.txt; and
|
||||
SMB file/print sharing: see cifs6.txt) working on a LAN or WAN is to make
|
||||
your routers forward all broadcast packets from TCP/IP ports 137, 138 and 139.
|
||||
You will find, however, if you do this on a large LAN or a WAN, that your
|
||||
network is completely swamped by NetBIOS and browsing packets, which is why
|
||||
WINS was developed to minimise the necessity of broadcast traffic.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
WINS Clients therefore claim names from the WINS server. If the WINS
|
||||
server allows them to register a name, the client's NetBIOS session service
|
||||
can then offer services on this name. Other WINS clients will then
|
||||
contact the WINS server to resolve a NetBIOS name.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
129
docs/devel/Tracing.xml
Normal file
@ -0,0 +1,129 @@
|
||||
<chapter id="tracing">
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>Andrew</firstname><surname>Tridgell</surname>
|
||||
<affiliation>
|
||||
<orgname>Samba Team</orgname>
|
||||
</affiliation>
|
||||
</author>
|
||||
</chapterinfo>
|
||||
|
||||
<title>Tracing samba system calls</title>
|
||||
|
||||
<para>
|
||||
This file describes how to do a system call trace on Samba to work out
|
||||
what its doing wrong. This is not for the faint of heart, but if you
|
||||
are reading this then you are probably desperate.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Actually its not as bad as the the above makes it sound, just don't
|
||||
expect the output to be very pretty :-)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Ok, down to business. One of the big advantages of unix systems is
|
||||
that they nearly all come with a system trace utility that allows you
|
||||
to monitor all system calls that a program is making. This is
|
||||
extremely using for debugging and also helps when trying to work out
|
||||
why something is slower than you expect. You can use system tracing
|
||||
without any special compilation options.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The system trace utility is called different things on different
|
||||
systems. On Linux systems its called strace. Under SunOS 4 its called
|
||||
trace. Under SVR4 style systems (including solaris) its called
|
||||
truss. Under many BSD systems its called ktrace.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The first thing you should do is read the man page for your native
|
||||
system call tracer. In the discussion below I'll assume its called
|
||||
strace as strace is the only portable system tracer (its available for
|
||||
free for many unix types) and its also got some of the nicest
|
||||
features.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Next, try using strace on some simple commands. For example, <command>strace
|
||||
ls</command> or <command>strace echo hello</command>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You'll notice that it produces a LOT of output. It is showing you the
|
||||
arguments to every system call that the program makes and the
|
||||
result. Very little happens in a program without a system call so you
|
||||
get lots of output. You'll also find that it produces a lot of
|
||||
"preamble" stuff showing the loading of shared libraries etc. Ignore
|
||||
this (unless its going wrong!)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For example, the only line that really matters in the <command>strace echo
|
||||
hello</command> output is:
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
write(1, "hello\n", 6) = 6
|
||||
</programlisting></para>
|
||||
|
||||
<para>all the rest is just setting up to run the program.</para>
|
||||
|
||||
<para>
|
||||
Ok, now you're familiar with strace. To use it on Samba you need to
|
||||
strace the running smbd daemon. The way I tend ot use it is to first
|
||||
login from my Windows PC to the Samba server, then use smbstatus to
|
||||
find which process ID that client is attached to, then as root I do
|
||||
<command>strace -p PID</command> to attach to that process. I normally redirect the
|
||||
stderr output from this command to a file for later perusal. For
|
||||
example, if I'm using a csh style shell:
|
||||
</para>
|
||||
|
||||
<para><command>strace -f -p 3872 >& strace.out</command></para>
|
||||
|
||||
<para>or with a sh style shell:</para>
|
||||
|
||||
<para><command>strace -f -p 3872 > strace.out 2>&1</command></para>
|
||||
|
||||
<para>
|
||||
Note the "-f" option. This is only available on some systems, and
|
||||
allows you to trace not just the current process, but any children it
|
||||
forks. This is great for finding printing problems caused by the
|
||||
"print command" being wrong.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Once you are attached you then can do whatever it is on the client
|
||||
that is causing problems and you will capture all the system calls
|
||||
that smbd makes.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
So how do you interpret the results? Generally I search through the
|
||||
output for strings that I know will appear when the problem
|
||||
happens. For example, if I am having touble with permissions on a file
|
||||
I would search for that files name in the strace output and look at
|
||||
the surrounding lines. Another trick is to match up file descriptor
|
||||
numbers and "follow" what happens to an open file until it is closed.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Beyond this you will have to use your initiative. To give you an idea
|
||||
of what you are looking for here is a piece of strace output that
|
||||
shows that <filename>/dev/null</filename> is not world writeable, which
|
||||
causes printing to fail with Samba:
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
[pid 28268] open("/dev/null", O_RDWR) = -1 EACCES (Permission denied)
|
||||
[pid 28268] open("/dev/null", O_WRONLY) = -1 EACCES (Permission denied)
|
||||
</programlisting></para>
|
||||
|
||||
<para>
|
||||
The process is trying to first open <filename>/dev/null</filename> read-write
|
||||
then read-only. Both fail. This means <filename>/dev/null</filename> has
|
||||
incorrect permissions.
|
||||
</para>
|
||||
|
||||
</chapter>
|
184
docs/devel/architecture.xml
Normal file
@ -0,0 +1,184 @@
|
||||
<chapter id="architecture">
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>Dan</firstname><surname>Shearer</surname>
|
||||
</author>
|
||||
<pubdate> November 1997</pubdate>
|
||||
</chapterinfo>
|
||||
|
||||
<title>Samba Architecture</title>
|
||||
|
||||
<sect1>
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>
|
||||
This document gives a general overview of how Samba works
|
||||
internally. The Samba Team has tried to come up with a model which is
|
||||
the best possible compromise between elegance, portability, security
|
||||
and the constraints imposed by the very messy SMB and CIFS
|
||||
protocol.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It also tries to answer some of the frequently asked questions such as:
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem><para>
|
||||
Is Samba secure when running on Unix? The xyz platform?
|
||||
What about the root priveliges issue?
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>Pros and cons of multithreading in various parts of Samba</para></listitem>
|
||||
|
||||
<listitem><para>Why not have a separate process for name resolution, WINS, and browsing?</para></listitem>
|
||||
|
||||
</orderedlist>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Multithreading and Samba</title>
|
||||
|
||||
<para>
|
||||
People sometimes tout threads as a uniformly good thing. They are very
|
||||
nice in their place but are quite inappropriate for smbd. nmbd is
|
||||
another matter, and multi-threading it would be very nice.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The short version is that smbd is not multithreaded, and alternative
|
||||
servers that take this approach under Unix (such as Syntax, at the
|
||||
time of writing) suffer tremendous performance penalties and are less
|
||||
robust. nmbd is not threaded either, but this is because it is not
|
||||
possible to do it while keeping code consistent and portable across 35
|
||||
or more platforms. (This drawback also applies to threading smbd.)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The longer versions is that there are very good reasons for not making
|
||||
smbd multi-threaded. Multi-threading would actually make Samba much
|
||||
slower, less scalable, less portable and much less robust. The fact
|
||||
that we use a separate process for each connection is one of Samba's
|
||||
biggest advantages.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Threading smbd</title>
|
||||
|
||||
<para>
|
||||
A few problems that would arise from a threaded smbd are:
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem><para>
|
||||
It's not only to create threads instead of processes, but you
|
||||
must care about all variables if they have to be thread specific
|
||||
(currently they would be global).
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
if one thread dies (eg. a seg fault) then all threads die. We can
|
||||
immediately throw robustness out the window.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
many of the system calls we make are blocking. Non-blocking
|
||||
equivalents of many calls are either not available or are awkward (and
|
||||
slow) to use. So while we block in one thread all clients are
|
||||
waiting. Imagine if one share is a slow NFS filesystem and the others
|
||||
are fast, we will end up slowing all clients to the speed of NFS.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
you can't run as a different uid in different threads. This means
|
||||
we would have to switch uid/gid on _every_ SMB packet. It would be
|
||||
horrendously slow.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
the per process file descriptor limit would mean that we could only
|
||||
support a limited number of clients.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
we couldn't use the system locking calls as the locking context of
|
||||
fcntl() is a process, not a thread.
|
||||
</para></listitem>
|
||||
|
||||
</orderedlist>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Threading nmbd</title>
|
||||
|
||||
<para>
|
||||
This would be ideal, but gets sunk by portability requirements.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Andrew tried to write a test threads library for nmbd that used only
|
||||
ansi-C constructs (using setjmp and longjmp). Unfortunately some OSes
|
||||
defeat this by restricting longjmp to calling addresses that are
|
||||
shallower than the current address on the stack (apparently AIX does
|
||||
this). This makes a truly portable threads library impossible. So to
|
||||
support all our current platforms we would have to code nmbd both with
|
||||
and without threads, and as the real aim of threads is to make the
|
||||
code clearer we would not have gained anything. (it is a myth that
|
||||
threads make things faster. threading is like recursion, it can make
|
||||
things clear but the same thing can always be done faster by some
|
||||
other method)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Chris tried to spec out a general design that would abstract threading
|
||||
vs separate processes (vs other methods?) and make them accessible
|
||||
through some general API. This doesn't work because of the data
|
||||
sharing requirements of the protocol (packets in the future depending
|
||||
on packets now, etc.) At least, the code would work but would be very
|
||||
clumsy, and besides the fork() type model would never work on Unix. (Is there an OS that it would work on, for nmbd?)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
A fork() is cheap, but not nearly cheap enough to do on every UDP
|
||||
packet that arrives. Having a pool of processes is possible but is
|
||||
nasty to program cleanly due to the enormous amount of shared data (in
|
||||
complex structures) between the processes. We can't rely on each
|
||||
platform having a shared memory system.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>nbmd Design</title>
|
||||
|
||||
<para>
|
||||
Originally Andrew used recursion to simulate a multi-threaded
|
||||
environment, which use the stack enormously and made for really
|
||||
confusing debugging sessions. Luke Leighton rewrote it to use a
|
||||
queuing system that keeps state information on each packet. The
|
||||
first version used a single structure which was used by all the
|
||||
pending states. As the initialisation of this structure was
|
||||
done by adding arguments, as the functionality developed, it got
|
||||
pretty messy. So, it was replaced with a higher-order function
|
||||
and a pointer to a user-defined memory block. This suddenly
|
||||
made things much simpler: large numbers of functions could be
|
||||
made static, and modularised. This is the same principle as used
|
||||
in NT's kernel, and achieves the same effect as threads, but in
|
||||
a single process.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Then Jeremy rewrote nmbd. The packet data in nmbd isn't what's on the
|
||||
wire. It's a nice format that is very amenable to processing but still
|
||||
keeps the idea of a distinct packet. See "struct packet_struct" in
|
||||
nameserv.h. It has all the detail but none of the on-the-wire
|
||||
mess. This makes it ideal for using in disk or memory-based databases
|
||||
for browsing and WINS support.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
</chapter>
|
70
docs/devel/attributions.xml
Normal file
@ -0,0 +1,70 @@
|
||||
<para><link linkend="netbios">Definition of NetBIOS Protocol and Name Resolution Modes</link>
|
||||
<itemizedlist> <listitem><para>Luke Leighton</para></listitem>
|
||||
</itemizedlist>
|
||||
</para><para><link linkend="unix-smb">NetBIOS in a Unix World</link>
|
||||
<itemizedlist> <listitem><para>Andrew Tridgell</para></listitem>
|
||||
</itemizedlist>
|
||||
</para><para><link linkend="ntdomain">NT Domain RPC's</link>
|
||||
<itemizedlist> <listitem><para>Luke Leighton <<ulink noescape="1" url="mailto:lkcl@switchboard.net">lkcl@switchboard.net</ulink>></para></listitem>
|
||||
<listitem><para>Paul Ashton <<ulink noescape="1" url="mailto:paul@argo.demon.co.uk">paul@argo.demon.co.uk</ulink>></para></listitem>
|
||||
<listitem><para>Duncan Stansfield <<ulink noescape="1" url="mailto:duncans@sco.com">duncans@sco.com</ulink>></para></listitem>
|
||||
</itemizedlist>
|
||||
</para><para><link linkend="architecture">Samba Architecture</link>
|
||||
<itemizedlist> <listitem><para>Dan Shearer</para></listitem>
|
||||
</itemizedlist>
|
||||
</para><para><link linkend="debug">The samba DEBUG system</link>
|
||||
<itemizedlist> <listitem><para>Chris Hertel</para></listitem>
|
||||
</itemizedlist>
|
||||
</para><para><link linkend="internals">Samba Internals</link>
|
||||
<itemizedlist> <listitem><para>David Chappell <<ulink noescape="1" url="mailto:David.Chappell@mail.trincoll.edu">David.Chappell@mail.trincoll.edu</ulink>></para></listitem>
|
||||
</itemizedlist>
|
||||
</para><para><link linkend="CodingSuggestions">Coding Suggestions</link>
|
||||
<itemizedlist> <listitem><para>Steve French</para></listitem>
|
||||
<listitem><para>Simo Sorce</para></listitem>
|
||||
<listitem><para>Andrew Bartlett</para></listitem>
|
||||
<listitem><para>Tim Potter</para></listitem>
|
||||
<listitem><para>Martin Pool</para></listitem>
|
||||
</itemizedlist>
|
||||
</para><para><link linkend="contributing">Contributing code</link>
|
||||
<itemizedlist> <listitem><para>Jelmer R. Vernooij <<ulink noescape="1" url="mailto:jelmer@samba.org">jelmer@samba.org</ulink>></para></listitem>
|
||||
</itemizedlist>
|
||||
</para><para><link linkend="modules">Modules</link>
|
||||
<itemizedlist> <listitem><para>Jelmer Vernooij <<ulink noescape="1" url="mailto:jelmer@samba.org">jelmer@samba.org</ulink>></para></listitem>
|
||||
</itemizedlist>
|
||||
</para><para><link linkend="sam">The Upcoming SAM System</link>
|
||||
<itemizedlist> <listitem><para>Andrew Bartlett</para></listitem>
|
||||
</itemizedlist>
|
||||
</para><para><link linkend="rpc-plugin">RPC Pluggable Modules</link>
|
||||
<itemizedlist> <listitem><para>Anthony Liguori <<ulink noescape="1" url="mailto:aliguor@us.ibm.com">aliguor@us.ibm.com</ulink>></para></listitem>
|
||||
<listitem><para>Jelmer Vernooij <<ulink noescape="1" url="mailto:jelmer@samba.org">jelmer@samba.org</ulink>></para></listitem>
|
||||
</itemizedlist>
|
||||
</para><para><link linkend="vfs">VFS Modules</link>
|
||||
<itemizedlist> <listitem><para>Alexander Bokovoy <<ulink noescape="1" url="mailto:ab@samba.org">ab@samba.org</ulink>></para></listitem>
|
||||
<listitem><para>Stefan Metzmacher <<ulink noescape="1" url="mailto:metze@metzemix.de">metze@metzemix.de</ulink>></para></listitem>
|
||||
</itemizedlist>
|
||||
</para><para><link linkend="registry">The registry subsystem</link>
|
||||
<itemizedlist> <listitem><para>Jelmer R. Vernooij <<ulink noescape="1" url="mailto:jelmer@samba.org">jelmer@samba.org</ulink>></para></listitem>
|
||||
</itemizedlist>
|
||||
</para><para><link linkend="parsing">The smb.conf file</link>
|
||||
<itemizedlist> <listitem><para>Chris Hertel</para></listitem>
|
||||
</itemizedlist>
|
||||
</para><para><link linkend="wins">Samba WINS Internals</link>
|
||||
<itemizedlist> <listitem><para>Gerald Carter</para></listitem>
|
||||
</itemizedlist>
|
||||
</para><para><link linkend="pwencrypt">LanMan and NT Password Encryption</link>
|
||||
<itemizedlist> <listitem><para>Jeremy Allison <<ulink noescape="1" url="mailto:samba@samba.org">samba@samba.org</ulink>></para></listitem>
|
||||
</itemizedlist>
|
||||
</para><para><link linkend="tracing">Tracing samba system calls</link>
|
||||
<itemizedlist> <listitem><para>Andrew Tridgell</para></listitem>
|
||||
</itemizedlist>
|
||||
</para><para><link linkend="windows-debug">Finding useful information on windows</link>
|
||||
<itemizedlist> <listitem><para>Jelmer R. Vernooij <<ulink noescape="1" url="mailto:jelmer@samba.org">jelmer@samba.org</ulink>></para></listitem>
|
||||
<listitem><para>Andrew Tridgell <<ulink noescape="1" url="mailto:tridge@samba.org">tridge@samba.org</ulink>></para></listitem>
|
||||
</itemizedlist>
|
||||
</para><para><link linkend="printing">Samba Printing Internals</link>
|
||||
<itemizedlist> <listitem><para>Gerald Carter</para></listitem>
|
||||
</itemizedlist>
|
||||
</para><para><link linkend="Packaging">Notes to packagers</link>
|
||||
<itemizedlist> <listitem><para>Jelmer Vernooij</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
2932
docs/devel/cifsntdomain.xml
Normal file
109
docs/devel/contributing.xml
Normal file
@ -0,0 +1,109 @@
|
||||
<chapter id="contributing">
|
||||
<chapterinfo>
|
||||
&author.jelmer;
|
||||
</chapterinfo>
|
||||
|
||||
<title>Contributing code</title>
|
||||
|
||||
<para>Here are a few tips and notes that might be useful if you are
|
||||
interested in modifying samba source code and getting it into
|
||||
samba's main branch.</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>Retrieving the source</term>
|
||||
|
||||
<listitem>
|
||||
<para>In order to contribute code to samba, make sure you have the
|
||||
latest source. Retrieving the samba source code from CVS is
|
||||
documented in the appendix of the Samba HOWTO Collection.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>Discuss large modifications with team members</term>
|
||||
<listitem>
|
||||
<para>Please discuss large modifications you are going to make
|
||||
with members of the samba team. Some parts of the samba code
|
||||
have one or more 'owners' - samba developers who wrote most
|
||||
of the code and maintain it.
|
||||
</para>
|
||||
|
||||
<para>This way you can avoid spending your time and effort on
|
||||
something that is not going to make it into the main samba branch
|
||||
because someone else was working on the same thing or because your
|
||||
implementation is not the correct one.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>Patch format</term>
|
||||
<listitem>
|
||||
<para>Patches to the samba tree should be in unified diff format,
|
||||
e.g. files generated by <userinput>diff -u</userinput>.
|
||||
</para>
|
||||
|
||||
<para>If you are modifying a copy of samba you retrieved from CVS,
|
||||
you can easily generate a diff file of these changes by running
|
||||
<userinput>cvs diff -u</userinput>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>Points of attention when modifying samba source code</term>
|
||||
<listitem><para>
|
||||
<itemizedlist>
|
||||
<listitem><para>Don't simply copy code from other places and modify it until it
|
||||
works. Code needs to be clean and logical. Duplicate
|
||||
code is to be avoided.</para></listitem>
|
||||
<listitem><para>Test your patch. It might take a while before one of us looks
|
||||
at your patch so it will take longer before your patch when your patch
|
||||
needs to go thru the review cycle again.</para></listitem>
|
||||
<listitem><para>Don't put seperate patches in one large diff file. This makes
|
||||
it harder to read, understand and test the patch. You might
|
||||
also risk not getting a good patch committed because you mixed it
|
||||
with one that had issues. </para></listitem>
|
||||
<listitem><para>Make sure your patch complies to the samba coding style as
|
||||
suggested in the coding-suggestions chapter. </para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>Sending in bugfixes</term>
|
||||
<listitem>
|
||||
<para>Bugfixes to bugs in samba should be submitted to samba's
|
||||
<ulink url="https://bugzilla.samba.org/">bugzilla system</ulink>,
|
||||
along with a description of the bug.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>Sending in feature patches</term>
|
||||
<listitem>
|
||||
<para>Send feature patches along with a description of what the
|
||||
patch is supposed to do to the
|
||||
<ulink url="mailto:samba-technical@samba.org">Samba-technical mailinglist</ulink> and possibly to a samba team member who is (one of the) 'owners'
|
||||
of the code you made modifications to. We are all busy people
|
||||
so everybody tends to 'let one of the others handle it'. If nobody
|
||||
responded to your patch for a week, try to send it again until you
|
||||
get a response from one of us.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>Feedback on your patch</term>
|
||||
<listitem>
|
||||
<para>One of the team members will look at your patch and either
|
||||
commit your patch or give comments why he won't apply it. In the
|
||||
latter case you can fix your patch and re-send it until
|
||||
your patch is approved.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
</chapter>
|
321
docs/devel/debug.xml
Normal file
@ -0,0 +1,321 @@
|
||||
<chapter id="debug">
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>Chris</firstname><surname>Hertel</surname>
|
||||
</author>
|
||||
<pubdate>July 1998</pubdate>
|
||||
</chapterinfo>
|
||||
|
||||
<title>The samba DEBUG system</title>
|
||||
|
||||
<sect1>
|
||||
<title>New Output Syntax</title>
|
||||
|
||||
<para>
|
||||
The syntax of a debugging log file is represented as:
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
>debugfile< :== { >debugmsg< }
|
||||
|
||||
>debugmsg< :== >debughdr< '\n' >debugtext<
|
||||
|
||||
>debughdr< :== '[' TIME ',' LEVEL ']' FILE ':' [FUNCTION] '(' LINE ')'
|
||||
|
||||
>debugtext< :== { >debugline< }
|
||||
|
||||
>debugline< :== TEXT '\n'
|
||||
</programlisting></para>
|
||||
|
||||
<para>
|
||||
TEXT is a string of characters excluding the newline character.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
LEVEL is the DEBUG level of the message (an integer in the range
|
||||
0..10).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
TIME is a timestamp.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
FILE is the name of the file from which the debug message was
|
||||
generated.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
FUNCTION is the function from which the debug message was generated.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
LINE is the line number of the debug statement that generated the
|
||||
message.
|
||||
</para>
|
||||
|
||||
<para>Basically, what that all means is:</para>
|
||||
<orderedlist>
|
||||
<listitem><para>
|
||||
A debugging log file is made up of debug messages.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Each debug message is made up of a header and text. The header is
|
||||
separated from the text by a newline.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
The header begins with the timestamp and debug level of the
|
||||
message enclosed in brackets. The filename, function, and line
|
||||
number at which the message was generated follow. The filename is
|
||||
terminated by a colon, and the function name is terminated by the
|
||||
parenthesis which contain the line number. Depending upon the
|
||||
compiler, the function name may be missing (it is generated by the
|
||||
__FUNCTION__ macro, which is not universally implemented, dangit).
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
The message text is made up of zero or more lines, each terminated
|
||||
by a newline.
|
||||
</para></listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>Here's some example output:</para>
|
||||
|
||||
<para><programlisting>
|
||||
[1998/08/03 12:55:25, 1] nmbd.c:(659)
|
||||
Netbios nameserver version 1.9.19-prealpha started.
|
||||
Copyright Andrew Tridgell 1994-1997
|
||||
[1998/08/03 12:55:25, 3] loadparm.c:(763)
|
||||
Initializing global parameters
|
||||
</programlisting></para>
|
||||
|
||||
<para>
|
||||
Note that in the above example the function names are not listed on
|
||||
the header line. That's because the example above was generated on an
|
||||
SGI Indy, and the SGI compiler doesn't support the __FUNCTION__ macro.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>The DEBUG() Macro</title>
|
||||
|
||||
<para>
|
||||
Use of the DEBUG() macro is unchanged. DEBUG() takes two parameters.
|
||||
The first is the message level, the second is the body of a function
|
||||
call to the Debug1() function.
|
||||
</para>
|
||||
|
||||
<para>That's confusing.</para>
|
||||
|
||||
<para>Here's an example which may help a bit. If you would write</para>
|
||||
|
||||
<para><programlisting>
|
||||
printf( "This is a %s message.\n", "debug" );
|
||||
</programlisting></para>
|
||||
|
||||
<para>
|
||||
to send the output to stdout, then you would write
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
DEBUG( 0, ( "This is a %s message.\n", "debug" ) );
|
||||
</programlisting></para>
|
||||
|
||||
<para>
|
||||
to send the output to the debug file. All of the normal printf()
|
||||
formatting escapes work.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Note that in the above example the DEBUG message level is set to 0.
|
||||
Messages at level 0 always print. Basically, if the message level is
|
||||
less than or equal to the global value DEBUGLEVEL, then the DEBUG
|
||||
statement is processed.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The output of the above example would be something like:
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
[1998/07/30 16:00:51, 0] file.c:function(128)
|
||||
This is a debug message.
|
||||
</programlisting></para>
|
||||
|
||||
<para>
|
||||
Each call to DEBUG() creates a new header *unless* the output produced
|
||||
by the previous call to DEBUG() did not end with a '\n'. Output to the
|
||||
debug file is passed through a formatting buffer which is flushed
|
||||
every time a newline is encountered. If the buffer is not empty when
|
||||
DEBUG() is called, the new input is simply appended.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
...but that's really just a Kludge. It was put in place because
|
||||
DEBUG() has been used to write partial lines. Here's a simple (dumb)
|
||||
example of the kind of thing I'm talking about:
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
DEBUG( 0, ("The test returned " ) );
|
||||
if( test() )
|
||||
DEBUG(0, ("True") );
|
||||
else
|
||||
DEBUG(0, ("False") );
|
||||
DEBUG(0, (".\n") );
|
||||
</programlisting></para>
|
||||
|
||||
<para>
|
||||
Without the format buffer, the output (assuming test() returned true)
|
||||
would look like this:
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
[1998/07/30 16:00:51, 0] file.c:function(256)
|
||||
The test returned
|
||||
[1998/07/30 16:00:51, 0] file.c:function(258)
|
||||
True
|
||||
[1998/07/30 16:00:51, 0] file.c:function(261)
|
||||
.
|
||||
</programlisting></para>
|
||||
|
||||
<para>Which isn't much use. The format buffer kludge fixes this problem.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>The DEBUGADD() Macro</title>
|
||||
|
||||
<para>
|
||||
In addition to the kludgey solution to the broken line problem
|
||||
described above, there is a clean solution. The DEBUGADD() macro never
|
||||
generates a header. It will append new text to the current debug
|
||||
message even if the format buffer is empty. The syntax of the
|
||||
DEBUGADD() macro is the same as that of the DEBUG() macro.
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
DEBUG( 0, ("This is the first line.\n" ) );
|
||||
DEBUGADD( 0, ("This is the second line.\nThis is the third line.\n" ) );
|
||||
</programlisting></para>
|
||||
|
||||
<para>Produces</para>
|
||||
|
||||
<para><programlisting>
|
||||
[1998/07/30 16:00:51, 0] file.c:function(512)
|
||||
This is the first line.
|
||||
This is the second line.
|
||||
This is the third line.
|
||||
</programlisting></para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>The DEBUGLVL() Macro</title>
|
||||
|
||||
<para>
|
||||
One of the problems with the DEBUG() macro was that DEBUG() lines
|
||||
tended to get a bit long. Consider this example from
|
||||
nmbd_sendannounce.c:
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
DEBUG(3,("send_local_master_announcement: type %x for name %s on subnet %s for workgroup %s\n",
|
||||
type, global_myname, subrec->subnet_name, work->work_group));
|
||||
</programlisting></para>
|
||||
|
||||
<para>
|
||||
One solution to this is to break it down using DEBUG() and DEBUGADD(),
|
||||
as follows:
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
DEBUG( 3, ( "send_local_master_announcement: " ) );
|
||||
DEBUGADD( 3, ( "type %x for name %s ", type, global_myname ) );
|
||||
DEBUGADD( 3, ( "on subnet %s ", subrec->subnet_name ) );
|
||||
DEBUGADD( 3, ( "for workgroup %s\n", work->work_group ) );
|
||||
</programlisting></para>
|
||||
|
||||
<para>
|
||||
A similar, but arguably nicer approach is to use the DEBUGLVL() macro.
|
||||
This macro returns True if the message level is less than or equal to
|
||||
the global DEBUGLEVEL value, so:
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
if( DEBUGLVL( 3 ) )
|
||||
{
|
||||
dbgtext( "send_local_master_announcement: " );
|
||||
dbgtext( "type %x for name %s ", type, global_myname );
|
||||
dbgtext( "on subnet %s ", subrec->subnet_name );
|
||||
dbgtext( "for workgroup %s\n", work->work_group );
|
||||
}
|
||||
</programlisting></para>
|
||||
|
||||
<para>(The dbgtext() function is explained below.)</para>
|
||||
|
||||
<para>There are a few advantages to this scheme:</para>
|
||||
<orderedlist>
|
||||
<listitem><para>
|
||||
The test is performed only once.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
You can allocate variables off of the stack that will only be used
|
||||
within the DEBUGLVL() block.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Processing that is only relevant to debug output can be contained
|
||||
within the DEBUGLVL() block.
|
||||
</para></listitem>
|
||||
</orderedlist>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>New Functions</title>
|
||||
|
||||
<sect2>
|
||||
<title>dbgtext()</title>
|
||||
<para>
|
||||
This function prints debug message text to the debug file (and
|
||||
possibly to syslog) via the format buffer. The function uses a
|
||||
variable argument list just like printf() or Debug1(). The
|
||||
input is printed into a buffer using the vslprintf() function,
|
||||
and then passed to format_debug_text().
|
||||
|
||||
If you use DEBUGLVL() you will probably print the body of the
|
||||
message using dbgtext().
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>dbghdr()</title>
|
||||
<para>
|
||||
This is the function that writes a debug message header.
|
||||
Headers are not processed via the format buffer. Also note that
|
||||
if the format buffer is not empty, a call to dbghdr() will not
|
||||
produce any output. See the comments in dbghdr() for more info.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It is not likely that this function will be called directly. It
|
||||
is used by DEBUG() and DEBUGADD().
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>format_debug_text()</title>
|
||||
<para>
|
||||
This is a static function in debug.c. It stores the output text
|
||||
for the body of the message in a buffer until it encounters a
|
||||
newline. When the newline character is found, the buffer is
|
||||
written to the debug file via the Debug1() function, and the
|
||||
buffer is reset. This allows us to add the indentation at the
|
||||
beginning of each line of the message body, and also ensures
|
||||
that the output is written a line at a time (which cleans up
|
||||
syslog output).
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
117
docs/devel/dev-doc.xml
Normal file
@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
|
||||
<!ENTITY % globalentities SYSTEM '../global.ent'> %globalentities;
|
||||
<!ENTITY NetBIOS SYSTEM "NetBIOS.xml">
|
||||
<!ENTITY Architecture SYSTEM "architecture.xml">
|
||||
<!ENTITY debug SYSTEM "debug.xml">
|
||||
<!ENTITY internals SYSTEM "internals.xml">
|
||||
<!ENTITY parsing SYSTEM "parsing.xml">
|
||||
<!ENTITY unix-smb SYSTEM "unix-smb.xml">
|
||||
<!ENTITY CodingSuggestions SYSTEM "CodingSuggestions.xml">
|
||||
<!ENTITY Tracing SYSTEM "Tracing.xml">
|
||||
<!ENTITY cifsntdomain SYSTEM "cifsntdomain.xml">
|
||||
<!ENTITY printing SYSTEM "printing.xml">
|
||||
<!ENTITY wins SYSTEM "wins.xml">
|
||||
<!ENTITY sam SYSTEM "sam.xml">
|
||||
<!ENTITY encryption SYSTEM "encryption.xml">
|
||||
<!ENTITY rpc-plugin SYSTEM "rpc_plugin.xml">
|
||||
<!ENTITY modules SYSTEM "modules.xml">
|
||||
<!ENTITY packagers SYSTEM "packagers.xml">
|
||||
<!ENTITY contributing SYSTEM "contributing.xml">
|
||||
<!ENTITY vfs SYSTEM "vfs.xml">
|
||||
<!ENTITY windows-deb SYSTEM "windows-debug.xml">
|
||||
<!ENTITY registry SYSTEM "registry.xml">
|
||||
]>
|
||||
|
||||
<book id="Samba-Developers-Guide">
|
||||
|
||||
<title>SAMBA Developers Guide</title>
|
||||
|
||||
<bookinfo>
|
||||
<authorgroup>
|
||||
<editor>&person.jelmer;</editor>
|
||||
</authorgroup>
|
||||
|
||||
<abstract>
|
||||
<para>
|
||||
<emphasis>Last Update</emphasis> : Fri Oct 10 00:59:58 CEST 2003
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This book is a collection of documents that might be useful for
|
||||
people developing samba or those interested in doing so.
|
||||
It's nothing more than a collection of documents written by samba developers about
|
||||
the internals of various parts of samba and the SMB protocol. It's still (and will always be) incomplete.
|
||||
The most recent version of this document
|
||||
can be found at <ulink url="http://devel.samba.org/">http://devel.samba.org/</ulink>.
|
||||
Please send updates to <ulink
|
||||
url="mailto:jelmer@samba.org">Jelmer Vernooij</ulink>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This documentation is distributed under the GNU General Public License (GPL)
|
||||
version 2. A copy of the license is included with the Samba source
|
||||
distribution. A copy can be found on-line at <ulink
|
||||
url="http://www.fsf.org/licenses/gpl.txt">http://www.fsf.org/licenses/gpl.txt</ulink>
|
||||
</para>
|
||||
|
||||
</abstract>
|
||||
|
||||
</bookinfo>
|
||||
<preface>
|
||||
<title>Attributions</title>
|
||||
|
||||
&attributions-dev;
|
||||
</preface>
|
||||
|
||||
|
||||
<!-- Contents -->
|
||||
<toc/>
|
||||
|
||||
<!-- Chapters -->
|
||||
<part>
|
||||
<title>The protocol</title>
|
||||
|
||||
&NetBIOS;
|
||||
&unix-smb;
|
||||
&cifsntdomain;
|
||||
|
||||
</part>
|
||||
|
||||
<part>
|
||||
<title>Samba Basics</title>
|
||||
|
||||
&Architecture;
|
||||
&debug;
|
||||
&internals;
|
||||
&CodingSuggestions;
|
||||
&contributing;
|
||||
&modules;
|
||||
</part>
|
||||
|
||||
<part>
|
||||
<title>Samba Subsystems</title>
|
||||
|
||||
&sam;
|
||||
&rpc-plugin;
|
||||
&vfs;
|
||||
®istry;
|
||||
&parsing;
|
||||
&wins;
|
||||
&encryption;
|
||||
|
||||
</part>
|
||||
|
||||
<part>
|
||||
<title>Debugging and tracing</title>
|
||||
|
||||
&Tracing;
|
||||
&windows-deb;
|
||||
&printing;
|
||||
</part>
|
||||
|
||||
<part><title>Appendices</title>
|
||||
&packagers;
|
||||
</part>
|
||||
|
||||
</book>
|
197
docs/devel/encryption.xml
Normal file
@ -0,0 +1,197 @@
|
||||
<chapter id="pwencrypt">
|
||||
|
||||
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>Jeremy</firstname><surname>Allison</surname>
|
||||
<affiliation>
|
||||
<orgname>Samba Team</orgname>
|
||||
<address>
|
||||
<email>samba@samba.org</email>
|
||||
</address>
|
||||
</affiliation>
|
||||
</author>
|
||||
|
||||
<pubdate>19 Apr 1999</pubdate>
|
||||
</chapterinfo>
|
||||
|
||||
<title>LanMan and NT Password Encryption</title>
|
||||
|
||||
<sect1>
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>With the development of LanManager and Windows NT
|
||||
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.</para>
|
||||
|
||||
<para>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.</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>How does it work?</title>
|
||||
|
||||
<para>LanManager encryption is somewhat similar to UNIX
|
||||
password encryption. The server uses a file containing a
|
||||
hashed value of a user's password. This is created by taking
|
||||
the user's plaintext 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".</para>
|
||||
|
||||
<para>Windows NT encryption is a higher quality mechanism,
|
||||
consisting of doing an MD4 hash on a Unicode version of the user's
|
||||
password. This also produces a 16 byte hash value that is
|
||||
non-reversible.</para>
|
||||
|
||||
<para>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.</para>
|
||||
|
||||
<para>The client then uses the hashed password (16 byte values
|
||||
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".</para>
|
||||
|
||||
<para>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. For Windows NT protocol levels the above calculation
|
||||
is done on both hashes of the user's password and both responses are
|
||||
returned in the SMB call, giving two 24 byte values.</para>
|
||||
|
||||
<para>The Samba server then reproduces the above calculation, using
|
||||
its own stored value of the 16 byte hashed password (read from the
|
||||
<filename>smbpasswd</filename> 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.</para>
|
||||
|
||||
<para>If these values match exactly, then the client knew the
|
||||
correct password (or the 16 byte hashed value - see security note
|
||||
below) and is thus allowed access. If not, then the client did not
|
||||
know the correct password and is denied access.</para>
|
||||
|
||||
<para>Note that the Samba server never knows or stores the cleartext
|
||||
of the user's password - just the 16 byte hashed values derived from
|
||||
it. Also note that the cleartext password or 16 byte hashed values
|
||||
are never transmitted over the network - thus increasing security.</para>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>The smbpasswd file</title>
|
||||
<anchor id="SMBPASSWDFILEFORMAT"/>
|
||||
<para>In order for Samba to participate in the above protocol
|
||||
it must be able to look up the 16 byte hashed values 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 user's
|
||||
password given the UNIX hash of it), 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 <filename>
|
||||
/etc/passwd</filename> and the <filename>smbpasswd</filename> file,
|
||||
a utility, <command>mksmbpasswd.sh</command>, is provided to generate
|
||||
a smbpasswd file from a UNIX <filename>/etc/passwd</filename> file.
|
||||
</para>
|
||||
|
||||
|
||||
<para>To generate the smbpasswd file from your <filename>/etc/passwd
|
||||
</filename> file use the following command:</para>
|
||||
|
||||
<para><prompt>$ </prompt><userinput>cat /etc/passwd | mksmbpasswd.sh
|
||||
> /usr/local/samba/private/smbpasswd</userinput></para>
|
||||
|
||||
<para>If you are running on a system that uses NIS, use</para>
|
||||
|
||||
<para><prompt>$ </prompt><userinput>ypcat passwd | mksmbpasswd.sh
|
||||
> /usr/local/samba/private/smbpasswd</userinput></para>
|
||||
|
||||
<para>The <command>mksmbpasswd.sh</command> program is found in
|
||||
the Samba source directory. By default, the smbpasswd file is
|
||||
stored in :</para>
|
||||
|
||||
<para><filename>/usr/local/samba/private/smbpasswd</filename></para>
|
||||
|
||||
<para>The owner of the <filename>/usr/local/samba/private/</filename>
|
||||
directory should be set to root, and the permissions on it should
|
||||
be set to 0500 (<command>chmod 500 /usr/local/samba/private</command>).
|
||||
</para>
|
||||
|
||||
<para>Likewise, the smbpasswd file inside the private directory should
|
||||
be owned by root and the permissions on is should be set to 0600
|
||||
(<command>chmod 600 smbpasswd</command>).</para>
|
||||
|
||||
|
||||
<para>The format of the smbpasswd file is (The line has been
|
||||
wrapped here. It should appear as one entry per line in
|
||||
your smbpasswd file.)</para>
|
||||
|
||||
<para><programlisting>
|
||||
username:uid:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:
|
||||
[Account type]:LCT-<last-change-time>:Long name
|
||||
</programlisting></para>
|
||||
|
||||
<para>Although only the <replaceable>username</replaceable>,
|
||||
<replaceable>uid</replaceable>, <replaceable>
|
||||
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</replaceable>,
|
||||
[<replaceable>Account type</replaceable>] and <replaceable>
|
||||
last-change-time</replaceable> sections are significant
|
||||
and are looked at in the Samba code.</para>
|
||||
|
||||
<para>It is <emphasis>VITALLY</emphasis> important that there by 32
|
||||
'X' characters between the two ':' characters in the XXX sections -
|
||||
the smbpasswd and Samba code will fail to validate any entries that
|
||||
do not have 32 characters between ':' characters. The first XXX
|
||||
section is for the Lanman password hash, the second is for the
|
||||
Windows NT version.</para>
|
||||
|
||||
<para>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 user's password.</para>
|
||||
|
||||
<para>To set a user to have no password (not recommended), edit the file
|
||||
using vi, and replace the first 11 characters with the ascii text
|
||||
<constant>"NO PASSWORD"</constant> (minus the quotes).</para>
|
||||
|
||||
<para>For example, to clear the password for user bob, his smbpasswd file
|
||||
entry would look like :</para>
|
||||
|
||||
<para><programlisting>
|
||||
bob:100:NO PASSWORDXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:
|
||||
[U ]:LCT-00000000:Bob's full name:/bobhome:/bobshell
|
||||
</programlisting></para>
|
||||
|
||||
<para>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). In order for you to allow this the
|
||||
<command>smbpasswd</command> program must be able to connect to the
|
||||
<command>smbd</command> daemon as that user with no password. Enable this
|
||||
by adding the line :</para>
|
||||
|
||||
<para><command>null passwords = yes</command></para>
|
||||
|
||||
<para>to the [global] section of the smb.conf file (this is why
|
||||
the above scenario is not recommended). Preferably, allocate your
|
||||
users a default password to begin with, so you do not have
|
||||
to enable this on your server.</para>
|
||||
|
||||
<para><emphasis>Note : </emphasis>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 <filename>/etc/passwd</filename> file.</para>
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
119
docs/devel/gencache.xml
Normal file
@ -0,0 +1,119 @@
|
||||
<chapter id="gencache">
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>Rafal</firstname><surname>Szczesniak</surname>
|
||||
</author>
|
||||
<pubdate>April 2003</pubdate>
|
||||
</chapterinfo>
|
||||
|
||||
<title>General cache mechanism and API</title>
|
||||
|
||||
<sect1>
|
||||
<title>Abstract</title>
|
||||
<para>
|
||||
General cache (gencache) was designed to combine various kinds of caching
|
||||
mechanisms into one, defined by a simple API. This way, anyone can use it
|
||||
to create their own caching layer on top of gencache. An example of
|
||||
such approach is the netbios name cache.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>The mechanism</title>
|
||||
<para>
|
||||
Gencache utilises <emphasise>tdb</emphasise> database, like many other
|
||||
parts of Samba. As its origins are in Berkeley DB implementation, it
|
||||
uses key/value pairs stored in binary file. The values gencache
|
||||
operates on are string-based, however. This makes very easy to use it
|
||||
in command line environment eg. to quickly take a look at what's in
|
||||
the cache or set some value.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
All the data is stored in <filename>gencache.tdb</filename>
|
||||
file. Records put there are in key/value format as mentioned below,
|
||||
but as it's a cache, the timeout plays also important role and has a
|
||||
special place in the key/value pair, as well as API.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
|
||||
<sect1>
|
||||
<title>The data structure</title>
|
||||
<para>
|
||||
The record stored in <filename>gencache.tdb</filename> file consists
|
||||
of the key, the value and the expiration timeout. While the first part
|
||||
is stored completely independent from the others, the last two are
|
||||
kept together. The form the record has is:
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
key: <string&bt;
|
||||
value: <12-digit timeout&bt;/<string>
|
||||
</programlisting></para>
|
||||
|
||||
<para>The timeout part is the ASCII representation of
|
||||
<emphasis>time_t</emphasis> value of the time when the cache entry
|
||||
expires. Obviously the API, the programmer is provided with, hides this detail,
|
||||
so that you don't have to care about checking it. Simply watch
|
||||
carefully the return status of the function.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>The API</title>
|
||||
|
||||
<para><programlisting>
|
||||
BOOL gencache_init()
|
||||
</programlisting></para>
|
||||
|
||||
<para>This is used to initialise to whole caching mechanism. It means
|
||||
opening the file or creating it if non-existing. If it's already been
|
||||
opened earlier, then the routine just does nothing and returns
|
||||
<constant>true</constant>. If something goes wrong, say the user
|
||||
doesn't have necessary rights, the function returns
|
||||
<constant>false</constant>.</para>
|
||||
|
||||
<para><programlisting>
|
||||
BOOL gencache_shutdown()
|
||||
</programlisting></para>
|
||||
|
||||
<para>This is the proper way to close the cache file. It simply
|
||||
returns <constant>true</constant> after successful closing file and
|
||||
<constant>false</constant> upon a failure.</para>
|
||||
|
||||
<para><programlisting>
|
||||
BOOL gencache_set(const char* keystr, const char* value, time_t timeout)
|
||||
</programlisting></para>
|
||||
|
||||
<para>This is one of the most basic functions. What it allows you to
|
||||
do is to set some particular cache entry. If the entry haven't
|
||||
existed yet, the function will act just as it was "gencache_add"
|
||||
function. If it's already been in the cache, the entry will be set to
|
||||
the new value. In either case, the cache entry will be set with given
|
||||
key, value and timeout. Thus it is comfortable way to just set the
|
||||
entry and not care about the details.</para>
|
||||
|
||||
<para><programlisting>
|
||||
BOOL gencache_set_only(const char* keystr, const char* value, time_t timeout)
|
||||
</programlisting></para>
|
||||
|
||||
<para><programlisting>
|
||||
BOOL gencache_del(const char* keystr)
|
||||
</programlisting></para>
|
||||
|
||||
<para><programlisting>
|
||||
BOOL gencache_get(const char* keystr, char** valstr, time_t* timeout)
|
||||
</programlisting></para>
|
||||
|
||||
<para><programlisting>
|
||||
void gencache_iterate(void (*fn)(const char* key, const char *value, time_t timeout, void* dptr),
|
||||
void* data, const char* keystr_pattern)
|
||||
|
||||
</programlisting></para>
|
||||
|
||||
<sect1>
|
||||
<title>Writing your own caching layer</title>
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
440
docs/devel/internals.xml
Normal file
@ -0,0 +1,440 @@
|
||||
<chapter id="internals">
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>David</firstname><surname>Chappell</surname>
|
||||
<affiliation>
|
||||
<address><email>David.Chappell@mail.trincoll.edu</email></address>
|
||||
</affiliation>
|
||||
</author>
|
||||
<pubdate>8 May 1996</pubdate>
|
||||
</chapterinfo>
|
||||
|
||||
<title>Samba Internals</title>
|
||||
|
||||
<sect1>
|
||||
<title>Character Handling</title>
|
||||
<para>
|
||||
This section describes character set handling in Samba, as implemented in
|
||||
Samba 3.0 and above
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the past Samba had very ad-hoc character set handling. Scattered
|
||||
throughout the code were numerous calls which converted particular
|
||||
strings to/from DOS codepages. The problem is that there was no way of
|
||||
telling if a particular char* is in dos codepage or unix
|
||||
codepage. This led to a nightmare of code that tried to cope with
|
||||
particular cases without handlingt the general case.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>The new functions</title>
|
||||
|
||||
<para>
|
||||
The new system works like this:
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem><para>
|
||||
all char* strings inside Samba are "unix" strings. These are
|
||||
multi-byte strings that are in the charset defined by the "unix
|
||||
charset" option in smb.conf.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
there is no single fixed character set for unix strings, but any
|
||||
character set that is used does need the following properties:
|
||||
</para>
|
||||
<orderedlist>
|
||||
|
||||
<listitem><para>
|
||||
must not contain NULLs except for termination
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
must be 7-bit compatible with C strings, so that a constant
|
||||
string or character in C will be byte-for-byte identical to the
|
||||
equivalent string in the chosen character set.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
when you uppercase or lowercase a string it does not become
|
||||
longer than the original string
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
must be able to correctly hold all characters that your client
|
||||
will throw at it
|
||||
</para></listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
For example, UTF-8 is fine, and most multi-byte asian character sets
|
||||
are fine, but UCS2 could not be used for unix strings as they
|
||||
contain nulls.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem><para>
|
||||
when you need to put a string into a buffer that will be sent on the
|
||||
wire, or you need a string in a character set format that is
|
||||
compatible with the clients character set then you need to use a
|
||||
pull_ or push_ function. The pull_ functions pull a string from a
|
||||
wire buffer into a (multi-byte) unix string. The push_ functions
|
||||
push a string out to a wire buffer.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
the two main pull_ and push_ functions you need to understand are
|
||||
pull_string and push_string. These functions take a base pointer
|
||||
that should point at the start of the SMB packet that the string is
|
||||
in. The functions will check the flags field in this packet to
|
||||
automatically determine if the packet is marked as a unicode packet,
|
||||
and they will choose whether to use unicode for this string based on
|
||||
that flag. You may also force this decision using the STR_UNICODE or
|
||||
STR_ASCII flags. For use in smbd/ and libsmb/ there are wrapper
|
||||
functions clistr_ and srvstr_ that call the pull_/push_ functions
|
||||
with the appropriate first argument.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
You may also call the pull_ascii/pull_ucs2 or push_ascii/push_ucs2
|
||||
functions if you know that a particular string is ascii or
|
||||
unicode. There are also a number of other convenience functions in
|
||||
charcnv.c that call the pull_/push_ functions with particularly
|
||||
common arguments, such as pull_ascii_pstring()
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem><para>
|
||||
The biggest thing to remember is that internal (unix) strings in Samba
|
||||
may now contain multi-byte characters. This means you cannot assume
|
||||
that characters are always 1 byte long. Often this means that you will
|
||||
have to convert strings to ucs2 and back again in order to do some
|
||||
(seemingly) simple task. For examples of how to do this see functions
|
||||
like strchr_m(). I know this is very slow, and we will eventually
|
||||
speed it up but right now we want this stuff correct not fast.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
all lp_ functions now return unix strings. The magic "DOS" flag on
|
||||
parameters is gone.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
all vfs functions take unix strings. Don't convert when passing to them
|
||||
</para></listitem>
|
||||
|
||||
</orderedlist>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Macros in byteorder.h</title>
|
||||
|
||||
<para>
|
||||
This section describes the macros defined in byteorder.h. These macros
|
||||
are used extensively in the Samba code.
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>CVAL(buf,pos)</title>
|
||||
|
||||
<para>
|
||||
returns the byte at offset pos within buffer buf as an unsigned character.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>PVAL(buf,pos)</title>
|
||||
<para>returns the value of CVAL(buf,pos) cast to type unsigned integer.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>SCVAL(buf,pos,val)</title>
|
||||
<para>sets the byte at offset pos within buffer buf to value val.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>SVAL(buf,pos)</title>
|
||||
<para>
|
||||
returns the value of the unsigned short (16 bit) little-endian integer at
|
||||
offset pos within buffer buf. An integer of this type is sometimes
|
||||
refered to as "USHORT".
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>IVAL(buf,pos)</title>
|
||||
<para>returns the value of the unsigned 32 bit little-endian integer at offset
|
||||
pos within buffer buf.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>SVALS(buf,pos)</title>
|
||||
<para>returns the value of the signed short (16 bit) little-endian integer at
|
||||
offset pos within buffer buf.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>IVALS(buf,pos)</title>
|
||||
<para>returns the value of the signed 32 bit little-endian integer at offset pos
|
||||
within buffer buf.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>SSVAL(buf,pos,val)</title>
|
||||
<para>sets the unsigned short (16 bit) little-endian integer at offset pos within
|
||||
buffer buf to value val.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>SIVAL(buf,pos,val)</title>
|
||||
<para>sets the unsigned 32 bit little-endian integer at offset pos within buffer
|
||||
buf to the value val.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>SSVALS(buf,pos,val)</title>
|
||||
<para>sets the short (16 bit) signed little-endian integer at offset pos within
|
||||
buffer buf to the value val.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>SIVALS(buf,pos,val)</title>
|
||||
<para>sets the signed 32 bit little-endian integer at offset pos withing buffer
|
||||
buf to the value val.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>RSVAL(buf,pos)</title>
|
||||
<para>returns the value of the unsigned short (16 bit) big-endian integer at
|
||||
offset pos within buffer buf.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>RIVAL(buf,pos)</title>
|
||||
<para>returns the value of the unsigned 32 bit big-endian integer at offset
|
||||
pos within buffer buf.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>RSSVAL(buf,pos,val)</title>
|
||||
<para>sets the value of the unsigned short (16 bit) big-endian integer at
|
||||
offset pos within buffer buf to value val.
|
||||
refered to as "USHORT".</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>RSIVAL(buf,pos,val)</title>
|
||||
<para>sets the value of the unsigned 32 bit big-endian integer at offset
|
||||
pos within buffer buf to value val.</para>
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
||||
|
||||
|
||||
<sect1>
|
||||
<title>LAN Manager Samba API</title>
|
||||
|
||||
<para>
|
||||
This section describes the functions need to make a LAN Manager RPC call.
|
||||
This information had been obtained by examining the Samba code and the LAN
|
||||
Manager 2.0 API documentation. It should not be considered entirely
|
||||
reliable.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<programlisting>
|
||||
call_api(int prcnt, int drcnt, int mprcnt, int mdrcnt,
|
||||
char *param, char *data, char **rparam, char **rdata);
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This function is defined in client.c. It uses an SMB transaction to call a
|
||||
remote api.
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>Parameters</title>
|
||||
|
||||
<para>The parameters are as follows:</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem><para>
|
||||
prcnt: the number of bytes of parameters begin sent.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
drcnt: the number of bytes of data begin sent.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
mprcnt: the maximum number of bytes of parameters which should be returned
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
mdrcnt: the maximum number of bytes of data which should be returned
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
param: a pointer to the parameters to be sent.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
data: a pointer to the data to be sent.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
rparam: a pointer to a pointer which will be set to point to the returned
|
||||
paramters. The caller of call_api() must deallocate this memory.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
rdata: a pointer to a pointer which will be set to point to the returned
|
||||
data. The caller of call_api() must deallocate this memory.
|
||||
</para></listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
These are the parameters which you ought to send, in the order of their
|
||||
appearance in the parameter block:
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
|
||||
<listitem><para>
|
||||
An unsigned 16 bit integer API number. You should set this value with
|
||||
SSVAL(). I do not know where these numbers are described.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
An ASCIIZ string describing the parameters to the API function as defined
|
||||
in the LAN Manager documentation. The first parameter, which is the server
|
||||
name, is ommited. This string is based uppon the API function as described
|
||||
in the manual, not the data which is actually passed.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
An ASCIIZ string describing the data structure which ought to be returned.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Any parameters which appear in the function call, as defined in the LAN
|
||||
Manager API documentation, after the "Server" and up to and including the
|
||||
"uLevel" parameters.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
An unsigned 16 bit integer which gives the size in bytes of the buffer we
|
||||
will use to receive the returned array of data structures. Presumably this
|
||||
should be the same as mdrcnt. This value should be set with SSVAL().
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
An ASCIIZ string describing substructures which should be returned. If no
|
||||
substructures apply, this string is of zero length.
|
||||
</para></listitem>
|
||||
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
The code in client.c always calls call_api() with no data. It is unclear
|
||||
when a non-zero length data buffer would be sent.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Return value</title>
|
||||
|
||||
<para>
|
||||
The returned parameters (pointed to by rparam), in their order of appearance
|
||||
are:</para>
|
||||
|
||||
<orderedlist>
|
||||
|
||||
<listitem><para>
|
||||
An unsigned 16 bit integer which contains the API function's return code.
|
||||
This value should be read with SVAL().
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
An adjustment which tells the amount by which pointers in the returned
|
||||
data should be adjusted. This value should be read with SVAL(). Basically,
|
||||
the address of the start of the returned data buffer should have the returned
|
||||
pointer value added to it and then have this value subtracted from it in
|
||||
order to obtain the currect offset into the returned data buffer.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
A count of the number of elements in the array of structures returned.
|
||||
It is also possible that this may sometimes be the number of bytes returned.
|
||||
</para></listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
When call_api() returns, rparam points to the returned parameters. The
|
||||
first if these is the result code. It will be zero if the API call
|
||||
suceeded. This value by be read with "SVAL(rparam,0)".
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The second parameter may be read as "SVAL(rparam,2)". It is a 16 bit offset
|
||||
which indicates what the base address of the returned data buffer was when
|
||||
it was built on the server. It should be used to correct pointer before
|
||||
use.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The returned data buffer contains the array of returned data structures.
|
||||
Note that all pointers must be adjusted before use. The function
|
||||
fix_char_ptr() in client.c can be used for this purpose.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The third parameter (which may be read as "SVAL(rparam,4)") has something to
|
||||
do with indicating the amount of data returned or possibly the amount of
|
||||
data which can be returned if enough buffer space is allowed.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Code character table</title>
|
||||
<para>
|
||||
Certain data structures are described by means of ASCIIz strings containing
|
||||
code characters. These are the code characters:
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem><para>
|
||||
W a type byte little-endian unsigned integer
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
N a count of substructures which follow
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
D a four byte little-endian unsigned integer
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
B a byte (with optional count expressed as trailing ASCII digits)
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
z a four byte offset to a NULL terminated string
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
l a four byte offset to non-string user data
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
b an offset to data (with count expressed as trailing ASCII digits)
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
r pointer to returned data buffer???
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
L length in bytes of returned data buffer???
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
h number of bytes of information available???
|
||||
</para></listitem>
|
||||
</orderedlist>
|
||||
|
||||
</sect1>
|
||||
</chapter>
|
164
docs/devel/modules.xml
Normal file
@ -0,0 +1,164 @@
|
||||
<chapter id="modules">
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>Jelmer</firstname><surname>Vernooij</surname>
|
||||
<affiliation>
|
||||
<orgname>Samba Team</orgname>
|
||||
<address><email>jelmer@samba.org</email></address>
|
||||
</affiliation>
|
||||
</author>
|
||||
<pubdate> 19 March 2003 </pubdate>
|
||||
</chapterinfo>
|
||||
|
||||
<title>Modules</title>
|
||||
|
||||
<sect1>
|
||||
<title>Advantages</title>
|
||||
|
||||
<para>
|
||||
The new modules system has the following advantages:
|
||||
</para>
|
||||
|
||||
<simplelist>
|
||||
<member>Transparent loading of static and shared modules (no need
|
||||
for a subsystem to know about modules)</member>
|
||||
<member>Simple selection between shared and static modules at configure time</member>
|
||||
<member>"preload modules" option for increasing performance for stable modules</member>
|
||||
<member>No nasty #define stuff anymore</member>
|
||||
<member>All backends are available as plugin now (including pdb_ldap and pdb_tdb)</member>
|
||||
</simplelist>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Loading modules</title>
|
||||
|
||||
<para>
|
||||
Some subsystems in samba use different backends. These backends can be
|
||||
either statically linked in to samba or available as a plugin. A subsystem
|
||||
should have a function that allows a module to register itself. For example,
|
||||
the passdb subsystem has:
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
NTSTATUS smb_register_passdb(int version, const char *name, pdb_init_function init);
|
||||
</programlisting></para>
|
||||
|
||||
<para>
|
||||
This function will be called by the initialisation function of the module to
|
||||
register itself.
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>Static modules</title>
|
||||
|
||||
<para>
|
||||
The modules system compiles a list of initialisation functions for the
|
||||
static modules of each subsystem. This is a define. For example,
|
||||
it is here currently (from <filename>include/config.h</filename>):
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
/* Static init functions */
|
||||
#define static_init_pdb { pdb_mysql_init(); pdb_ldap_init(); pdb_smbpasswd_init(); pdb_tdbsam_init(); pdb_guest_init();}
|
||||
</programlisting></para>
|
||||
|
||||
<para>
|
||||
These functions should be called before the subsystem is used. That
|
||||
should be done when the subsystem is initialised or first used.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Shared modules</title>
|
||||
|
||||
<para>
|
||||
If a subsystem needs a certain backend, it should check if it has
|
||||
already been registered. If the backend hasn't been registered already,
|
||||
the subsystem should call smb_probe_module(char *subsystem, char *backend).
|
||||
This function tries to load the correct module from a certain path
|
||||
($LIBDIR/subsystem/backend.so). If the first character in 'backend'
|
||||
is a slash, smb_probe_module() tries to load the module from the
|
||||
absolute path specified in 'backend'.
|
||||
</para>
|
||||
|
||||
<para>After smb_probe_module() has been executed, the subsystem
|
||||
should check again if the module has been registered.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Writing modules</title>
|
||||
|
||||
<para>
|
||||
Each module has an initialisation function. For modules that are
|
||||
included with samba this name is '<replaceable>subsystem</replaceable>_<replaceable>backend</replaceable>_init'. For external modules (that will never be built-in, but only available as a module) this name is always 'init_module'. (In the case of modules included with samba, the configure system will add a #define subsystem_backend_init() init_module()).
|
||||
The prototype for these functions is:
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
NTSTATUS init_module(void);
|
||||
</programlisting></para>
|
||||
|
||||
<para>This function should call one or more
|
||||
registration functions. The function should return NT_STATUS_OK on success and
|
||||
NT_STATUS_UNSUCCESSFUL or a more useful nt error code on failure.</para>
|
||||
|
||||
<para>For example, pdb_ldap_init() contains: </para>
|
||||
|
||||
<para><programlisting>
|
||||
NTSTATUS pdb_ldap_init(void)
|
||||
{
|
||||
smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam", pdb_init_ldapsam);
|
||||
smb_register_passdb(PASSDB_INTERFACE_VERSION, "ldapsam_nua", pdb_init_ldapsam_nua);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
</programlisting></para>
|
||||
|
||||
<sect2>
|
||||
<title>Static/Shared selection in configure.in</title>
|
||||
|
||||
<para>
|
||||
Some macros in configure.in generate the various defines and substs that
|
||||
are necessary for the system to work correct. All modules that should
|
||||
be built by default have to be added to the variable 'default_modules'.
|
||||
For example, if ldap is found, pdb_ldap is added to this variable.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
On the bottom of configure.in, SMB_MODULE() should be called
|
||||
for each module and SMB_SUBSYSTEM() for each subsystem.
|
||||
</para>
|
||||
|
||||
<para>Syntax:</para>
|
||||
|
||||
<para><programlisting>
|
||||
SMB_MODULE(<replaceable>subsystem</replaceable>_<replaceable>backend</replaceable>, <replaceable>object files</replaceable>, <replaceable>plugin name</replaceable>, <replaceable>subsystem name</replaceable>, <replaceable>static_action</replaceable>, <replaceable>shared_action</replaceable>)
|
||||
SMB_SUBSYSTEM(<replaceable>subsystem</replaceable>,<replaceable>depfile</replaceable>)
|
||||
</programlisting></para>
|
||||
|
||||
<para>The depfile for a certain subsystem is the file that calls the
|
||||
initialisation functions for the statically built in modules.</para>
|
||||
|
||||
<para>
|
||||
<replaceable>@SUBSYSTEM_MODULES@</replaceable> in Makefile.in will
|
||||
be replaced with the names of the plugins to build.
|
||||
</para>
|
||||
|
||||
<para>You must make sure all .c files that contain defines that can
|
||||
be changed by ./configure are rebuilded in the 'modules_clean' make target.
|
||||
Practically, this means all c files that contain <command>static_init_subsystem;</command> calls need to be rebuilded.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
There currently also is a configure.in command called SMB_MODULE_PROVIVES().
|
||||
This is used for modules that register multiple things. It should not
|
||||
be used as probing will most likely disappear in the future.</para>
|
||||
</note>
|
||||
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
40
docs/devel/packagers.xml
Normal file
@ -0,0 +1,40 @@
|
||||
<chapter id="Packaging">
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>Jelmer</firstname><surname>Vernooij</surname>
|
||||
</author>
|
||||
</chapterinfo>
|
||||
|
||||
<title>Notes to packagers</title>
|
||||
|
||||
<sect1>
|
||||
<title>Versioning</title>
|
||||
|
||||
<para>Please, please update the version number in
|
||||
<filename>source/include/version.h</filename> to include the versioning of your package. This makes it easier to distinguish standard samba builds
|
||||
from custom-build samba builds (distributions often patch packages). For
|
||||
example, a good version would be: </para>
|
||||
|
||||
<para><programlisting>
|
||||
Version 2.999+3.0.alpha21-5 for Debian
|
||||
</programlisting></para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Modules</title>
|
||||
|
||||
<para>Samba now has support for building parts of samba as plugins. This
|
||||
makes it possible to, for example, put ldap or mysql support in a seperate
|
||||
package, thus making it possible to have a normal samba package not
|
||||
depending on ldap or mysql. To build as much parts of samba
|
||||
as a plugin, run: </para>
|
||||
|
||||
<para><programlisting>
|
||||
./configure --with-shared-modules=rpc,vfs,auth,pdb,charset
|
||||
</programlisting></para>
|
||||
|
||||
</sect1>
|
||||
|
||||
|
||||
</chapter>
|
239
docs/devel/parsing.xml
Normal file
@ -0,0 +1,239 @@
|
||||
<chapter id="parsing">
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>Chris</firstname><surname>Hertel</surname>
|
||||
</author>
|
||||
<pubdate>November 1997</pubdate>
|
||||
</chapterinfo>
|
||||
|
||||
<title>The smb.conf file</title>
|
||||
|
||||
<sect1>
|
||||
<title>Lexical Analysis</title>
|
||||
|
||||
<para>
|
||||
Basically, the file is processed on a line by line basis. There are
|
||||
four types of lines that are recognized by the lexical analyzer
|
||||
(params.c):
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem><para>
|
||||
Blank lines - Lines containing only whitespace.
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Comment lines - Lines beginning with either a semi-colon or a
|
||||
pound sign (';' or '#').
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Section header lines - Lines beginning with an open square bracket ('[').
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
Parameter lines - Lines beginning with any other character.
|
||||
(The default line type.)
|
||||
</para></listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
The first two are handled exclusively by the lexical analyzer, which
|
||||
ignores them. The latter two line types are scanned for
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem><para>
|
||||
- Section names
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
- Parameter names
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
- Parameter values
|
||||
</para></listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
These are the only tokens passed to the parameter loader
|
||||
(loadparm.c). Parameter names and values are divided from one
|
||||
another by an equal sign: '='.
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>Handling of Whitespace</title>
|
||||
|
||||
<para>
|
||||
Whitespace is defined as all characters recognized by the isspace()
|
||||
function (see ctype(3C)) except for the newline character ('\n')
|
||||
The newline is excluded because it identifies the end of the line.
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem><para>
|
||||
The lexical analyzer scans past white space at the beginning of a line.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Section and parameter names may contain internal white space. All
|
||||
whitespace within a name is compressed to a single space character.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Internal whitespace within a parameter value is kept verbatim with
|
||||
the exception of carriage return characters ('\r'), all of which
|
||||
are removed.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Leading and trailing whitespace is removed from names and values.
|
||||
</para></listitem>
|
||||
|
||||
</orderedlist>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Handling of Line Continuation</title>
|
||||
|
||||
<para>
|
||||
Long section header and parameter lines may be extended across
|
||||
multiple lines by use of the backslash character ('\\'). Line
|
||||
continuation is ignored for blank and comment lines.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If the last (non-whitespace) character within a section header or on
|
||||
a parameter line is a backslash, then the next line will be
|
||||
(logically) concatonated with the current line by the lexical
|
||||
analyzer. For example:
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
param name = parameter value string \
|
||||
with line continuation.
|
||||
</programlisting></para>
|
||||
|
||||
<para>Would be read as</para>
|
||||
|
||||
<para><programlisting>
|
||||
param name = parameter value string with line continuation.
|
||||
</programlisting></para>
|
||||
|
||||
<para>
|
||||
Note that there are five spaces following the word 'string',
|
||||
representing the one space between 'string' and '\\' in the top
|
||||
line, plus the four preceeding the word 'with' in the second line.
|
||||
(Yes, I'm counting the indentation.)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Line continuation characters are ignored on blank lines and at the end
|
||||
of comments. They are *only* recognized within section and parameter
|
||||
lines.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Line Continuation Quirks</title>
|
||||
|
||||
<para>Note the following example:</para>
|
||||
|
||||
<para><programlisting>
|
||||
param name = parameter value string \
|
||||
\
|
||||
with line continuation.
|
||||
</programlisting></para>
|
||||
|
||||
<para>
|
||||
The middle line is *not* parsed as a blank line because it is first
|
||||
concatonated with the top line. The result is
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
param name = parameter value string with line continuation.
|
||||
</programlisting></para>
|
||||
|
||||
<para>The same is true for comment lines.</para>
|
||||
|
||||
<para><programlisting>
|
||||
param name = parameter value string \
|
||||
; comment \
|
||||
with a comment.
|
||||
</programlisting></para>
|
||||
|
||||
<para>This becomes:</para>
|
||||
|
||||
<para><programlisting>
|
||||
param name = parameter value string ; comment with a comment.
|
||||
</programlisting></para>
|
||||
|
||||
<para>
|
||||
On a section header line, the closing bracket (']') is considered a
|
||||
terminating character, and the rest of the line is ignored. The lines
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
[ section name ] garbage \
|
||||
param name = value
|
||||
</programlisting></para>
|
||||
|
||||
<para>are read as</para>
|
||||
|
||||
<para><programlisting>
|
||||
[section name]
|
||||
param name = value
|
||||
</programlisting></para>
|
||||
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Syntax</title>
|
||||
|
||||
<para>The syntax of the smb.conf file is as follows:</para>
|
||||
|
||||
<para><programlisting>
|
||||
<file> :== { <section> } EOF
|
||||
<section> :== <section header> { <parameter line> }
|
||||
<section header> :== '[' NAME ']'
|
||||
<parameter line> :== NAME '=' VALUE NL
|
||||
</programlisting></para>
|
||||
|
||||
<para>Basically, this means that</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem><para>
|
||||
a file is made up of zero or more sections, and is terminated by
|
||||
an EOF (we knew that).
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
A section is made up of a section header followed by zero or more
|
||||
parameter lines.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
A section header is identified by an opening bracket and
|
||||
terminated by the closing bracket. The enclosed NAME identifies
|
||||
the section.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
A parameter line is divided into a NAME and a VALUE. The *first*
|
||||
equal sign on the line separates the NAME from the VALUE. The
|
||||
VALUE is terminated by a newline character (NL = '\n').
|
||||
</para></listitem>
|
||||
|
||||
</orderedlist>
|
||||
|
||||
<sect2>
|
||||
<title>About params.c</title>
|
||||
|
||||
<para>
|
||||
The parsing of the config file is a bit unusual if you are used to
|
||||
lex, yacc, bison, etc. Both lexical analysis (scanning) and parsing
|
||||
are performed by params.c. Values are loaded via callbacks to
|
||||
loadparm.c.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
</chapter>
|
393
docs/devel/printing.xml
Normal file
@ -0,0 +1,393 @@
|
||||
<chapter id="printing">
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>Gerald</firstname><surname>Carter</surname>
|
||||
</author>
|
||||
<pubdate>October 2002</pubdate>
|
||||
</chapterinfo>
|
||||
|
||||
|
||||
<title>Samba Printing Internals</title>
|
||||
|
||||
|
||||
<sect1>
|
||||
<title>Abstract</title>
|
||||
<para>
|
||||
The purpose of this document is to provide some insight into
|
||||
Samba's printing functionality and also to describe the semantics
|
||||
of certain features of Windows client printing.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
|
||||
|
||||
<sect1>
|
||||
<title>
|
||||
Printing Interface to Various Back ends
|
||||
</title>
|
||||
|
||||
<para>
|
||||
Samba uses a table of function pointers to seven functions. The
|
||||
function prototypes are defined in the <varname>printif</varname> structure declared
|
||||
in <filename>printing.h</filename>.
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>retrieve the contents of a print queue</para></listitem>
|
||||
<listitem><para>pause the print queue</para></listitem>
|
||||
<listitem><para>resume a paused print queue</para></listitem>
|
||||
<listitem><para>delete a job from the queue</para></listitem>
|
||||
<listitem><para>pause a job in the print queue</para></listitem>
|
||||
<listitem><para>result a paused print job in the queue</para></listitem>
|
||||
<listitem><para>submit a job to the print queue</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
Currently there are only two printing back end implementations
|
||||
defined.
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>a generic set of functions for working with standard UNIX
|
||||
printing subsystems</para></listitem>
|
||||
|
||||
<listitem><para>a set of CUPS specific functions (this is only enabled if
|
||||
the CUPS libraries were located at compile time).</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
</sect1>
|
||||
|
||||
|
||||
|
||||
|
||||
<sect1>
|
||||
<title>
|
||||
Print Queue TDB's
|
||||
</title>
|
||||
|
||||
|
||||
<para>
|
||||
Samba provides periodic caching of the output from the "lpq command"
|
||||
for performance reasons. This cache time is configurable in seconds.
|
||||
Obviously the longer the cache time the less often smbd will be
|
||||
required to exec a copy of lpq. However, the accuracy of the print
|
||||
queue contents displayed to clients will be diminished as well.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The list of currently opened print queue TDB's can be found
|
||||
be examining the list of tdb_print_db structures ( see print_db_head
|
||||
in printing.c ). A queue TDB is opened using the wrapper function
|
||||
printing.c:get_print_db_byname(). The function ensures that smbd
|
||||
does not open more than MAX_PRINT_DBS_OPEN in an effort to prevent
|
||||
a large print server from exhausting all available file descriptors.
|
||||
If the number of open queue TDB's exceeds the MAX_PRINT_DBS_OPEN
|
||||
limit, smbd falls back to a most recently used algorithm for maintaining
|
||||
a list of open TDB's.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
There are two ways in which a a print job can be entered into
|
||||
a print queue's TDB. The first is to submit the job from a Windows
|
||||
client which will insert the job information directly into the TDB.
|
||||
The second method is to have the print job picked up by executing the
|
||||
"lpq command".
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
/* included from printing.h */
|
||||
struct printjob {
|
||||
pid_t pid; /* which process launched the job */
|
||||
int sysjob; /* the system (lp) job number */
|
||||
int fd; /* file descriptor of open file if open */
|
||||
time_t starttime; /* when the job started spooling */
|
||||
int status; /* the status of this job */
|
||||
size_t size; /* the size of the job so far */
|
||||
int page_count; /* then number of pages so far */
|
||||
BOOL spooled; /* has it been sent to the spooler yet? */
|
||||
BOOL smbjob; /* set if the job is a SMB job */
|
||||
fstring filename; /* the filename used to spool the file */
|
||||
fstring jobname; /* the job name given to us by the client */
|
||||
fstring user; /* the user who started the job */
|
||||
fstring queuename; /* service number of printer for this job */
|
||||
NT_DEVICEMODE *nt_devmode;
|
||||
};
|
||||
</programlisting></para>
|
||||
|
||||
<para>
|
||||
The current manifestation of the printjob structure contains a field
|
||||
for the UNIX job id returned from the "lpq command" and a Windows job
|
||||
ID (32-bit bounded by PRINT_MAX_JOBID). When a print job is returned
|
||||
by the "lpq command" that does not match an existing job in the queue's
|
||||
TDB, a 32-bit job ID above the <*vance doesn't know what word is missing here*> is generating by adding UNIX_JOB_START to
|
||||
the id reported by lpq.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In order to match a 32-bit Windows jobid onto a 16-bit lanman print job
|
||||
id, smbd uses an in memory TDB to match the former to a number appropriate
|
||||
for old lanman clients.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
When updating a print queue, smbd will perform the following
|
||||
steps ( refer to <filename>print.c:print_queue_update()</filename> ):
|
||||
</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem><para>Check to see if another smbd is currently in
|
||||
the process of updating the queue contents by checking the pid
|
||||
stored in <constant>LOCK/<replaceable>printer_name</replaceable></constant>.
|
||||
If so, then do not update the TDB.</para></listitem>
|
||||
|
||||
<listitem><para>Lock the mutex entry in the TDB and store our own pid.
|
||||
Check that this succeeded, else fail.</para></listitem>
|
||||
|
||||
<listitem><para>Store the updated time stamp for the new cache
|
||||
listing</para></listitem>
|
||||
|
||||
<listitem><para>Retrieve the queue listing via "lpq command"</para></listitem>
|
||||
|
||||
<listitem><para><programlisting>
|
||||
foreach job in the queue
|
||||
{
|
||||
if the job is a UNIX job, create a new entry;
|
||||
if the job has a Windows based jobid, then
|
||||
{
|
||||
Lookup the record by the jobid;
|
||||
if the lookup failed, then
|
||||
treat it as a UNIX job;
|
||||
else
|
||||
update the job status only
|
||||
}
|
||||
}</programlisting></para></listitem>
|
||||
|
||||
<listitem><para>Delete any jobs in the TDB that are not
|
||||
in the in the lpq listing</para></listitem>
|
||||
|
||||
<listitem><para>Store the print queue status in the TDB</para></listitem>
|
||||
|
||||
<listitem><para>update the cache time stamp again</para></listitem>
|
||||
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
Note that it is the contents of this TDB that is returned to Windows
|
||||
clients and not the actual listing from the "lpq command".
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The NT_DEVICEMODE stored as part of the printjob structure is used to
|
||||
store a pointer to a non-default DeviceMode associated with the print
|
||||
job. The pointer will be non-null when the client included a Device
|
||||
Mode in the OpenPrinterEx() call and subsequently submitted a job for
|
||||
printing on that same handle. If the client did not include a Device
|
||||
Mode in the OpenPrinterEx() request, the nt_devmode field is NULL
|
||||
and the job has the printer's device mode associated with it by default.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Only non-default Device Mode are stored with print jobs in the print
|
||||
queue TDB. Otherwise, the Device Mode is obtained from the printer
|
||||
object when the client issues a GetJob(level == 2) request.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
|
||||
|
||||
|
||||
<sect1>
|
||||
<title>
|
||||
ChangeID and Client Caching of Printer Information
|
||||
</title>
|
||||
|
||||
<para>
|
||||
[To be filled in later]
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
|
||||
|
||||
<sect1>
|
||||
<title>
|
||||
Windows NT/2K Printer Change Notify
|
||||
</title>
|
||||
|
||||
<para>
|
||||
When working with Windows NT+ clients, it is possible for a
|
||||
print server to use RPC to send asynchronous change notification
|
||||
events to clients for certain printer and print job attributes.
|
||||
This can be useful when the client needs to know that a new
|
||||
job has been added to the queue for a given printer or that the
|
||||
driver for a printer has been changed. Note that this is done
|
||||
entirely orthogonal to cache updates based on a new ChangeID for
|
||||
a printer object.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The basic set of RPC's used to implement change notification are
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>RemoteFindFirstPrinterChangeNotifyEx ( RFFPCN )</para></listitem>
|
||||
<listitem><para>RemoteFindNextPrinterChangeNotifyEx ( RFNPCN )</para></listitem>
|
||||
<listitem><para>FindClosePrinterChangeNotify( FCPCN )</para></listitem>
|
||||
<listitem><para>ReplyOpenPrinter</para></listitem>
|
||||
<listitem><para>ReplyClosePrinter</para></listitem>
|
||||
<listitem><para>RouteRefreshPrinterChangeNotify ( RRPCN )</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
One additional RPC is available to a server, but is never used by the
|
||||
Windows spooler service:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>RouteReplyPrinter()</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
The opnum for all of these RPC's are defined in include/rpc_spoolss.h
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Windows NT print servers use a bizarre method of sending print
|
||||
notification event to clients. The process of registering a new change
|
||||
notification handle is as follows. The 'C' is for client and the
|
||||
'S' is for server. All error conditions have been eliminated.
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
C: Obtain handle to printer or to the printer
|
||||
server via the standard OpenPrinterEx() call.
|
||||
S: Respond with a valid handle to object
|
||||
|
||||
C: Send a RFFPCN request with the previously obtained
|
||||
handle with either (a) set of flags for change events
|
||||
to monitor, or (b) a PRINTER_NOTIFY_OPTIONS structure
|
||||
containing the event information to monitor. The windows
|
||||
spooler has only been observed to use (b).
|
||||
S: The <* another missing word*> opens a new TCP session to the client (thus requiring
|
||||
all print clients to be CIFS servers as well) and sends
|
||||
a ReplyOpenPrinter() request to the client.
|
||||
C: The client responds with a printer handle that can be used to
|
||||
send event notification messages.
|
||||
S: The server replies success to the RFFPCN request.
|
||||
|
||||
C: The windows spooler follows the RFFPCN with a RFNPCN
|
||||
request to fetch the current values of all monitored
|
||||
attributes.
|
||||
S: The server replies with an array SPOOL_NOTIFY_INFO_DATA
|
||||
structures (contained in a SPOOL_NOTIFY_INFO structure).
|
||||
|
||||
C: If the change notification handle is ever released by the
|
||||
client via a FCPCN request, the server sends a ReplyClosePrinter()
|
||||
request back to the client first. However a request of this
|
||||
nature from the client is often an indication that the previous
|
||||
notification event was not marshalled correctly by the server
|
||||
or a piece of data was wrong.
|
||||
S: The server closes the internal change notification handle
|
||||
(POLICY_HND) and does not send any further change notification
|
||||
events to the client for that printer or job.
|
||||
</programlisting></para>
|
||||
|
||||
<para>
|
||||
The current list of notification events supported by Samba can be
|
||||
found by examining the internal tables in srv_spoolss_nt.c
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>printer_notify_table[]</para></listitem>
|
||||
<listitem><para>job_notify_table[]</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
When an event occurs that could be monitored, smbd sends a message
|
||||
to itself about the change. The list of events to be transmitted
|
||||
are queued by the smbd process sending the message to prevent an
|
||||
overload of TDB usage and the internal message is sent during smbd's
|
||||
idle loop (refer to printing/notify.c and the functions
|
||||
send_spoolss_notify2_msg() and print_notify_send_messages() ).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The decision of whether or not the change is to be sent to connected
|
||||
clients is made by the routine which actually sends the notification.
|
||||
( refer to srv_spoolss_nt.c:recieve_notify2_message() ).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Because it possible to receive a listing of multiple changes for
|
||||
multiple printers, the notification events must be split into
|
||||
categories by the printer name. This makes it possible to group
|
||||
multiple change events to be sent in a single RPC according to the
|
||||
printer handle obtained via a ReplyOpenPrinter().
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The actual change notification is performed using the RRPCN request
|
||||
RPC. This packet contains
|
||||
</para>
|
||||
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
<listitem><para>the printer handle registered with the
|
||||
client's spooler on which the change occurred</para></listitem>
|
||||
|
||||
<listitem><para>The change_low value which was sent as part
|
||||
of the last RFNPCN request from the client</para></listitem>
|
||||
|
||||
<listitem><para>The SPOOL_NOTIFY_INFO container with the event
|
||||
information</para></listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
A <varname>SPOOL_NOTIFY_INFO</varname> contains:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
<listitem><para>the version and flags field are predefined
|
||||
and should not be changed</para></listitem>
|
||||
|
||||
<listitem><para>The count field is the number of entries
|
||||
in the SPOOL_NOTIFY_INFO_DATA array</para></listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
<para>
|
||||
The <varname>SPOOL_NOTIFY_INFO_DATA</varname> entries contain:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
<listitem><para>The type defines whether or not this event
|
||||
is for a printer or a print job</para></listitem>
|
||||
|
||||
<listitem><para>The field is the flag identifying the event</para></listitem>
|
||||
|
||||
<listitem><para>the notify_data union contains the new valuie of the
|
||||
attribute</para></listitem>
|
||||
|
||||
<listitem><para>The enc_type defines the size of the structure for marshalling
|
||||
and unmarshalling</para></listitem>
|
||||
|
||||
<listitem><para>(a) the id must be 0 for a printer event on a printer handle.
|
||||
(b) the id must be the job id for an event on a printer job
|
||||
(c) the id must be the matching number of the printer index used
|
||||
in the response packet to the RFNPCN when using a print server
|
||||
handle for notification. Samba currently uses the snum of
|
||||
the printer for this which can break if the list of services
|
||||
has been modified since the notification handle was registered.</para></listitem>
|
||||
|
||||
<listitem><para>The size is either (a) the string length in UNICODE for strings,
|
||||
(b) the size in bytes of the security descriptor, or (c) 0 for
|
||||
data values.</para></listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
</sect1>
|
||||
</chapter>
|
10
docs/devel/registry.dot
Normal file
@ -0,0 +1,10 @@
|
||||
digraph foo {
|
||||
libwinregistry -> libregistry;
|
||||
KConfig -> libregistry;
|
||||
gconf -> libregistry;
|
||||
"TDB (Samba)" -> libwinregistry;
|
||||
"Wine registry files" -> libwinregistry;
|
||||
"RPC (Remote windows server" -> libwinregistry;
|
||||
"NT4-style Registry files" -> libwinregistry;
|
||||
libregistry -> libwinregistry;
|
||||
}
|
209
docs/devel/registry.xml
Normal file
@ -0,0 +1,209 @@
|
||||
<chapter id="registry">
|
||||
<chapterinfo>
|
||||
&author.jelmer;
|
||||
<pubdate>24 September 2003</pubdate>
|
||||
</chapterinfo>
|
||||
|
||||
<title>The registry subsystem</title>
|
||||
|
||||
<sect1><title>Planned backends</title>
|
||||
|
||||
<para>
|
||||
The new registry subsystem will work with several different backends:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>NT4 (NT4 registry files)</para></listitem>
|
||||
<listitem><para>TDB (Samba TDB files)</para></listitem>
|
||||
<listitem><para>RPC (Remote Registry over RPC, reg pipe)</para></listitem>
|
||||
<listitem><para>wine (Wine Registry Files)</para></listitem>
|
||||
<listitem><para>gconf (The GNOME configuration backend)</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Data structures</title>
|
||||
|
||||
<para>
|
||||
The following structure describes a registry key:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
typedef struct reg_key_s {
|
||||
char *name; /* Name of the key */
|
||||
smb_ucs2_t *class_name; /* Name of key class */
|
||||
int type; /* One of REG_ROOT_KEY or REG_SUB_KEY */
|
||||
NTTIME last_mod; /* Time last modified */
|
||||
struct reg_key_s *owner;
|
||||
struct key_list_s *sub_keys; /* NULL indicates keys not available in memory, function should be called */
|
||||
struct val_list_s *values; /* NULL indicates values not available in memory, function should be called */
|
||||
SEC_DESC *security;
|
||||
REG_HANDLE *handle; /* Pointer to REG_HANDLE this key belongs to */
|
||||
void *backend_data; /* Pointer used by the backend */
|
||||
} REG_KEY;
|
||||
</programlisting>
|
||||
|
||||
<para>The following structure describes a registry value:</para>
|
||||
|
||||
<programlisting>
|
||||
typedef struct val_key_s {
|
||||
char *name; /* NULL if name not available */
|
||||
int data_type;
|
||||
int data_len;
|
||||
void *data_blk; /* Might want a separate block */
|
||||
REG_HANDLE *handle; /* Pointer to REG_HANDLE this key belongs to */
|
||||
void *backend_data;
|
||||
} REG_VAL;
|
||||
</programlisting>
|
||||
|
||||
<para>The following structures are used for lists of subkeys or values:</para>
|
||||
|
||||
<programlisting>
|
||||
/* container for registry subkey names */
|
||||
typedef struct key_list_s {
|
||||
TALLOC_CTX *ctx;
|
||||
uint32 num_subkeys;
|
||||
REG_KEY **subkeys;
|
||||
} REG_KEY_LIST;
|
||||
|
||||
/* container for registry values */
|
||||
typedef struct val_list_s {
|
||||
TALLOC_CTX *ctx;
|
||||
uint32 num_vals;
|
||||
REG_VAL **vals;
|
||||
} REG_VAL_LIST;
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
And this structure is used for an instance of a registry (a registry file that's opened, a remote registry pipe we're connected to, etc).
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
typedef struct reg_handle_s {
|
||||
REGISTRY_OPS *functions;
|
||||
REG_KEY *root; /* NULL if not available */
|
||||
void *backend_data;
|
||||
} REG_HANDLE;
|
||||
</programlisting>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>External interface</title>
|
||||
|
||||
<programlisting>
|
||||
REG_HANDLE *reg_open(char *backend, char *location, BOOL try_full_load);
|
||||
REG_KEY *reg_open_key(REG_KEY *parent, char *name);
|
||||
REG_VAL *reg_key_get_val(REG_KEY *key, char *name);
|
||||
REG_VAL_LIST *reg_key_get_vals(REG_KEY *key);
|
||||
REG_KEY_LIST *reg_key_get_subkeys(REG_KEY *key);
|
||||
BOOL reg_key_del(REG_KEY *key);
|
||||
BOOL reg_val_del(REG_VAL *val);
|
||||
BOOL reg_key_add(REG_KEY *parent, REG_KEY *key);
|
||||
BOOL reg_val_add(REG_KEY *parent, REG_VAL *val):
|
||||
BOOL reg_val_update(REG_VAL *val);
|
||||
BOOL reg_key_update(REG_KEY *key);
|
||||
void reg_free_key(REG_KEY *key);
|
||||
void reg_free_val(REG_VAL *val);
|
||||
void reg_free(REG_HANDLE *h);
|
||||
void reg_free_key_list(REG_KEY_LIST *list):
|
||||
void reg_free_val_list(REG_VAL_LIST *list):
|
||||
</programlisting>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Utility functions</title>
|
||||
|
||||
<para>The following helper functions are available:</para>
|
||||
|
||||
<programlisting>
|
||||
void reg_key_list_init( REG_KEY_LIST *ctr );
|
||||
int reg_key_list_addkey( REG_KEY_LIST *ctr, const char *keyname );
|
||||
int reg_key_list_numkeys( REG_KEY_LIST *ctr );
|
||||
char* reg_key_list_specific_key( REG_KEY_LIST *ctr, uint32 key_index );
|
||||
void reg_key_list_destroy( REG_KEY_LIST *ctr );
|
||||
void reg_val_list_init( REG_VAL_LIST *ctr );
|
||||
int reg_val_list_numvals( REG_VAL_LIST *ctr );
|
||||
void free_registry_value( REG_VAL *val );
|
||||
uint8* regval_data_p( REG_VAL *val );
|
||||
int regval_size( REG_VAL *val );
|
||||
char* regval_name( REG_VAL *val );
|
||||
uint32 regval_type( REG_VAL *val );
|
||||
TALLOC_CTX* reg_val_list_getctx( REG_VAL_LIST *val );
|
||||
int reg_val_list_addvalue( REG_VAL_LIST *ctr, const char *name, uint16 type,
|
||||
const char *data_p, size_t size );
|
||||
int reg_val_list_copyvalue( REG_VAL_LIST *ctr, REG_VAL *val );
|
||||
int reg_val_list_delvalue( REG_VAL_LIST *ctr, const char *name );
|
||||
void reg_val_list_destroy( REG_VAL_LIST *ctr );
|
||||
</programlisting>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Writing backends</title>
|
||||
|
||||
<para>There are basically two ways of reading data from the registry: loading
|
||||
it all into memory and then working in this copy in memory, or
|
||||
re-reading/re-opening it every time necessary.</para>
|
||||
|
||||
<para>This interface aims to support both types. </para>
|
||||
|
||||
<para>A registry backend should provide the following functions:</para>
|
||||
|
||||
<programlisting>
|
||||
typedef struct {
|
||||
REG_HANDLE *(*open_registry) (const char *location, BOOL try_complete_load);
|
||||
REG_KEY *(*open_root_key) (REG_HANDLE *);
|
||||
REG_KEY *(*open_key_rel) (REG_KEY *parent, const char *name);
|
||||
/* if open_key_abs is set to NULL, a default implementation will be provided. */
|
||||
REG_KEY *(*open_key_abs) (REG_HANDLE *, const char *name);
|
||||
REG_KEY_LIST *(*get_subkeys) (REG_KEY *);
|
||||
REG_VAL_LIST *(*get_values) (REG_KEY *);
|
||||
BOOL (*add_key)(REG_KEY *, REG_KEY *);
|
||||
BOOL (*update_key)(REG_KEY *);
|
||||
BOOL (*del_key)(REG_KEY *);
|
||||
BOOL (*add_value)(REG_KEY *, REG_VAL *);
|
||||
BOOL (*update_value)(REG_VAL *);
|
||||
BOOL (*del_value)(REG_VAL *);
|
||||
REG_VAL *(*get_value) (REG_KEY *, const char *name);
|
||||
/* It is not guaranteed that no data has been stored before save()
|
||||
* has been called. This function is only useful for backends that
|
||||
* store the data in memory and then write out the whole registry at once */
|
||||
BOOL (*save)(REG_HANDLE *, const char *location);
|
||||
BOOL (*close_registry) (REG_HANDLE *);
|
||||
void (*free_key)(REG_KEY *);
|
||||
void (*free_value)(REG_VAL *);
|
||||
} REGISTRY_OPS;
|
||||
</programlisting>
|
||||
|
||||
<para>open_root_key() is optional. It's only called if the
|
||||
<parameter>root</parameter> field of the REG_HANDLE struct is NULL.</para>
|
||||
|
||||
<para>open_key_abs() is optional. If it's NULL, the frontend will
|
||||
provide a replacement, using open_key_rel().</para>
|
||||
|
||||
<para>get_values() and get_value() are optional. They're only called if
|
||||
the <parameter>values</parameter> field of the REG_KEY struct is NULL.</para>
|
||||
|
||||
<para>get_subkeys() and get_key() are optional. THey're only called
|
||||
if the <parameter>subkeys</parameter> field of the REG_KEY struct is NULL.</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1><title>Memory allocation</title>
|
||||
|
||||
<para>Okay, so who's responsible for what parts of the memory? </para>
|
||||
|
||||
<para>The memory is basically maintained by the backends. When the user
|
||||
is finished using a particular structure, it should call the related free
|
||||
function for the structure it's freeing.</para>
|
||||
|
||||
<para>The backend should then decide what to do with the structure. It may
|
||||
choose to free it, or, if it's maintaining single copies of everything in
|
||||
memory, may choose to ignore the free and free it when the registry is closed.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
88
docs/devel/rpc_plugin.xml
Normal file
@ -0,0 +1,88 @@
|
||||
<chapter id="rpc-plugin">
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>Anthony</firstname><surname>Liguori</surname>
|
||||
<affiliation>
|
||||
<orgname>IBM</orgname>
|
||||
<address><email>aliguor@us.ibm.com</email></address>
|
||||
</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Jelmer</firstname><surname>Vernooij</surname>
|
||||
<affiliation>
|
||||
<orgname>Samba Team</orgname>
|
||||
<address><email>jelmer@samba.org</email></address>
|
||||
</affiliation>
|
||||
</author>
|
||||
<pubdate>January 2003</pubdate>
|
||||
</chapterinfo>
|
||||
|
||||
<title>RPC Pluggable Modules</title>
|
||||
|
||||
<sect1>
|
||||
<title>About</title>
|
||||
|
||||
<para>
|
||||
This document describes how to make use the new RPC Pluggable Modules features
|
||||
of Samba 3.0. This architecture was added to increase the maintainability of
|
||||
Samba allowing RPC Pipes to be worked on separately from the main CVS branch.
|
||||
The RPM architecture will also allow third-party vendors to add functionality
|
||||
to Samba through plug-ins.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>General Overview</title>
|
||||
|
||||
<para>
|
||||
When an RPC call is sent to smbd, smbd tries to load a shared library by the
|
||||
name <filename>librpc_<pipename>.so</filename> to handle the call if
|
||||
it doesn't know how to handle the call internally. For instance, LSA calls
|
||||
are handled by <filename>librpc_lsass.so</filename>..
|
||||
These shared libraries should be located in the <filename><sambaroot>/lib/rpc</filename>. smbd then attempts to call the init_module function within
|
||||
the shared library. Check the chapter on modules for more information.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In the init_module function, the library should call
|
||||
rpc_pipe_register_commands(). This function takes the following arguments:
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *srv,
|
||||
const struct api_struct *cmds, int size);
|
||||
</programlisting></para>
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry><term>version</term>
|
||||
<listitem><para>Version number of the RPC interface. Use the define <emphasis>SMB_RPC_INTERFACE_VERSION</emphasis> for this
|
||||
argument.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term>clnt</term>
|
||||
<listitem><para>the Client name of the named pipe</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term>srv</term>
|
||||
<listitem><para>the Server name of the named pipe</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term>cmds</term>
|
||||
<listitem><para>a list of api_structs that map RPC ordinal numbers to function calls</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term>size</term>
|
||||
<listitem><para>the number of api_structs contained in cmds</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<para>
|
||||
See rpc_server/srv_reg.c and rpc_server/srv_reg_nt.c for a small example of
|
||||
how to use this library.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
</chapter>
|
357
docs/devel/sam.xml
Normal file
@ -0,0 +1,357 @@
|
||||
<chapter id="sam">
|
||||
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>Andrew</firstname><surname>Bartlett</surname>
|
||||
</author>
|
||||
<pubdate>1 October 2002</pubdate>
|
||||
</chapterinfo>
|
||||
|
||||
<title>The Upcoming SAM System</title>
|
||||
|
||||
<sect1>
|
||||
<title>Security in the 'new SAM'</title>
|
||||
|
||||
<para>One of the biggest problems with passdb is it's implementation of
|
||||
'security'. Access control is on a 'are you root at the moment' basis,
|
||||
and it has no concept of NT ACLs. Things like ldapsam had to add
|
||||
'magic' 'are you root' checks.</para>
|
||||
|
||||
<para>We took this very seriously when we started work, and the new structure
|
||||
is designed with this in mind, from the ground up. Each call to the SAM
|
||||
has a NT_TOKEN and (if relevant) an 'access desired'. This is either
|
||||
provided as a parameter, or implicitly supplied by the object being
|
||||
accessed.</para>
|
||||
|
||||
<para>
|
||||
For example, when you call
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
NTSTATUS sam_get_account_by_name(const SAM_CONTEXT *context, const
|
||||
NT_USER_TOKEN *access_token, uint32 access_desired, const char *domain,
|
||||
const char *name, SAM_ACCOUNT_HANDLE **account)
|
||||
</programlisting>
|
||||
|
||||
<para>
|
||||
The context can be NULL (and is used to allow import/export by setting
|
||||
up 2 contexts, and allowing calls on both simultaneously)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The access token *must* be specified. Normally the user's token out of
|
||||
current_user, this can also be a global 'system' context.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The access desired is as per the ACL, for passing to the seaccess stuff.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The domain/username are standard. Even if we only have one domain,
|
||||
keeping this ensures that we don't get 'unqualified' usernames (same
|
||||
problem as we had with unqualified SIDs).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
We return a 'handle'. This is opaque to the rest of Samba, but is
|
||||
operated on by get/set routines, all of which return NTSTATUS.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The access checking is done by the SAM module. The reason it is not
|
||||
done 'above' the interface is to ensure a 'choke point'. I put a lot of
|
||||
effort into the auth subsystem to ensure we never 'accidentally' forgot
|
||||
to check for null passwords, missed a restriction etc. I intend the SAM
|
||||
to be written with the same caution.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The reason the access checking is not handled by the interface itself is
|
||||
due to the different implementations it make take on. For example, on
|
||||
ADS, you cannot set a password over a non-SSL connection. Other
|
||||
backends may have similar requirements - we need to leave this policy up
|
||||
to the modules. They will naturally have access to 'helper' procedures
|
||||
and good examples to avoid mishaps.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
(Furthermore, some backends my actually chose to push the whole ACL
|
||||
issue to the remote server, and - assuming ldap for this example - bind
|
||||
as the user directly)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Each returned handle has an internal 'access permitted', which allows
|
||||
the 'get' and 'set' routines to return 'ACCESS_DENIED' for things that
|
||||
were not able to be retrieved from the backend. This removes the need
|
||||
to specify the NT_TOKEN on every operation, and allows for 'object not
|
||||
present' to be easily distinguished from 'access denied'.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
When you 'set' an object (calling sam_update_account) the internal
|
||||
details are again used. Each change that has been made to the object
|
||||
has been flagged, so as to avoid race conditions (on unmodified
|
||||
components) and to avoid violating any extra ACL requirements on the
|
||||
actual data store (like the LDAP server).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Finally, we have generic get_sec_desc() and set_sec_desc() routines to
|
||||
allow external ACL manipulation. These do lookups based on SID.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Standalone from UNIX</title>
|
||||
|
||||
<para>
|
||||
One of the primary tenants of the 'new SAM' is that it would not attempt
|
||||
to deal with 'what unix id for that'. This would be left to the 'SMS'
|
||||
(Sid Mapping System') or SID farm, and probably administered via
|
||||
winbind. We have had constructive discussion on how 'basic' unix
|
||||
accounts like 'root' would be handled, and we think this can work.
|
||||
Accounts not preexisting in unix would be served up via winbind.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This is an *optional* part, and my preferred end-game. We have a fare
|
||||
way to go before things like winbind up to it however.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Handles and Races in the new SAM</title>
|
||||
|
||||
<para>
|
||||
One of the things that the 'new SAM' work has tried to face is both
|
||||
compatibility with existing code, and a closer alignment to the SAMR
|
||||
interface. I consider SAMR to be a 'primary customer' to the this work,
|
||||
because if we get alignment with that wrong, things get more, rather
|
||||
than less complex. Also, most other parts of Samba are much more
|
||||
flexible with what they can allow.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In any case, that was a decision taken as to how the general design
|
||||
would progress. BTW, my understanding of SAMR may be completely flawed.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
One of the most race-prone areas of the new code is the conflicting
|
||||
update problem. We have taken two approaches:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>'Not conflicting' conflicts. Due to the way usrmgr operates, it will
|
||||
open a user, display all the properties and *save* them all, even if you
|
||||
don't change any.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For this, see what I've done in rpc_server/srv_samr_util.c. I intend
|
||||
to take this one step further, and operate on the 'handle' that the
|
||||
values were read from. This should mean that we only update things that
|
||||
have *really* changed.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
'conflicting' updates: Currently we don't deal with this (in passdb
|
||||
or the new sam stuff), but the design is sufficiently flexible to 'deny'
|
||||
a second update. I don't foresee locking records however.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Layers</title>
|
||||
|
||||
<sect2>
|
||||
<title>Application</title>
|
||||
|
||||
<para>
|
||||
This is where smbd, samtest and whatever end-user replacement we have
|
||||
for pdbedit sits. They use only the SAM interface, and do not get
|
||||
'special knowledge' of what is below them.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>SAM Interface</title>
|
||||
|
||||
<para>
|
||||
This level 'owns' the various handle structures, the get/set routines on
|
||||
those structures and provides the public interface. The application
|
||||
layer may initialize a 'context' to be passed to all interface routines,
|
||||
else a default, self-initialising context will be supplied. This layser
|
||||
finds the appropriate backend module for the task, and tries very hard
|
||||
not to need to much 'knowledge'. It should just provide the required
|
||||
abstraction to the modules below, and arrange for their initial loading.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
We could possibly add ACL checking at this layer, to avoid discrepancies
|
||||
in implementation modules.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>SAM Modules</title>
|
||||
|
||||
<para>
|
||||
These do not communicate with the application directly, only by setting
|
||||
values in the handles, and receiving requests from the interface. These
|
||||
modules are responsible for translating values from the handle's
|
||||
.private into (say) an LDAP modification list. The module is expected
|
||||
to 'know' things like it's own domain SID, domain name, and any other
|
||||
state attached to the SAM. Simpler modules may call back to some helper
|
||||
routine.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>SAM Modules</title>
|
||||
|
||||
<sect2>
|
||||
<title>Special Module: sam_passdb</title>
|
||||
|
||||
<para>
|
||||
In order for there to be a smooth transition, kai is writing a module
|
||||
that reads existing passdb backends, and translates them into SAM
|
||||
replies. (Also pulling data from the account policy DB etc). We also
|
||||
intend to write a module that does the reverse - gives the SAM a passdb
|
||||
interface.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>sam_ads</title>
|
||||
<para>
|
||||
This is the first of the SAM modules to be committed to the tree -
|
||||
mainly because I needed to coordinate work with metze (who authored most
|
||||
of it). This module aims to use Samba's libads code to provide an
|
||||
Active Directory LDAP client, suitable for use on a mixed-mode DC.
|
||||
While it is currently being tested against Win2k servers (with a
|
||||
password in the smb.conf file) it is expected to eventually use a
|
||||
(possibly modified) OpenLDAP server. We hope that this will assist in
|
||||
the construction of an Samba AD DC.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
We also intend to construct a Samba 2.2/3.0 compatible ldap module,
|
||||
again using libads code.
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Memory Management</title>
|
||||
|
||||
<para>
|
||||
The 'new SAM' development effort also concerned itself with getting a
|
||||
sane implementation of memory management. It was decided that we would
|
||||
be (as much as possible) talloc based, using an 'internal talloc
|
||||
context' on many objects. That is, the creation of an object would
|
||||
initiate it's own internal talloc context, and this would be used for
|
||||
all operations on that object. Much of this is already implemented in
|
||||
passdb. Also, like passdb, it will be possible to specify that some
|
||||
object actually be created on a specified context.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Memory management is important here because the APIs in the 'new SAM' do
|
||||
not use 'pdb_init()' or an equivalent. They always allocate new
|
||||
objects. Enumeration's are slightly different, and occur on a supplied
|
||||
context that 'owns' the entire list, rather than per-element. (the
|
||||
enumeration functions return an array of all elements - not full handles
|
||||
just basic (and public) info) Likewise for things that fill in a char
|
||||
**.
|
||||
</para>
|
||||
|
||||
<para>For example:</para>
|
||||
|
||||
<para><programlisting>
|
||||
NTSTATUS sam_lookup_sid(const SAM_CONTEXT *context, const NT_USER_TOKEN
|
||||
*access_token, TALLOC_CTX *mem_ctx, const DOM_SID *sid, char **name,
|
||||
uint32 *type)
|
||||
</programlisting></para>
|
||||
|
||||
<para>Takes a context to allocate the 'name' on, while:</para>
|
||||
|
||||
<para><programlisting>
|
||||
NTSTATUS sam_get_account_by_sid(const SAM_CONTEXT *context, const
|
||||
NT_USER_TOKEN *access_token, uint32 access_desired, const DOM_SID
|
||||
*accountsid, SAM_ACCOUNT_HANDLE **account)
|
||||
</programlisting></para>
|
||||
|
||||
<para>Allocates a handle and stores the allocation context on that handle.</para>
|
||||
|
||||
<para>I think that the following:</para>
|
||||
|
||||
<para><programlisting>
|
||||
NTSTATUS sam_enum_accounts(const SAM_CONTEXT *context, const
|
||||
NT_USER_TOKEN *access_token, const DOM_SID *domainsid, uint16 acct_ctrl,
|
||||
int32 *account_count, SAM_ACCOUNT_ENUM **accounts)
|
||||
</programlisting></para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Testing</title>
|
||||
|
||||
<para>
|
||||
Testing is vital in any piece of software, and Samba is certainly no
|
||||
exception. In designing this new subsystem, we have taken care to ensure
|
||||
it is easily tested, independent of outside protocols.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To this end, Jelmer has constructed 'samtest'.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This utility (see torture/samtest.c) is structured like rpcclient, but
|
||||
instead operates on the SAM subsystem. It creates a 'custom' SAM
|
||||
context, that may be distinct from the default values used by the rest
|
||||
of the system, and can load a separate configuration file.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
A small number of commands are currently implemented, but these have
|
||||
already proved vital in testing. I expect SAM module authors will find
|
||||
it particularly valuable.
|
||||
</para>
|
||||
|
||||
<para>Example useage:</para>
|
||||
|
||||
<para><prompt>$</prompt> <command>bin/samtest</command></para>
|
||||
|
||||
<para><programlisting>
|
||||
> context ads:ldap://192.168.1.96
|
||||
</programlisting>
|
||||
(this loads a new context, using the new ADS module. The parameter is
|
||||
the 'location' of the ldap server)
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
> lookup_name DOMAIN abartlet
|
||||
</programlisting>
|
||||
(returns a sid).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Because the 'new SAM' is NT ACL based, there will be a command to
|
||||
specify an arbitrary NT ACL, but for now it uses 'system' by default.
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
316
docs/devel/unix-smb.xml
Normal file
@ -0,0 +1,316 @@
|
||||
<chapter id="unix-smb">
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>Andrew</firstname><surname>Tridgell</surname>
|
||||
</author>
|
||||
<pubdate>April 1995</pubdate>
|
||||
</chapterinfo>
|
||||
|
||||
<title>NetBIOS in a Unix World</title>
|
||||
|
||||
<sect1>
|
||||
<title>Introduction</title>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
It was written to help out a person who was writing a paper on unix to
|
||||
PC connectivity.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Usernames</title>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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).
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>File Ownership</title>
|
||||
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
There are several possible solutions to this problem, including
|
||||
username mapping, and forcing a specific username for particular
|
||||
shares.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Passwords</title>
|
||||
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Unix passwords are case sensitive. So if users use mixed case
|
||||
passwords they are in trouble.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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 its validation via another machine
|
||||
(typically a WinNT server).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Samba supports the password encryption method used by SMB
|
||||
clients. Note that the use of password encryption in Microsoft
|
||||
networking leads to password hashes that are "plain text equivalent".
|
||||
This means that it is *VERY* important to ensure that the Samba
|
||||
smbpasswd file containing these password hashes is only readable
|
||||
by the root user. See the documentation ENCRYPTION.txt for more
|
||||
details.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Locking</title>
|
||||
<para>
|
||||
Since samba 2.2, samba supports other types of locking as well. This
|
||||
section is outdated.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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 its lock. Unix has no simple way of implementing
|
||||
opportunistic locking, and currently Samba has no support for it.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Deny Modes</title>
|
||||
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Unix has no equivalent notion. To implement this Samba uses either lock
|
||||
files based on the files inode and placed in a separate lock
|
||||
directory or a shared memory implementation. The lock file method
|
||||
is clumsy and consumes processing and file resources,
|
||||
the shared memory implementation is vastly prefered and is turned on
|
||||
by default for those systems that support it.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Trapdoor UIDs</title>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Note that you can also get the "trapdoor uid" message for other
|
||||
reasons. Please see the FAQ for details.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Port numbers</title>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Protocol Complexity</title>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
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. Microsoft recently
|
||||
renamed the SMB protocol CIFS (Common Internet File System) and have
|
||||
published new specifications. These are far superior to the old
|
||||
X/Open documents but there are still undocumented calls and features.
|
||||
This specification is actively being worked on by a CIFS developers
|
||||
mailing list hosted by Microsft.
|
||||
</para>
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
797
docs/devel/vfs.xml
Normal file
@ -0,0 +1,797 @@
|
||||
<chapter id="vfs">
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>Alexander</firstname><surname>Bokovoy</surname>
|
||||
<affiliation>
|
||||
<address><email>ab@samba.org</email></address>
|
||||
</affiliation>
|
||||
</author>
|
||||
<author>
|
||||
<firstname>Stefan</firstname><surname>Metzmacher</surname>
|
||||
<affiliation>
|
||||
<address><email>metze@samba.org</email></address>
|
||||
</affiliation>
|
||||
</author>
|
||||
<pubdate> 27 May 2003 </pubdate>
|
||||
</chapterinfo>
|
||||
|
||||
<title>VFS Modules</title>
|
||||
|
||||
<sect1>
|
||||
<title>The Samba (Posix) VFS layer</title>
|
||||
|
||||
<sect2>
|
||||
<title>The general interface</title>
|
||||
|
||||
<para>
|
||||
Each VFS operation has a vfs_op_type, a function pointer and a handle pointer in the
|
||||
struct vfs_ops and tree macros to make it easier to call the operations.
|
||||
(Take a look at <filename>include/vfs.h</filename> and <filename>include/vfs_macros.h</filename>.)
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
typedef enum _vfs_op_type {
|
||||
SMB_VFS_OP_NOOP = -1,
|
||||
|
||||
...
|
||||
|
||||
/* File operations */
|
||||
|
||||
SMB_VFS_OP_OPEN,
|
||||
SMB_VFS_OP_CLOSE,
|
||||
SMB_VFS_OP_READ,
|
||||
SMB_VFS_OP_WRITE,
|
||||
SMB_VFS_OP_LSEEK,
|
||||
SMB_VFS_OP_SENDFILE,
|
||||
|
||||
...
|
||||
|
||||
SMB_VFS_OP_LAST
|
||||
} vfs_op_type;
|
||||
</programlisting></para>
|
||||
|
||||
<para>This struct contains the function and handle pointers for all operations.<programlisting>
|
||||
struct vfs_ops {
|
||||
struct vfs_fn_pointers {
|
||||
...
|
||||
|
||||
/* File operations */
|
||||
|
||||
int (*open)(struct vfs_handle_struct *handle,
|
||||
struct connection_struct *conn,
|
||||
const char *fname, int flags, mode_t mode);
|
||||
int (*close)(struct vfs_handle_struct *handle,
|
||||
struct files_struct *fsp, int fd);
|
||||
ssize_t (*read)(struct vfs_handle_struct *handle,
|
||||
struct files_struct *fsp, int fd, void *data, size_t n);
|
||||
ssize_t (*write)(struct vfs_handle_struct *handle,
|
||||
struct files_struct *fsp, int fd,
|
||||
const void *data, size_t n);
|
||||
SMB_OFF_T (*lseek)(struct vfs_handle_struct *handle,
|
||||
struct files_struct *fsp, int fd,
|
||||
SMB_OFF_T offset, int whence);
|
||||
ssize_t (*sendfile)(struct vfs_handle_struct *handle,
|
||||
int tofd, files_struct *fsp, int fromfd,
|
||||
const DATA_BLOB *header, SMB_OFF_T offset, size_t count);
|
||||
|
||||
...
|
||||
} ops;
|
||||
|
||||
struct vfs_handles_pointers {
|
||||
...
|
||||
|
||||
/* File operations */
|
||||
|
||||
struct vfs_handle_struct *open;
|
||||
struct vfs_handle_struct *close;
|
||||
struct vfs_handle_struct *read;
|
||||
struct vfs_handle_struct *write;
|
||||
struct vfs_handle_struct *lseek;
|
||||
struct vfs_handle_struct *sendfile;
|
||||
|
||||
...
|
||||
} handles;
|
||||
};
|
||||
</programlisting></para>
|
||||
|
||||
<para>
|
||||
This macros SHOULD be used to call any vfs operation.
|
||||
DO NOT ACCESS conn->vfs.ops.* directly !!!
|
||||
<programlisting>
|
||||
...
|
||||
|
||||
/* File operations */
|
||||
#define SMB_VFS_OPEN(conn, fname, flags, mode) \
|
||||
((conn)->vfs.ops.open((conn)->vfs.handles.open,\
|
||||
(conn), (fname), (flags), (mode)))
|
||||
#define SMB_VFS_CLOSE(fsp, fd) \
|
||||
((fsp)->conn->vfs.ops.close(\
|
||||
(fsp)->conn->vfs.handles.close, (fsp), (fd)))
|
||||
#define SMB_VFS_READ(fsp, fd, data, n) \
|
||||
((fsp)->conn->vfs.ops.read(\
|
||||
(fsp)->conn->vfs.handles.read,\
|
||||
(fsp), (fd), (data), (n)))
|
||||
#define SMB_VFS_WRITE(fsp, fd, data, n) \
|
||||
((fsp)->conn->vfs.ops.write(\
|
||||
(fsp)->conn->vfs.handles.write,\
|
||||
(fsp), (fd), (data), (n)))
|
||||
#define SMB_VFS_LSEEK(fsp, fd, offset, whence) \
|
||||
((fsp)->conn->vfs.ops.lseek(\
|
||||
(fsp)->conn->vfs.handles.lseek,\
|
||||
(fsp), (fd), (offset), (whence)))
|
||||
#define SMB_VFS_SENDFILE(tofd, fsp, fromfd, header, offset, count) \
|
||||
((fsp)->conn->vfs.ops.sendfile(\
|
||||
(fsp)->conn->vfs.handles.sendfile,\
|
||||
(tofd), (fsp), (fromfd), (header), (offset), (count)))
|
||||
|
||||
...
|
||||
</programlisting></para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Possible VFS operation layers</title>
|
||||
|
||||
<para>
|
||||
These values are used by the VFS subsystem when building the conn->vfs
|
||||
and conn->vfs_opaque structs for a connection with multiple VFS modules.
|
||||
Internally, Samba differentiates only opaque and transparent layers at this process.
|
||||
Other types are used for providing better diagnosing facilities.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Most modules will provide transparent layers. Opaque layer is for modules
|
||||
which implement actual file system calls (like DB-based VFS). For example,
|
||||
default POSIX VFS which is built in into Samba is an opaque VFS module.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Other layer types (logger, splitter, scanner) were designed to provide different
|
||||
degree of transparency and for diagnosing VFS module behaviour.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Each module can implement several layers at the same time provided that only
|
||||
one layer is used per each operation.
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
typedef enum _vfs_op_layer {
|
||||
SMB_VFS_LAYER_NOOP = -1, /* - For using in VFS module to indicate end of array */
|
||||
/* of operations description */
|
||||
SMB_VFS_LAYER_OPAQUE = 0, /* - Final level, does not call anything beyond itself */
|
||||
SMB_VFS_LAYER_TRANSPARENT, /* - Normal operation, calls underlying layer after */
|
||||
/* possibly changing passed data */
|
||||
SMB_VFS_LAYER_LOGGER, /* - Logs data, calls underlying layer, logging may not */
|
||||
/* use Samba VFS */
|
||||
SMB_VFS_LAYER_SPLITTER, /* - Splits operation, calls underlying layer _and_ own facility, */
|
||||
/* then combines result */
|
||||
SMB_VFS_LAYER_SCANNER /* - Checks data and possibly initiates additional */
|
||||
/* file activity like logging to files _inside_ samba VFS */
|
||||
} vfs_op_layer;
|
||||
</programlisting></para>
|
||||
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>The Interaction between the Samba VFS subsystem and the modules</title>
|
||||
|
||||
<sect2>
|
||||
<title>Initialization and registration</title>
|
||||
|
||||
<para>
|
||||
As each Samba module a VFS module should have a
|
||||
<programlisting>NTSTATUS vfs_example_init(void);</programlisting> function if it's staticly linked to samba or
|
||||
<programlisting>NTSTATUS init_module(void);</programlisting> function if it's a shared module.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This should be the only non static function inside the module.
|
||||
Global variables should also be static!
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The module should register its functions via the
|
||||
<programlisting>
|
||||
NTSTATUS smb_register_vfs(int version, const char *name, vfs_op_tuple *vfs_op_tuples);
|
||||
</programlisting> function.
|
||||
</para>
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry><term>version</term>
|
||||
<listitem><para>should be filled with SMB_VFS_INTERFACE_VERSION</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term>name</term>
|
||||
<listitem><para>this is the name witch can be listed in the
|
||||
<command>vfs objects</command> parameter to use this module.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term>vfs_op_tuples</term>
|
||||
<listitem><para>
|
||||
this is an array of vfs_op_tuple's.
|
||||
(vfs_op_tuples is descripted in details below.)
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<para>
|
||||
For each operation the module wants to provide it has a entry in the
|
||||
vfs_op_tuple array.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
typedef struct _vfs_op_tuple {
|
||||
void* op;
|
||||
vfs_op_type type;
|
||||
vfs_op_layer layer;
|
||||
} vfs_op_tuple;
|
||||
</programlisting>
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry><term>op</term>
|
||||
<listitem><para>the function pointer to the specified function.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term>type</term>
|
||||
<listitem><para>the vfs_op_type of the function to specified witch operation the function provides.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term>layer</term>
|
||||
<listitem><para>the vfs_op_layer in whitch the function operates.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<para>A simple example:</para>
|
||||
|
||||
<programlisting>
|
||||
static vfs_op_tuple example_op_tuples[] = {
|
||||
{SMB_VFS_OP(example_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT},
|
||||
{SMB_VFS_OP(example_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_TRANSPARENT},
|
||||
|
||||
{SMB_VFS_OP(example_rename), SMB_VFS_OP_RENAME, SMB_VFS_LAYER_OPAQUE},
|
||||
|
||||
/* This indicates the end of the array */
|
||||
{SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
|
||||
};
|
||||
|
||||
NTSTATUS init_module(void)
|
||||
{
|
||||
return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "example", example_op_tuples);
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>How the Modules handle per connection data</title>
|
||||
|
||||
<para>Each VFS function has as first parameter a pointer to the modules vfs_handle_struct.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
typedef struct vfs_handle_struct {
|
||||
struct vfs_handle_struct *next, *prev;
|
||||
const char *param;
|
||||
struct vfs_ops vfs_next;
|
||||
struct connection_struct *conn;
|
||||
void *data;
|
||||
void (*free_data)(void **data);
|
||||
} vfs_handle_struct;
|
||||
</programlisting>
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry><term>param</term>
|
||||
<listitem><para>this is the module parameter specified in the <command>vfs objects</command> parameter.</para>
|
||||
<para>e.g. for 'vfs objects = example:test' param would be "test".</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term>vfs_next</term>
|
||||
<listitem><para>This vfs_ops struct contains the information for calling the next module operations.
|
||||
Use the SMB_VFS_NEXT_* macros to call a next module operations and
|
||||
don't access handle->vfs_next.ops.* directly!</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term>conn</term>
|
||||
<listitem><para>This is a pointer back to the connection_struct to witch the handle belongs.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term>data</term>
|
||||
<listitem><para>This is a pointer for holding module private data.
|
||||
You can alloc data with connection life time on the handle->conn->mem_ctx TALLOC_CTX.
|
||||
But you can also manage the memory allocation yourself.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term>free_data</term>
|
||||
<listitem><para>This is a function pointer to a function that free's the module private data.
|
||||
If you talloc your private data on the TALLOC_CTX handle->conn->mem_ctx,
|
||||
you can set this function pointer to NULL.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<para>Some useful MACROS for handle private data.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
#define SMB_VFS_HANDLE_GET_DATA(handle, datap, type, ret) { \
|
||||
if (!(handle)||((datap=(type *)(handle)->data)==NULL)) { \
|
||||
DEBUG(0,("%s() failed to get vfs_handle->data!\n",FUNCTION_MACRO)); \
|
||||
ret; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SMB_VFS_HANDLE_SET_DATA(handle, datap, free_fn, type, ret) { \
|
||||
if (!(handle)) { \
|
||||
DEBUG(0,("%s() failed to set handle->data!\n",FUNCTION_MACRO)); \
|
||||
ret; \
|
||||
} else { \
|
||||
if ((handle)->free_data) { \
|
||||
(handle)->free_data(&(handle)->data); \
|
||||
} \
|
||||
(handle)->data = (void *)datap; \
|
||||
(handle)->free_data = free_fn; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SMB_VFS_HANDLE_FREE_DATA(handle) { \
|
||||
if ((handle) && (handle)->free_data) { \
|
||||
(handle)->free_data(&(handle)->data); \
|
||||
} \
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
<para>How SMB_VFS_LAYER_TRANSPARENT functions can call the SMB_VFS_LAYER_OPAQUE functions.</para>
|
||||
|
||||
<para>The easiest way to do this is to use the SMB_VFS_OPAQUE_* macros.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
...
|
||||
/* File operations */
|
||||
#define SMB_VFS_OPAQUE_OPEN(conn, fname, flags, mode) \
|
||||
((conn)->vfs_opaque.ops.open(\
|
||||
(conn)->vfs_opaque.handles.open,\
|
||||
(conn), (fname), (flags), (mode)))
|
||||
#define SMB_VFS_OPAQUE_CLOSE(fsp, fd) \
|
||||
((fsp)->conn->vfs_opaque.ops.close(\
|
||||
(fsp)->conn->vfs_opaque.handles.close,\
|
||||
(fsp), (fd)))
|
||||
#define SMB_VFS_OPAQUE_READ(fsp, fd, data, n) \
|
||||
((fsp)->conn->vfs_opaque.ops.read(\
|
||||
(fsp)->conn->vfs_opaque.handles.read,\
|
||||
(fsp), (fd), (data), (n)))
|
||||
#define SMB_VFS_OPAQUE_WRITE(fsp, fd, data, n) \
|
||||
((fsp)->conn->vfs_opaque.ops.write(\
|
||||
(fsp)->conn->vfs_opaque.handles.write,\
|
||||
(fsp), (fd), (data), (n)))
|
||||
#define SMB_VFS_OPAQUE_LSEEK(fsp, fd, offset, whence) \
|
||||
((fsp)->conn->vfs_opaque.ops.lseek(\
|
||||
(fsp)->conn->vfs_opaque.handles.lseek,\
|
||||
(fsp), (fd), (offset), (whence)))
|
||||
#define SMB_VFS_OPAQUE_SENDFILE(tofd, fsp, fromfd, header, offset, count) \
|
||||
((fsp)->conn->vfs_opaque.ops.sendfile(\
|
||||
(fsp)->conn->vfs_opaque.handles.sendfile,\
|
||||
(tofd), (fsp), (fromfd), (header), (offset), (count)))
|
||||
...
|
||||
</programlisting>
|
||||
|
||||
<para>How SMB_VFS_LAYER_TRANSPARENT functions can call the next modules functions.</para>
|
||||
|
||||
<para>The easiest way to do this is to use the SMB_VFS_NEXT_* macros.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
...
|
||||
/* File operations */
|
||||
#define SMB_VFS_NEXT_OPEN(handle, conn, fname, flags, mode) \
|
||||
((handle)->vfs_next.ops.open(\
|
||||
(handle)->vfs_next.handles.open,\
|
||||
(conn), (fname), (flags), (mode)))
|
||||
#define SMB_VFS_NEXT_CLOSE(handle, fsp, fd) \
|
||||
((handle)->vfs_next.ops.close(\
|
||||
(handle)->vfs_next.handles.close,\
|
||||
(fsp), (fd)))
|
||||
#define SMB_VFS_NEXT_READ(handle, fsp, fd, data, n) \
|
||||
((handle)->vfs_next.ops.read(\
|
||||
(handle)->vfs_next.handles.read,\
|
||||
(fsp), (fd), (data), (n)))
|
||||
#define SMB_VFS_NEXT_WRITE(handle, fsp, fd, data, n) \
|
||||
((handle)->vfs_next.ops.write(\
|
||||
(handle)->vfs_next.handles.write,\
|
||||
(fsp), (fd), (data), (n)))
|
||||
#define SMB_VFS_NEXT_LSEEK(handle, fsp, fd, offset, whence) \
|
||||
((handle)->vfs_next.ops.lseek(\
|
||||
(handle)->vfs_next.handles.lseek,\
|
||||
(fsp), (fd), (offset), (whence)))
|
||||
#define SMB_VFS_NEXT_SENDFILE(handle, tofd, fsp, fromfd, header, offset, count) \
|
||||
((handle)->vfs_next.ops.sendfile(\
|
||||
(handle)->vfs_next.handles.sendfile,\
|
||||
(tofd), (fsp), (fromfd), (header), (offset), (count)))
|
||||
...
|
||||
</programlisting>
|
||||
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Upgrading to the New VFS Interface</title>
|
||||
|
||||
<sect2>
|
||||
<title>Upgrading from 2.2.* and 3.0aplha modules</title>
|
||||
|
||||
<orderedlist>
|
||||
<listitem><para>
|
||||
Add "vfs_handle_struct *handle, " as first parameter to all vfs operation functions.
|
||||
e.g. example_connect(connection_struct *conn, const char *service, const char *user);
|
||||
-> example_connect(vfs_handle_struct *handle, connection_struct *conn, const char *service, const char *user);
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Replace "default_vfs_ops." with "smb_vfs_next_".
|
||||
e.g. default_vfs_ops.connect(conn, service, user);
|
||||
-> smb_vfs_next_connect(conn, service, user);
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Uppercase all "smb_vfs_next_*" functions.
|
||||
e.g. smb_vfs_next_connect(conn, service, user);
|
||||
-> SMB_VFS_NEXT_CONNECT(conn, service, user);
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Add "handle, " as first parameter to all SMB_VFS_NEXT_*() calls.
|
||||
e.g. SMB_VFS_NEXT_CONNECT(conn, service, user);
|
||||
-> SMB_VFS_NEXT_CONNECT(handle, conn, service, user);
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
(Only for 2.2.* modules)
|
||||
Convert the old struct vfs_ops example_ops to
|
||||
a vfs_op_tuple example_op_tuples[] array.
|
||||
e.g.
|
||||
<programlisting>
|
||||
struct vfs_ops example_ops = {
|
||||
/* Disk operations */
|
||||
example_connect, /* connect */
|
||||
example_disconnect, /* disconnect */
|
||||
NULL, /* disk free *
|
||||
/* Directory operations */
|
||||
NULL, /* opendir */
|
||||
NULL, /* readdir */
|
||||
NULL, /* mkdir */
|
||||
NULL, /* rmdir */
|
||||
NULL, /* closedir */
|
||||
/* File operations */
|
||||
NULL, /* open */
|
||||
NULL, /* close */
|
||||
NULL, /* read */
|
||||
NULL, /* write */
|
||||
NULL, /* lseek */
|
||||
NULL, /* sendfile */
|
||||
NULL, /* rename */
|
||||
NULL, /* fsync */
|
||||
example_stat, /* stat */
|
||||
example_fstat, /* fstat */
|
||||
example_lstat, /* lstat */
|
||||
NULL, /* unlink */
|
||||
NULL, /* chmod */
|
||||
NULL, /* fchmod */
|
||||
NULL, /* chown */
|
||||
NULL, /* fchown */
|
||||
NULL, /* chdir */
|
||||
NULL, /* getwd */
|
||||
NULL, /* utime */
|
||||
NULL, /* ftruncate */
|
||||
NULL, /* lock */
|
||||
NULL, /* symlink */
|
||||
NULL, /* readlink */
|
||||
NULL, /* link */
|
||||
NULL, /* mknod */
|
||||
NULL, /* realpath */
|
||||
NULL, /* fget_nt_acl */
|
||||
NULL, /* get_nt_acl */
|
||||
NULL, /* fset_nt_acl */
|
||||
NULL, /* set_nt_acl */
|
||||
|
||||
NULL, /* chmod_acl */
|
||||
NULL, /* fchmod_acl */
|
||||
|
||||
NULL, /* sys_acl_get_entry */
|
||||
NULL, /* sys_acl_get_tag_type */
|
||||
NULL, /* sys_acl_get_permset */
|
||||
NULL, /* sys_acl_get_qualifier */
|
||||
NULL, /* sys_acl_get_file */
|
||||
NULL, /* sys_acl_get_fd */
|
||||
NULL, /* sys_acl_clear_perms */
|
||||
NULL, /* sys_acl_add_perm */
|
||||
NULL, /* sys_acl_to_text */
|
||||
NULL, /* sys_acl_init */
|
||||
NULL, /* sys_acl_create_entry */
|
||||
NULL, /* sys_acl_set_tag_type */
|
||||
NULL, /* sys_acl_set_qualifier */
|
||||
NULL, /* sys_acl_set_permset */
|
||||
NULL, /* sys_acl_valid */
|
||||
NULL, /* sys_acl_set_file */
|
||||
NULL, /* sys_acl_set_fd */
|
||||
NULL, /* sys_acl_delete_def_file */
|
||||
NULL, /* sys_acl_get_perm */
|
||||
NULL, /* sys_acl_free_text */
|
||||
NULL, /* sys_acl_free_acl */
|
||||
NULL /* sys_acl_free_qualifier */
|
||||
};
|
||||
</programlisting>
|
||||
->
|
||||
<programlisting>
|
||||
static vfs_op_tuple example_op_tuples[] = {
|
||||
{SMB_VFS_OP(example_connect), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT},
|
||||
{SMB_VFS_OP(example_disconnect), SMB_VFS_OP_DISCONNECT, SMB_VFS_LAYER_TRANSPARENT},
|
||||
|
||||
{SMB_VFS_OP(example_fstat), SMB_VFS_OP_FSTAT, SMB_VFS_LAYER_TRANSPARENT},
|
||||
{SMB_VFS_OP(example_stat), SMB_VFS_OP_STAT, SMB_VFS_LAYER_TRANSPARENT},
|
||||
{SMB_VFS_OP(example_lstat), SMB_VFS_OP_LSTAT, SMB_VFS_LAYER_TRANSPARENT},
|
||||
|
||||
{SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP}
|
||||
};
|
||||
</programlisting>
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Move the example_op_tuples[] array to the end of the file.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Add the init_module() function at the end of the file.
|
||||
e.g.
|
||||
<programlisting>
|
||||
NTSTATUS init_module(void)
|
||||
{
|
||||
return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,"example",example_op_tuples);
|
||||
}
|
||||
</programlisting>
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Check if your vfs_init() function does more then just prepare the vfs_ops structs or
|
||||
remember the struct smb_vfs_handle_struct.
|
||||
<simplelist>
|
||||
<member>If NOT you can remove the vfs_init() function.</member>
|
||||
<member>If YES decide if you want to move the code to the example_connect() operation or to the init_module(). And then remove vfs_init().
|
||||
e.g. a debug class registration should go into init_module() and the allocation of private data should go to example_connect().</member>
|
||||
</simplelist>
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
(Only for 3.0alpha* modules)
|
||||
Check if your vfs_done() function contains needed code.
|
||||
<simplelist>
|
||||
<member>If NOT you can remove the vfs_done() function.</member>
|
||||
<member>If YES decide if you can move the code to the example_disconnect() operation. Otherwise register a SMB_EXIT_EVENT with smb_register_exit_event(); (Described in the <link linkend="modules">modules section</link>) And then remove vfs_done(). e.g. the freeing of private data should go to example_disconnect().
|
||||
</member>
|
||||
</simplelist>
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Check if you have any global variables left.
|
||||
Decide if it wouldn't be better to have this data on a connection basis.
|
||||
<simplelist>
|
||||
<member>If NOT leave them as they are. (e.g. this could be the variable for the private debug class.)</member>
|
||||
<member>If YES pack all this data into a struct. You can use handle->data to point to such a struct on a per connection basis.</member>
|
||||
</simplelist>
|
||||
|
||||
e.g. if you have such a struct:
|
||||
<programlisting>
|
||||
struct example_privates {
|
||||
char *some_string;
|
||||
int db_connection;
|
||||
};
|
||||
</programlisting>
|
||||
first way of doing it:
|
||||
<programlisting>
|
||||
static int example_connect(vfs_handle_struct *handle,
|
||||
connection_struct *conn, const char *service,
|
||||
const char* user)
|
||||
{
|
||||
struct example_privates *data = NULL;
|
||||
|
||||
/* alloc our private data */
|
||||
data = (struct example_privates *)talloc_zero(conn->mem_ctx, sizeof(struct example_privates));
|
||||
if (!data) {
|
||||
DEBUG(0,("talloc_zero() failed\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* init out private data */
|
||||
data->some_string = talloc_strdup(conn->mem_ctx,"test");
|
||||
if (!data->some_string) {
|
||||
DEBUG(0,("talloc_strdup() failed\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
data->db_connection = open_db_conn();
|
||||
|
||||
/* and now store the private data pointer in handle->data
|
||||
* we don't need to specify a free_function here because
|
||||
* we use the connection TALLOC context.
|
||||
* (return -1 if something failed.)
|
||||
*/
|
||||
VFS_HANDLE_SET_DATA(handle, data, NULL, struct example_privates, return -1);
|
||||
|
||||
return SMB_VFS_NEXT_CONNECT(handle,conn,service,user);
|
||||
}
|
||||
|
||||
static int example_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
|
||||
{
|
||||
struct example_privates *data = NULL;
|
||||
|
||||
/* get the pointer to our private data
|
||||
* return -1 if something failed
|
||||
*/
|
||||
SMB_VFS_HANDLE_GET_DATA(handle, data, struct example_privates, return -1);
|
||||
|
||||
/* do something here...*/
|
||||
DEBUG(0,("some_string: %s\n",data->some_string));
|
||||
|
||||
return SMB_VFS_NEXT_CLOSE(handle, fsp, fd);
|
||||
}
|
||||
</programlisting>
|
||||
second way of doing it:
|
||||
<programlisting>
|
||||
static void free_example_privates(void **datap)
|
||||
{
|
||||
struct example_privates *data = (struct example_privates *)*datap;
|
||||
|
||||
SAFE_FREE(data->some_string);
|
||||
SAFE_FREE(data);
|
||||
|
||||
*datap = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static int example_connect(vfs_handle_struct *handle,
|
||||
connection_struct *conn, const char *service,
|
||||
const char* user)
|
||||
{
|
||||
struct example_privates *data = NULL;
|
||||
|
||||
/* alloc our private data */
|
||||
data = (struct example_privates *)malloc(sizeof(struct example_privates));
|
||||
if (!data) {
|
||||
DEBUG(0,("malloc() failed\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* init out private data */
|
||||
data->some_string = strdup("test");
|
||||
if (!data->some_string) {
|
||||
DEBUG(0,("strdup() failed\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
data->db_connection = open_db_conn();
|
||||
|
||||
/* and now store the private data pointer in handle->data
|
||||
* we need to specify a free_function because we used malloc() and strdup().
|
||||
* (return -1 if something failed.)
|
||||
*/
|
||||
SMB_VFS_HANDLE_SET_DATA(handle, data, free_example_privates, struct example_privates, return -1);
|
||||
|
||||
return SMB_VFS_NEXT_CONNECT(handle,conn,service,user);
|
||||
}
|
||||
|
||||
static int example_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
|
||||
{
|
||||
struct example_privates *data = NULL;
|
||||
|
||||
/* get the pointer to our private data
|
||||
* return -1 if something failed
|
||||
*/
|
||||
SMB_VFS_HANDLE_GET_DATA(handle, data, struct example_privates, return -1);
|
||||
|
||||
/* do something here...*/
|
||||
DEBUG(0,("some_string: %s\n",data->some_string));
|
||||
|
||||
return SMB_VFS_NEXT_CLOSE(handle, fsp, fd);
|
||||
}
|
||||
</programlisting>
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
To make it easy to build 3rd party modules it would be usefull to provide
|
||||
configure.in, (configure), install.sh and Makefile.in with the module.
|
||||
(Take a look at the example in <filename>examples/VFS</filename>.)
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The configure script accepts <option>--with-samba-source</option> to specify
|
||||
the path to the samba source tree.
|
||||
It also accept <option>--enable-developer</option> which lets the compiler
|
||||
give you more warnings.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The idea is that you can extend this
|
||||
<filename>configure.in</filename> and <filename>Makefile.in</filename> scripts
|
||||
for your module.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Compiling & Testing...
|
||||
<simplelist>
|
||||
<member><userinput>./configure <option>--enable-developer</option></userinput> ...</member>
|
||||
<member><userinput>make</userinput></member>
|
||||
<member>Try to fix all compiler warnings</member>
|
||||
<member><userinput>make</userinput></member>
|
||||
<member>Testing, Testing, Testing ...</member>
|
||||
</simplelist>
|
||||
</para></listitem>
|
||||
</orderedlist>
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Some Notes</title>
|
||||
|
||||
<sect2>
|
||||
<title>Implement TRANSPARENT functions</title>
|
||||
|
||||
<para>
|
||||
Avoid writing functions like this:
|
||||
|
||||
<programlisting>
|
||||
static int example_close(vfs_handle_struct *handle, files_struct *fsp, int fd)
|
||||
{
|
||||
return SMB_VFS_NEXT_CLOSE(handle, fsp, fd);
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
Overload only the functions you really need to!
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Implement OPAQUE functions</title>
|
||||
|
||||
<para>
|
||||
If you want to just implement a better version of a
|
||||
default samba opaque function
|
||||
(e.g. like a disk_free() function for a special filesystem)
|
||||
it's ok to just overload that specific function.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If you want to implement a database filesystem or
|
||||
something different from a posix filesystem.
|
||||
Make sure that you overload every vfs operation!!!
|
||||
</para>
|
||||
<para>
|
||||
Functions your FS does not support should be overloaded by something like this:
|
||||
e.g. for a readonly filesystem.
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
static int example_rename(vfs_handle_struct *handle, connection_struct *conn,
|
||||
char *oldname, char *newname)
|
||||
{
|
||||
DEBUG(10,("function rename() not allowed on vfs 'example'\n"));
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
19
docs/devel/windows-debug.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<chapter id="windows-debug">
|
||||
<chapterinfo>
|
||||
&author.jelmer;
|
||||
&author.tridge;
|
||||
</chapterinfo>
|
||||
|
||||
<title>Finding useful information on windows</title>
|
||||
|
||||
<sect1><title>Netlogon debugging output</title>
|
||||
|
||||
<procedure>
|
||||
<step><para>stop netlogon service on PDC</para></step>
|
||||
<step><para>rename original netlogon.dll to netlogon.dll.original</para></step>
|
||||
<step><para>copy checked version of netlogon.dll to system32 directory</para></step>
|
||||
<step><para>set HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters\DBFlag to 0x20000004</para></step>
|
||||
<step><para>start netlogon service on PDC</para></step>
|
||||
</procedure>
|
||||
</sect1>
|
||||
</chapter>
|
79
docs/devel/wins.xml
Normal file
@ -0,0 +1,79 @@
|
||||
<chapter id="wins">
|
||||
<chapterinfo>
|
||||
<author>
|
||||
<firstname>Gerald</firstname><surname>Carter</surname>
|
||||
</author>
|
||||
<pubdate>October 2002</pubdate>
|
||||
</chapterinfo>
|
||||
|
||||
|
||||
<title>Samba WINS Internals</title>
|
||||
|
||||
|
||||
<sect1>
|
||||
<title>WINS Failover</title>
|
||||
|
||||
|
||||
<para>
|
||||
The current Samba codebase possesses the capability to use groups of WINS
|
||||
servers that share a common namespace for NetBIOS name registration and
|
||||
resolution. The formal parameter syntax is
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
WINS_SERVER_PARAM = SERVER [ SEPARATOR SERVER_LIST ]
|
||||
WINS_SERVER_PARAM = "wins server"
|
||||
SERVER = ADDR[:TAG]
|
||||
ADDR = ip_addr | fqdn
|
||||
TAG = string
|
||||
SEPARATOR = comma | \s+
|
||||
SERVER_LIST = SERVER [ SEPARATOR SERVER_LIST ]
|
||||
</programlisting></para>
|
||||
|
||||
<para>
|
||||
A simple example of a valid wins server setting is
|
||||
</para>
|
||||
|
||||
<para><programlisting>
|
||||
[global]
|
||||
wins server = 192.168.1.2 192.168.1.3
|
||||
</programlisting></para>
|
||||
|
||||
<para>
|
||||
In the event that no TAG is defined in for a SERVER in the list, smbd assigns a default
|
||||
TAG of "*". A TAG is used to group servers of a shared NetBIOS namespace together. Upon
|
||||
startup, nmbd will attempt to register the netbios name value with one server in each
|
||||
tagged group.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
An example using tags to group WINS servers together is show here. Note that the use of
|
||||
interface names in the tags is only by convention and is not a technical requirement.
|
||||
</para>
|
||||
|
||||
|
||||
<para><programlisting>
|
||||
[global]
|
||||
wins server = 192.168.1.2:eth0 192.168.1.3:eth0 192.168.2.2:eth1
|
||||
</programlisting></para>
|
||||
|
||||
<para>
|
||||
Using this configuration, nmbd would attempt to register the server's NetBIOS name
|
||||
with one WINS server in each group. Because the "eth0" group has two servers, the
|
||||
second server would only be used when a registration (or resolution) request to
|
||||
the first server in that group timed out.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
NetBIOS name resolution follows a similar pattern as name registration. When resolving
|
||||
a NetBIOS name via WINS, smbd and other Samba programs will attempt to query a single WINS
|
||||
server in a tagged group until either a positive response is obtained at least once or
|
||||
until a server from every tagged group has responded negatively to the name query request.
|
||||
If a timeout occurs when querying a specific WINS server, that server is marked as down to
|
||||
prevent further timeouts and the next server in the WINS group is contacted. Once marked as
|
||||
dead, Samba will not attempt to contact that server for name registration/resolution queries
|
||||
for a period of 10 minutes.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
</chapter>
|
68
docs/docbook.txt
Normal file
@ -0,0 +1,68 @@
|
||||
!==
|
||||
!== docbook.txt for Samba 3.0
|
||||
!==
|
||||
!== Author: David Bannon, D.Bannon@latrobe.edu.au November, 2000
|
||||
!== Updates: Gerald (Jerry) Carter, jerry@samba.org, Feb. 2001
|
||||
!== Updates: Jelmer Vernooij, jelmer@samba.org, Aug, 2002
|
||||
!== Updates: Jelmer Vernooij, jelmer@samba.org, Jun, 2003
|
||||
|
||||
What are DocBook documents doing in the Samba Distribution ?
|
||||
-----------------------------------------------------------
|
||||
|
||||
We have converted all samba docs to XML/DocBook V4.2
|
||||
in order to make them easier to maintain and produce a nicer looking
|
||||
product.
|
||||
|
||||
This short note (strange isn't it how it always starts out as a short note
|
||||
and becomes a long one ?) will explain very briefly how and why we have
|
||||
done this.
|
||||
|
||||
|
||||
The format
|
||||
----------
|
||||
If you are new to xml, regard an xml file as 'source code'. You don't
|
||||
read it directly, but use it to create other formats (like the txt and html
|
||||
included in ../txtdocs and ../htmldocs).
|
||||
|
||||
Docbook is a particular XML style, particularly suited to producing
|
||||
technical manuals.
|
||||
|
||||
For more information on DocBook tags and format, see "DocBook: The
|
||||
Definitive Guide" by Walsh and Muellner, (c) O'Reilly Publishing.
|
||||
This book covers DocBook V4.2 and is available on-line
|
||||
at http://www.docbook.org/
|
||||
|
||||
The Output
|
||||
----------
|
||||
The current Samba CVS tree contains the XML/DocBook source files.
|
||||
|
||||
A regularly generated version can be found at http://samba.org/samba/docs/.
|
||||
|
||||
The Tools
|
||||
---------
|
||||
|
||||
To generate the docs, you need to have the following packages installed:
|
||||
|
||||
* autoconf
|
||||
* docbook-utils
|
||||
* xsltproc
|
||||
* pngtopnm and pnmtops (from the netpbm utilities)
|
||||
* cvs2cl (for generating the changelog file for the HOWTO)
|
||||
|
||||
For generating PDF (thru LaTeX):
|
||||
* db2latex (from http://db2latex.sf.net/). Make sure to get CVS version
|
||||
dated 20030622 -- it works best. Versions previous to 20030425 are known
|
||||
to have problems, as well as current (as of 20031210) snapshots.
|
||||
* pdflatex
|
||||
|
||||
For generating PostScript (thru LaTeX):
|
||||
* latex
|
||||
* dvips
|
||||
|
||||
For generating ASCII:
|
||||
* xmlto
|
||||
|
||||
This directory now contains a ./configure script and Makefile to
|
||||
support the automated building of man pages (including HTML versions), and
|
||||
the building of the Samba-HOWTO-Collection and the
|
||||
Samba Developers Guide (HTML,DVI,TeX,PDF,PS,Text versions).
|
1340
docs/guide/Chap01-WindowsNetworkingPrimer.xml
Normal file
1604
docs/guide/Chap02-SimpleOfficeServer.xml
Normal file
1310
docs/guide/Chap03-TheSmallOffice.xml
Normal file
2757
docs/guide/Chap04-SecureOfficeServer.xml
Normal file
2004
docs/guide/Chap05-500UserNetwork.xml
Normal file
3778
docs/guide/Chap06-MakingHappyUsers.xml
Normal file
1815
docs/guide/Chap07-2000UserNetwork.xml
Normal file
1256
docs/guide/Chap08-MigrateNT4Samba3.xml
Normal file
2505
docs/guide/Chap09-AddingUNIXClients.xml
Normal file
2086
docs/guide/Chap10-KerberosFastStart.xml
Normal file
1100
docs/guide/Chap10b-DomainAppsSupport.xml
Normal file
766
docs/guide/Chap11-HighAvailability.xml
Normal file
@ -0,0 +1,766 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
|
||||
|
||||
<!-- Stuff for xincludes -->
|
||||
<!ENTITY % xinclude SYSTEM "../entities/xinclude.dtd">
|
||||
%xinclude;
|
||||
|
||||
<!-- entities files to use -->
|
||||
<!ENTITY % global_entities SYSTEM '../entities/global.entities'>
|
||||
%global_entities;
|
||||
|
||||
]>
|
||||
|
||||
<chapter id="HA">
|
||||
<title>Performance, Reliability, and Availability</title>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>performance</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>reliability</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>availability</primary>
|
||||
</indexterm>
|
||||
Well, you have reached the chapter before the Appendix. It is customary to attempt
|
||||
to wrap up the theme and contents of a book in what is generally regarded as the
|
||||
chapter that should draw conclusions. This book is a suspense thriller and since
|
||||
the plot of the stories told mostly lead you to bigger, better Samba-3 networking
|
||||
solutions, it is perhaps appropriate to close this book with a few pertinent comments
|
||||
regarding some of the things everyone can do to deliver a reliable Samba-3 network.
|
||||
</para>
|
||||
|
||||
<blockquote><attribution>Anonymous</attribution><para>
|
||||
In a world so full of noise, how can the sparrow be heard?
|
||||
</para></blockquote>
|
||||
|
||||
<sect1>
|
||||
<title>Introduction</title>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>clustering</primary>
|
||||
</indexterm>
|
||||
The sparrow is a small bird whose sounds are drowned out by the noise of the busy
|
||||
world it lives in. Likewise, the simple steps that can be taken to improve the
|
||||
reliability and availability of a Samba network are often drowned out by the volume
|
||||
of discussions about grandiose Samba clustering designs. This is not intended to
|
||||
suggest that clustering is not important, because clearly it is. This chapter does not devote
|
||||
itself to discussion of clustering because each clustering methodology uses its own
|
||||
custom tools and methods. Only passing comments are offered concerning these methods.
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>cluster</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>samba cluster</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>scalability</primary>
|
||||
</indexterm>
|
||||
<ulink url="http://www.google.com/search?hl=en&lr=&ie=ISO-8859-1&q=samba+cluster&btnG=Google+Search">A search</ulink>
|
||||
for <quote>samba cluster</quote> produced 71,600 hits. And a search for <quote>highly available samba</quote>
|
||||
and <quote>highly available windows</quote> produced an amazing number of references.
|
||||
It is clear from the resources on the Internet that Windows file and print services
|
||||
availability, reliability, and scalability are of vital interest to corporate network users.
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>performance</primary>
|
||||
</indexterm>
|
||||
So without further background, you can review a checklist of simple steps that
|
||||
can be taken to ensure acceptable network performance while keeping costs of ownership
|
||||
well under control.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Dissection and Discussion</title>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>simple</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>complexities</primary>
|
||||
</indexterm>
|
||||
If it is your purpose to get the best mileage out of your Samba servers, there is one rule that
|
||||
must be obeyed. If you want the best, keep your implementation as simple as possible. You may
|
||||
well be forced to introduce some complexities, but you should do so only as a last resort.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Simple solutions are likely to be easier to get right than are complex ones. They certainly
|
||||
make life easier for your successor. Simple implementations can be more readily audited than can
|
||||
complex ones.
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>broken behavior</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>poor performance</primary>
|
||||
</indexterm>
|
||||
Problems reported by users fall into three categories: configurations that do not work, those
|
||||
that have broken behavior, and poor performance. The term <emphasis>broken behavior</emphasis>
|
||||
means that the function of a partciluar Samba component appears to work sometimes, but not at
|
||||
others. The resulting intermittent operation is clearly unacceptable. An example of
|
||||
<emphasis>broken behavior</emphasis> known to many Windows networking users occurs when the
|
||||
list of Windows machines in MS Explorer changes, sometimes listing machines that are running
|
||||
and at other times not listing them even though the machines are in use on the network.
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>smbfs</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>smbmnt</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>smbmount</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>smbumnt</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>smbumount</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>front-end</primary>
|
||||
</indexterm>
|
||||
A significant number of reports concern problems with the <command>smbfs</command> file system
|
||||
driver that is part of the Linux kernel, not part of Samba. Users continue to interpret that
|
||||
<command>smbfs</command> is part of Samba, simply because Samba includes the front-end tools
|
||||
that are used to manage <command>smbfs</command>-based file service connections. So, just
|
||||
for the record, the tools <command>smbmnt, smbmount, smbumount,</command> and <command>smbumnt</command> are front-end
|
||||
facilities to core drivers that are supplied as part of the Linux kernel. These tools share a
|
||||
common infrastructure with some Samba components, but they are not maintained as part of
|
||||
Samba and are really foreign to it.
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>cifsfs</primary>
|
||||
</indexterm>
|
||||
The new project, <command>cifsfs</command>, is destined to replace <command>smbfs</command>.
|
||||
It, too, is not part of Samba, even though one of the Samba Team members is a prime mover in
|
||||
this project.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The following table lists typical causes of:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>Not Working (NW)</para></listitem>
|
||||
<listitem><para>Broken Behavior (BB)</para></listitem>
|
||||
<listitem><para>Poor Performance (PP)</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
|
||||
<table id="ProbList">
|
||||
<title>Effect of Common Problems</title>
|
||||
<tgroup cols="4">
|
||||
<colspec align="left"/>
|
||||
<colspec align="center"/>
|
||||
<colspec align="center"/>
|
||||
<colspec align="center"/>
|
||||
<thead>
|
||||
<row>
|
||||
<entry><para>Problem</para></entry>
|
||||
<entry><para>NW</para></entry>
|
||||
<entry><para>BB</para></entry>
|
||||
<entry><para>PP</para></entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><para>File Locking</para></entry>
|
||||
<entry><para>-</para></entry>
|
||||
<entry><para>X</para></entry>
|
||||
<entry><para>-</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><para>Hardware Problems</para></entry>
|
||||
<entry><para>X</para></entry>
|
||||
<entry><para>X</para></entry>
|
||||
<entry><para>X</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><para>Incorrect Authentication</para></entry>
|
||||
<entry><para>X</para></entry>
|
||||
<entry><para>X</para></entry>
|
||||
<entry><para>-</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><para>Incorrect Configuration</para></entry>
|
||||
<entry><para>X</para></entry>
|
||||
<entry><para>X</para></entry>
|
||||
<entry><para>X</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><para>LDAP Problems</para></entry>
|
||||
<entry><para>X</para></entry>
|
||||
<entry><para>X</para></entry>
|
||||
<entry><para>-</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><para>Name Resolution</para></entry>
|
||||
<entry><para>X</para></entry>
|
||||
<entry><para>X</para></entry>
|
||||
<entry><para>X</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><para>Printing Problems</para></entry>
|
||||
<entry><para>X</para></entry>
|
||||
<entry><para>X</para></entry>
|
||||
<entry><para>-</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><para>Slow File Transfer</para></entry>
|
||||
<entry><para>-</para></entry>
|
||||
<entry><para>-</para></entry>
|
||||
<entry><para>X</para></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><para>Winbind Problems</para></entry>
|
||||
<entry><para>X</para></entry>
|
||||
<entry><para>X</para></entry>
|
||||
<entry><para>-</para></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>network hygiene</primary>
|
||||
</indexterm>
|
||||
It is obvious to all that the first requirement (as a matter of network hygiene) is to eliminate
|
||||
problems that affect basic network operation. This book has provided sufficient working examples
|
||||
to help you to avoid all these problems.
|
||||
</para>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>Guidelines for Reliable Samba Operation</title>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>resilient</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>extreme demand</primary>
|
||||
</indexterm>
|
||||
Your objective is to provide a network that works correctly, can grow at all times, is resilient
|
||||
at times of extreme demand, and can scale to meet future needs. The following subject areas provide
|
||||
pointers that can help you today.
|
||||
</para>
|
||||
|
||||
<sect2>
|
||||
<title>Name Resolution</title>
|
||||
|
||||
<para>
|
||||
There are three basic current problem areas: bad hostnames, routed networks, and network collisions.
|
||||
These are covered in the discussion below.
|
||||
</para>
|
||||
|
||||
<sect3>
|
||||
<title>Bad Hostnames</title>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>DHCP</primary>
|
||||
<secondary>client</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>netbios name</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>localhost</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>/etc/hosts</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>NetBIOS</primary>
|
||||
</indexterm>
|
||||
When configured as a DHCP client, a number of Linux distributions set the system hostname
|
||||
to <constant>localhost</constant>. If the parameter <parameter>netbios name</parameter> is not
|
||||
specified to something other than <constant>localhost</constant>, the Samba server appears
|
||||
in the Windows Explorer as <constant>LOCALHOST</constant>. Moreover, the entry in the <filename>/etc/hosts</filename>
|
||||
on the Linux server points to IP address <constant>127.0.0.1</constant>. This means that
|
||||
when the Windows client obtains the IP address of the Samba server called <constant>LOCALHOST</constant>,
|
||||
it obtains the IP address <constant>127.0.0.1</constant> and then proceeds to attempt to
|
||||
set up a NetBIOS over TCP/IP connection to it. This cannot work, because that IP address is
|
||||
the local Windows machine itself. Hostnames must be valid for Windows networking to function
|
||||
correctly.
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>digits</primary>
|
||||
</indexterm>
|
||||
A few sites have tried to name Windows clients and Samba servers with a name that begins
|
||||
with the digits 1-9. This does not work either because it may result in the client or
|
||||
server attempting to use that name as an IP address.
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>DNS</primary>
|
||||
<secondary>name lookup</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>resolve</primary>
|
||||
</indexterm>
|
||||
A Samba server called <constant>FRED</constant>, in a NetBIOS Domain called <constant>COLLISION</constant>
|
||||
in a network environment that is part of the fully qualified Internet domain name space known
|
||||
as <constant>parrots.com</constant>, results in DNS name lookups for: <constant>fred.parrots.com</constant>
|
||||
and <constant>collision.parrots.com</constant>. It is, therefore, a mistake to name the Domain
|
||||
(workgroup) <constant>collision.parrots.com</constant> since this results in DNS lookup
|
||||
attempts to resolve: <constant>fred.parrots.com.parrots.com</constant>, which most likely
|
||||
fails given that you probably do not have this in your DNS name space.
|
||||
</para>
|
||||
|
||||
<note><para><indexterm>
|
||||
<primary>Active Directory</primary>
|
||||
<secondary>realm</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>ADS</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>DNS</primary>
|
||||
</indexterm>
|
||||
An Active Directory realm called <constant>collision.parrots.com</constant> is perfectly okay,
|
||||
although it too must be capable of being resolved via DNS, something that functions correctly
|
||||
if Windows 200x ADS has been properly installed and configured.
|
||||
</para></note>
|
||||
|
||||
</sect3>
|
||||
|
||||
<sect3>
|
||||
<title>Routed Networks</title>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>NetBIOS</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>UDP</primary>
|
||||
<secondary>broadcast</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>broadcast</primary>
|
||||
</indexterm>
|
||||
NetBIOS networks (Windows networking with NetBIOS over TCP/IP enabled) makes extensive use
|
||||
of UDP-based broadcast traffic. You saw that during the exercises in Chapter 1.
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>routers</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>forwarded</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>multi-subnet</primary>
|
||||
</indexterm>
|
||||
UDP broadcast traffic is not forwarded by routers. This means that NetBIOS broadcast-based
|
||||
networking cannot function across routed networks (i.e., multi-subnet networks) unless
|
||||
special provisions are made:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para><indexterm>
|
||||
<primary>LMHOSTS</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>remote announce</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>remote browse sync</primary>
|
||||
</indexterm>
|
||||
Either install on every Windows client an LMHOSTS file (located in the directory
|
||||
<filename>C:\windows\system32\drivers\etc</filename>). It is also necessary to
|
||||
add to the Samba server &smb.conf; file the parameters: <parameter>remote announce</parameter>
|
||||
and <parameter>remote browse sync</parameter>. For more information, refer to the on-line
|
||||
manual page for the &smb.conf; file.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para><indexterm>
|
||||
<primary>WINS</primary>
|
||||
<secondary>server</secondary>
|
||||
</indexterm>
|
||||
Or configure Samba as a WINS server, and configure all network clients to use that
|
||||
WINS server in their TCP/IP configuration.
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<note><para><indexterm>
|
||||
<primary>WINS</primary>
|
||||
<secondary>name resolution</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>DNS</primary>
|
||||
</indexterm>
|
||||
The use of DNS is not an acceptable substitute for WINS. DNS does not store specific
|
||||
information regarding NetBIOS networking particulars that does get stored in the WINS
|
||||
name resolution database, and that Windows clients require and depend on.
|
||||
</para></note>
|
||||
|
||||
</sect3>
|
||||
|
||||
<sect3>
|
||||
<title>Network Collisions</title>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>network</primary>
|
||||
<secondary>collisions</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>network</primary>
|
||||
<secondary>tiemouts</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>collision rates</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>network</primary>
|
||||
<secondary>load</secondary>
|
||||
</indexterm>
|
||||
Excessive network activity causes NetBIOS network time-outs. Time-outs may result in
|
||||
blue screen of death (BSOD) experiences. High collision rates may be caused by excessive
|
||||
UDP broadcast activity, by defective networking hardware, or through excessive network
|
||||
loads (another way of saying that the network is poorly designed).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The use of WINS is highly recommended to reduce network broadcast traffic, as outlined
|
||||
in Chapter 1.
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>netbios forwarding</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>broadcast storms</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>performance</primary>
|
||||
</indexterm>
|
||||
Under no circumstances should the facility be supported by many routers, known as <constant>NetBIOS
|
||||
forwarding</constant>, unless you know exactly what you are doing. Inappropriate use of this
|
||||
facility can result in UDP broadcast storms. In one case in 1999, a university network became
|
||||
unusable due to this being enabled on all routers. The problem was discovered during performance
|
||||
testing of a Samba server. The maximum throughput on a 100-Base-T (100 MBit/sec) network was
|
||||
less than 15 KBytes/sec. After the NetBIOS forwarding was turned off, file transfer performance
|
||||
immediately returned to 11 MBytes/sec.
|
||||
</para>
|
||||
|
||||
</sect3>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Samba Configuration</title>
|
||||
|
||||
<para>
|
||||
As a general rule, the contents of the &smb.conf; file should be kept as simple as possible.
|
||||
No parameter should be specified unless you know it is essential to operation.
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>document the settings</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>documented</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>optimized</primary>
|
||||
</indexterm>
|
||||
Many UNIX administrators like to fully document the settings in the &smb.conf; file. This is a
|
||||
bad idea because it adds content to the file. The &smb.conf; file is re-read by every <command>smbd</command>
|
||||
process every time the file time stamp changes (or, on systems where this does not work, every 20 seconds or so).
|
||||
</para>
|
||||
|
||||
<para>
|
||||
As the size of the &smb.conf; file grows the risk of introduction of parsing errors increases also.
|
||||
It is recommended to keep a fully documented &smb.conf; file on hand, and then to operate Samba only
|
||||
with an optimized file.
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>testparm</primary>
|
||||
</indexterm>
|
||||
The preferred way to maintain a documented file is to call it something like <filename>smb.conf.master</filename>.
|
||||
You can generate the optimized file by executing:
|
||||
<screen>
|
||||
&rootprompt; testparm -s smb.conf.master > smb.conf
|
||||
</screen>
|
||||
You should carefully observe all warnings issued. It is also a good practice to execute the following
|
||||
command to confirm correct interpretation of the &smb.conf; file contents:
|
||||
<screen>
|
||||
&rootprompt; testparm
|
||||
Load smb config files from /etc/samba/smb.conf
|
||||
Can't find include file /etc/samba/machine.
|
||||
Processing section "[homes]"
|
||||
Processing section "[print$]"
|
||||
Processing section "[netlogon]"
|
||||
Processing section "[Profiles]"
|
||||
Processing section "[printers]"
|
||||
Processing section "[media]"
|
||||
Processing section "[data]"
|
||||
Processing section "[cdr]"
|
||||
Processing section "[apps]"
|
||||
Loaded services file OK.
|
||||
'winbind separator = +' might cause problems with group membership.
|
||||
Server role: ROLE_DOMAIN_PDC
|
||||
Press enter to see a dump of your service definitions
|
||||
</screen>
|
||||
<indexterm>
|
||||
<primary>fatal problem</primary>
|
||||
</indexterm>
|
||||
You now, of course, press the enter key to complete the command, or else abort it by pressing Ctrl-C.
|
||||
The important thing to note is the noted Server role, as well as warning messages. Noted configuration
|
||||
conflicts must be remedied before proceeding. For example, the following error message represents a
|
||||
common fatal problem:
|
||||
<screen>
|
||||
ERROR: both 'wins support = true' and 'wins server = <server list>'
|
||||
cannot be set in the smb.conf file. nmbd will abort with this setting.
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>performance degradation</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>socket options</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>socket address</primary>
|
||||
</indexterm>
|
||||
There are two parameters that can cause severe network performance degradation, <parameter>socket options</parameter>
|
||||
and <parameter>socket address</parameter>. The <parameter>socket options</parameter> parameter was often necessary
|
||||
when Samba was used with the Linux 2.2.x kernels. Later kernels are largely self-tuning and seldom benefit from
|
||||
this parameter being set. Do not use either parameter unless it has been proven necessary to use them.
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>strict sync</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>sync always</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>severely degrade</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>network</primary>
|
||||
<secondary>performance</secondary>
|
||||
</indexterm>
|
||||
Another &smb.conf; parameter that may cause severe network performance degradation is the
|
||||
<parameter>strict sync</parameter> parameter. Do not use this at all. There is no good reason
|
||||
to use this with any modern Windows client. The <parameter>strict sync</parameter> is often
|
||||
used together with the <parameter>sync always</parameter> parameter. This, too, can severely
|
||||
degrade network performance, so do not set it or if you must, do so with caution.
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>opportunistic locking</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>file caching</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>caching</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>oplocks</primary>
|
||||
</indexterm>
|
||||
Finally, many network administrators deliberately disable opportunistic locking support. While this
|
||||
does not degrade Samba performance, it significantly degrades Windows client performance because
|
||||
this disables local file caching on Windows clients and forces every file read and written to
|
||||
invoke a network read or write call. If for any reason you must disable oplocks (opportunistic locking)
|
||||
support, do so on the share on which it is required only. That way, all other shares can provide
|
||||
oplock support for operations that are tolerant of it. See <link linkend="ch12dblck"/> for more
|
||||
information.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Use and Location of BDCs</title>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>BDC</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>PDC</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>routed network</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>wide-area network</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>network segment</primary>
|
||||
</indexterm>
|
||||
On a network segment where there is a PDC and a BDC, the BDC carries the bulk of the network logon
|
||||
processing. If the BDC is a heavily loaded server, the PDC carries a greater proportion of
|
||||
authentication and logon processing. When a sole BDC on a routed network segment gets heavily
|
||||
loaded, it is possible that network logon requests and authentication requests may be directed
|
||||
to a BDC on a distant network segment. This significantly hinders wide-area network operations
|
||||
and is undesirable.
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>Domain Member</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>Domain Controller</primary>
|
||||
</indexterm>
|
||||
As a general guide, instead of adding Domain Member servers to a network, you would be better advised
|
||||
to add BDCs until there are fewer than 30 Windows clients per BDC. Beyond that ratio, you should add
|
||||
Domain Member servers. This practice ensures that there is always sufficient Domain Controllers
|
||||
to handle logon requests and authentication traffic.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Use One Consistent Version of MS Windows Client</title>
|
||||
|
||||
<para>
|
||||
Every network client has its own peculiarities. From a management perspective, it is easier to deal
|
||||
with one version of MS Windows that is maintained to a consistent update level, than it is to deal
|
||||
with a mixture of clients.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
On a number of occasions, particular Microsoft service pack updates of a Windows server or client
|
||||
have necessitated special handling from the Samba server end. If you want to remain sane, keep you
|
||||
client workstation configurations consistent.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>For Scalability, Use SAN Based Storage on Samba Servers</title>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>SAN</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>synchronization</primary>
|
||||
</indexterm>
|
||||
Many SAN-based storage systems permit more than one server to share a common data store.
|
||||
Use of a shared SAN data store means that you do not need to use time- and resource-hungry data
|
||||
synchronization techniques.
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>load distribution</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>clustering</primary>
|
||||
</indexterm>
|
||||
The use of a collection of relatively low-cost front-end Samba servers that are coupled to
|
||||
a shared backend SAN data store permits load distribution while containing costs below that
|
||||
of installing and managing a complex clustering facility.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Distribute Network Load with MSDFS</title>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>MSDFS</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>distributed</primary>
|
||||
</indexterm>
|
||||
Microsoft DFS (distributed file system) technology has been implemented in Samba. MSDFS permits
|
||||
data to be accessed from a single share and yet to actually be distributed across multiple actual
|
||||
servers. Refer to <emphasis>TOSHARG</emphasis>, Chapter 16, for information regarding implementation of an MSDFS installation.
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>front-end</primary>
|
||||
<secondary>server</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>MSDFS</primary>
|
||||
</indexterm>
|
||||
The combination of multiple back end servers together with a front-end server and use of MSDFS
|
||||
can achieve almost the same as you would obtain with a clustered Samba server.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Replicate Data to Conserve Peak-Demand Wide-Area Bandwidth</title>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>replicate</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>rsync</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>wide-area network</primary>
|
||||
</indexterm>
|
||||
Consider using <command>rsync</command> to replicate data across the wide-area network during times
|
||||
of low utilization. Users can then access the replicated data store rather than needing to do so
|
||||
across the wide-area network. This works best for read-only data, but with careful planning can be
|
||||
implemented so that modified files get replicated back to the point of origin. Be careful with your
|
||||
implementation if you choose to permit modification and return replication of the modified file;
|
||||
otherwise, you may inadvertently overwrite important data.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Hardware Problems</title>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>hardware prices</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>hardware problems</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>NICs</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>defective</primary>
|
||||
<secondary>hubs</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>defective</primary>
|
||||
<secondary>switches</secondary>
|
||||
</indexterm><indexterm>
|
||||
<primary>defective</primary>
|
||||
<secondary>cables</secondary>
|
||||
</indexterm>
|
||||
Networking hardware prices have fallen sharply over the past five years. A surprising number
|
||||
of Samba networking problems over this time have been traced to defective network interface
|
||||
cards (NICs) or defective hubs, switches, and cables.
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>corrective action</primary>
|
||||
</indexterm>
|
||||
Not surprising is the fact that network administrators do not like to be shown to have made
|
||||
a bad decision. Money saved in buying low-cost hardware may result in high costs incurred
|
||||
in corrective action.
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>intermittent</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>data corruption</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>slow network</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>low performance</primary>
|
||||
</indexterm><indexterm>
|
||||
<primary>data integrity</primary>
|
||||
</indexterm>
|
||||
Defective NICs, hubs, and switches may appear as intermittent network access problems, intermittent
|
||||
or persistent data corruption, slow network throughput, low performance, or even as blue-screen-of-death (BSOD)
|
||||
problems with MS Windows clients. In one case, a company updated several workstations with newer, faster
|
||||
Windows client machines that triggered problems during logon as well as data integrity problems on
|
||||
an older PC that was unaffected so long as the new machines were kept shut down.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Defective hardware problems may take patience and persistence before the real cause can be discovered.
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>RAID controllers</primary>
|
||||
</indexterm>
|
||||
Networking hardware defects can significantly impact perceived Samba performance, but defective
|
||||
RAID controllers as well as SCSI and IDE hard disk controllers have also been known to impair Samba server
|
||||
operations. One business came to this realization only after replacing a Samba installation with MS
|
||||
Windows Server 2000 running on the same hardware. The root of the problem completely eluded the network
|
||||
administrator until the entire server was replaced. While you may well think that this would never
|
||||
happen to you, experience shows that given the right (unfortunate) circumstances, this can happen to anyone.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2>
|
||||
<title>Key Points Learned</title>
|
||||
|
||||
<para>
|
||||
This chapter has touched in broad sweeps on a number of simple steps that can be taken
|
||||
to ensure that your Samba network is resilient, scalable, and reliable, and that it
|
||||
performs well.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Always keep in mind that someone is responsible to maintain and manage your design.
|
||||
In the long term, that may not be you. Spare a thought for your successor and give him or
|
||||
her an even break.
|
||||
</para>
|
||||
|
||||
<para><indexterm>
|
||||
<primary>assumptions</primary>
|
||||
</indexterm>
|
||||
Last, but not least, you should not only keep the network design simple, but it should
|
||||
be well documented. This book may serve as your pattern for documenting every
|
||||
aspect of your design, its implementation, and particularly the objects and assumptions
|
||||
that underlie it.
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
|
1683
docs/guide/Chap12-Appendix.xml
Normal file
60
docs/guide/acknowledgements.xml
Normal file
@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
|
||||
|
||||
<!-- Stuff for xincludes -->
|
||||
<!ENTITY % xinclude SYSTEM "../entities/xinclude.dtd">
|
||||
%xinclude;
|
||||
|
||||
<!-- entities files to use -->
|
||||
<!ENTITY % global_entities SYSTEM '../entities/global.entities'>
|
||||
%global_entities;
|
||||
|
||||
]>
|
||||
|
||||
<preface lang="en-US">
|
||||
<title>Acknowledgments</title>
|
||||
|
||||
<para>
|
||||
<emphasis>Samba-3 by Example</emphasis> would not have been written except
|
||||
as a result of feedback provided by reviewers of the book <emphasis>The
|
||||
Official Samba-3 HOWTO and Reference Guide.</emphasis> I hope this book
|
||||
more than answers the challenge and fills the void that was brought to
|
||||
my attention.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
I am deeply indebted to a large group of diligent people. Space prevents
|
||||
me from listing all of them, but a few stand out as worthy of mention.
|
||||
Jelmer Vernooij made the notable contribution of building the XML production
|
||||
environment and thereby made possible the typesetting of this book.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Samba would not have come into existence if Andrew Tridgell had not taken
|
||||
the first steps. He continues to lead the project. Under the shadow of his
|
||||
mantle are some great guys who never give up and are always ready to help.
|
||||
Thank you to: Jeremy Allison, Jerry Carter, Andrew Bartlett, Jelmer Vernooij,
|
||||
Alexander Bokovoy, Volker Lendecke, and other team members who answered my
|
||||
continuous stream of questions &smbmdash; all of which resulted in improved content
|
||||
in this book.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
My heartfelt thanks go out also to a small set of reviewers (alphabetically
|
||||
listed) who gave substantial feedback and significant suggestions for improvement:
|
||||
Roland Gruber, Luke Howard, Jon Johnston, Alan Munter, Tarjei Huse, Mike MacIsaac,
|
||||
Scott Mann, Ed Riddle, Santos Soler, Mark Taylor, and Jérôme Tournier.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
My appreciation is extended to a team of over 30 additional reviewers who
|
||||
helped me to find my way around dark corners.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Particular mention is due to Lyndell, Amos and Melissa who gave me the
|
||||
latitude necessary to spend nearly a entire year writing Samba documentation.
|
||||
</para>
|
||||
|
||||
</preface>
|
64
docs/guide/conventions.xml
Normal file
@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
|
||||
|
||||
<!-- Stuff for xincludes -->
|
||||
<!ENTITY % xinclude SYSTEM "../entities/xinclude.dtd">
|
||||
%xinclude;
|
||||
|
||||
<!-- entities files to use -->
|
||||
<!ENTITY % global_entities SYSTEM '../entities/global.entities'>
|
||||
%global_entities;
|
||||
|
||||
]>
|
||||
|
||||
<sect1>
|
||||
<title>Conventions Used</title>
|
||||
|
||||
<para>
|
||||
The following notation conventions are used throughout this book:
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
TOSHARG is used as an abbreviation for the book, <quote>The Official Samba-3
|
||||
HOWTO and Reference Guide,</quote> Editors: John H. Terpstra and Jelmer R. Vernooij,
|
||||
Publisher: Prentice Hall, ISBN: 0131453556.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Directories and filenames appear in mono-font. For example,
|
||||
<filename>/etc/pam.conf</filename>.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Executable names are bolded. For example, <command>smbd</command>.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Menu items and buttons appear in bold. For example, click <guibutton>Next</guibutton>.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Selecting a menu item is indicated as:
|
||||
<menuchoice>
|
||||
<guimenu>Start</guimenu>
|
||||
<guimenuitem>Control Panel</guimenuitem>
|
||||
<guimenuitem>Administrative Tools</guimenuitem>
|
||||
<guimenuitem>Active Directory Users and Computers</guimenuitem>
|
||||
</menuchoice>
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
</sect1>
|
||||
|
118
docs/guide/foreword.xml
Normal file
@ -0,0 +1,118 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
|
||||
|
||||
<!-- Stuff for xincludes -->
|
||||
<!ENTITY % xinclude SYSTEM "../entities/xinclude.dtd">
|
||||
%xinclude;
|
||||
|
||||
<!-- entities files to use -->
|
||||
<!ENTITY % global_entities SYSTEM '../entities/global.entities'>
|
||||
%global_entities;
|
||||
|
||||
]>
|
||||
|
||||
<preface lang="en-US">
|
||||
<title>Foreword</title>
|
||||
|
||||
<sect1><title>By Dan Kusnetzky, IDC</title>
|
||||
<blockquote>
|
||||
<attribution>
|
||||
Dan Kusnetzky, Vice President System Software Research, International Data Corporation
|
||||
</attribution>
|
||||
|
||||
<para>
|
||||
IDC's software research group has been conducting research on the market for software,
|
||||
including operating environments, for over twenty years. In 1994, the system software
|
||||
research team started to field questions from its subscribers on Linux. We had very
|
||||
little empirical data to offer when these queries first were heard, so IDC added Linux
|
||||
to its operating environment research agenda. The first demand and supply side research
|
||||
containing IDC's findings on Linux started to appear in early 1995.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
IDC has watched as Linux marched from being software for computer hobbyists to being
|
||||
a mainstream choice in many markets worldwide. This march is very similar to the adoption
|
||||
cycle UNIX experienced in the 1970s and 1980s. Windows repeated this pattern of adoption
|
||||
during the 1980s and 1990s. IDC has long projected that Linux would be a mainstream
|
||||
choice in nearly all markets by the end of 2005. The software is well down that path
|
||||
now and just might beat IDC's projections.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
As of the end of 2002, Linux was the number three desktop or client operating environment,
|
||||
responsible for nearly 3% of the worldwide shipments of client operating environment
|
||||
software. Linux was the number two server operating environment, responsible for nearly
|
||||
25% of the worldwide shipments of server operating environment software. This is an amazing
|
||||
level of growth from its rather humble beginnings of holding less than 1% share of either
|
||||
client or server operating environment market when IDC first started publishing its findings
|
||||
on Linux.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
IDC's demand-side studies have indicated that Linux is most often utilized as a platform
|
||||
for basic infrastructure services, such as supporting access to shared files and printers
|
||||
or supporting basic networking functions. IDC's most recent survey, conducted in late 2003,
|
||||
indicated that supporting file and print services was the most common use of Linux. Samba
|
||||
and NFS are the most commonly mentioned approaches to offering file and print services on
|
||||
Linux.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Nearly all of IDC's operating environment studies have shown that Linux is being added
|
||||
into organizational networks that already include Windows, UNIX, and mainframe operating
|
||||
environments. This, of course, means that interoperability with these operating environments
|
||||
is a crucial success factor for Linux.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
All of this leads to the book in hand, <emphasis>Samba-3 By Example</emphasis>, by John H. Terpstra, It addresses
|
||||
the most commonly heard questions about bringing Linux and Samba into a Windows or UNIX
|
||||
focused environment. Namely, organizations voice concerns about staff having sufficient
|
||||
levels of expertise to facilitate development, administration, operations and support activities
|
||||
around the adoption of Linux and Samba. I expect <emphasis>Samba-3</emphasis> by Example will be of enormous help
|
||||
to Windows or UNIX administrators hoping to gain a level of comfort and familiarity with both
|
||||
Linux and Samba.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Samba is a mature open source software product that is well established as a leading Windows
|
||||
file and print technology in use on large-scale UNIX systems. Its stability and scalability
|
||||
appears to be well respected. This book demonstrates easy approaches to implementing Samba-3
|
||||
no matter whether your network is large or small. It is a book that would make a fine addition
|
||||
to the network administrators' library!
|
||||
</para>
|
||||
</blockquote>
|
||||
|
||||
</sect1>
|
||||
|
||||
<sect1>
|
||||
<title>By Andrew Tridgell, Samba Team</title>
|
||||
|
||||
<blockquote><attribution>
|
||||
Andrew Tridgell, President, Samba Team
|
||||
</attribution>
|
||||
|
||||
<para>
|
||||
I've always been the sort of computer user that learns best by
|
||||
example. Seeing a complete example matching a real-world use of a
|
||||
piece of software gives me an understanding of that software far
|
||||
better than reading detailed manuals. If, like me, you are the sort of
|
||||
computer user that learns best by example then this book is for you.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
I was also delighted to see the use of ethereal to illustrate the
|
||||
network protocols used by Samba. Ethereal has developed into a very
|
||||
sophisticated network analysis tool, and familiarity with using
|
||||
ethereal is a very useful skill for any system administrator.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Enjoy this book, and make the most of Samba!
|
||||
</para>
|
||||
</blockquote>
|
||||
|
||||
</sect1>
|
||||
|
||||
</preface>
|
22
docs/guide/front-matter.xml
Normal file
@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
|
||||
|
||||
<!-- Stuff for xincludes -->
|
||||
<!ENTITY % xinclude SYSTEM "../entities/xinclude.dtd">
|
||||
%xinclude;
|
||||
|
||||
<!-- entities files to use -->
|
||||
<!ENTITY % global_entities SYSTEM '../entities/global.entities'>
|
||||
%global_entities;
|
||||
|
||||
]>
|
||||
|
||||
<preface lang="en-US">
|
||||
<title>Front Matter</title>
|
||||
|
||||
<para>
|
||||
Just a place holder.
|
||||
</para>
|
||||
|
||||
</preface>
|
270
docs/guide/glossary.xml
Normal file
@ -0,0 +1,270 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
|
||||
|
||||
<!-- Stuff for xincludes -->
|
||||
<!ENTITY % xinclude SYSTEM "../entities/xinclude.dtd">
|
||||
%xinclude;
|
||||
|
||||
<!-- entities files to use -->
|
||||
<!ENTITY % global_entities SYSTEM '../entities/global.entities'>
|
||||
%global_entities;
|
||||
|
||||
]>
|
||||
|
||||
<glossary>
|
||||
<title>Glossary</title>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Access Control List</glossterm>
|
||||
<acronym>ACL</acronym>
|
||||
<glossdef><para>
|
||||
A detailed list of permissions granted to users or groups with respect to file and network
|
||||
resource access.
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Active Directory Service</glossterm>
|
||||
<acronym>ADS</acronym>
|
||||
<glossdef><para>
|
||||
A service unique to Microsoft Windows 200x servers that provides a centrally managed
|
||||
directory for management of user identities and computer objects, as well as the
|
||||
permissions each user or computer may be granted to access distributed network resources.
|
||||
ADS uses Kerberos-based authentication and LDAP over Kerberos for directory access.
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Common Internet File System</glossterm>
|
||||
<acronym>CIFS</acronym>
|
||||
<glossdef><para>
|
||||
The new name for SMB. Microsoft renamed the SMB protocol to CIFS during
|
||||
the Internet hype in the 1990s. At about the time that the SMB protocol was renamed
|
||||
to CIFS, an additional dialect of the SMB protocol was in development. The need for the
|
||||
deployment of the NetBIOS layer was also removed, thus paving the way for use of the SMB
|
||||
protocol natively over TCP/IP (known as NetBIOS-less SMB or <quote>naked</quote> TCP
|
||||
transport).
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Common UNIX Printing System</glossterm>
|
||||
<acronym>CUPS</acronym>
|
||||
<glossdef><para>
|
||||
A recent implementation of a high-capability printing system for UNIX developed by
|
||||
<ulink url="http://www.easysw.com/">Easy Software Inc.</ulink> The design objective
|
||||
of CUPS was to provide a rich print processing system that has built-in intelligence
|
||||
that is capable of correctly rendering (processing) a file that is submitted for
|
||||
printing even if it was formatted for an entirely different printer.
|
||||
</para>
|
||||
</glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Domain Master Browser</glossterm>
|
||||
<acronym>DMB</acronym>
|
||||
<glossdef><para>
|
||||
The Domain Master Browser maintains a list of all the servers that
|
||||
have announced their services within a given workgroup or NT domain.
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Domain Name Service</glossterm>
|
||||
<acronym>DNS</acronym>
|
||||
<glossdef><para>
|
||||
A protocol by which computer hostnames may be resolved to the matching IP address/es.
|
||||
DNS is implemented by the Berkeley Internet Name Daemon. There exists a recent version
|
||||
of DNS that allows dynamic name registration by network clients or by a DHCP server.
|
||||
This recent protocol is known as Dynamic DNS (DDNS).
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Dynamic Host Configuration Protocol</glossterm>
|
||||
<acronym>DHCP</acronym>
|
||||
<glossdef><para>
|
||||
A protocol that was based on the BOOTP protocol that may be used to dynamically assign
|
||||
an IP address, from a reserved pool of addresses, to a network client or device.
|
||||
Additionally, DHCP may assign all network configuration settings and may be used to
|
||||
register a computer name and its address with a Dynamic DNS server.
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Ethereal</glossterm>
|
||||
<acronym>ethereal</acronym>
|
||||
<glossdef><para>
|
||||
A network analyzer, also known as: a network sniffer or a protocol analyzer. Ethereal is
|
||||
freely available for UNIX/Linux and Microsoft Windows systems from
|
||||
<ulink url="http://www.ethereal.com">the Ethereal Web site.</ulink>
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Group IDentifier</glossterm>
|
||||
<acronym>GID</acronym>
|
||||
<glossdef><para>
|
||||
The UNIX system Group Identifier; on older systems, a 32-bit unsigned integer, and on
|
||||
newer systems, an unsigned 64-bit integer. The GID is used in UNIX-like operating systems
|
||||
for all group level access control.
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Key Distribution Center</glossterm>
|
||||
<acronym>KDC</acronym>
|
||||
<glossdef><para>
|
||||
The Kerberos authentication protocol makes use of security keys (also called a ticket)
|
||||
by which access to network resources is controlled. The issuing of Kerberos tickets
|
||||
is effected by a KDC.
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Light Weight Directory Access Protocol</glossterm>
|
||||
<acronym>LDAP</acronym>
|
||||
<glossdef>
|
||||
<para>
|
||||
The Light Weight Directory Access Protocol is a technology that
|
||||
originated from the development of X.500 protocol specifications and
|
||||
implementations. LDAP was designed as a means of rapidly searching
|
||||
through X.500 information. Later LDAP was adapted as an engine that
|
||||
could drive its own directory database. LDAP is not a database per
|
||||
se; rather it is a technology that enables high volume search and
|
||||
locate activity from clients that wish to obtain simply defined
|
||||
information about a sub-set of records that are stored in a
|
||||
database. LDAP does not have a particularly efficient mechanism for
|
||||
storing records in the database, and it has no concept of transaction
|
||||
processing nor of mechanisms for preserving data consistency. LDAP is
|
||||
premised around the notion that the search and read activity far
|
||||
outweigh any need to add, delete, or modify records. LDAP does
|
||||
provide a means for replication of the database so as to keep slave
|
||||
servers up to date with a master. It also has built-in capability to
|
||||
handle external references and deferral.
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Local Master Browser</glossterm>
|
||||
<acronym>LMB</acronym>
|
||||
<glossdef><para>
|
||||
The Local Master Browser maintains a list of all servers that have announced themselves
|
||||
within a given workgroup or NT domain on a particular broadcast isolated subnet.
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Media Access Control</glossterm>
|
||||
<acronym>MAC</acronym>
|
||||
<glossdef><para>
|
||||
The hard-coded address of the physical layer device that is attached to the network.
|
||||
All network interface controllers must have a hard-coded and unique MAC address. The
|
||||
MAC address is 48 bits long.
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>NetBIOS Extended User Interface</glossterm>
|
||||
<acronym>NetBEUI</acronym>
|
||||
<glossdef><para>
|
||||
Very simple network protocol invented by IBM and Microsoft. It is used to do NetBIOS
|
||||
over ethernet with low overhead. NetBEUI is a non-routable protocol.
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Network Address Translation</glossterm>
|
||||
<acronym>NAT</acronym>
|
||||
<glossdef><para>
|
||||
Network address translation is a form of IP address masquerading. It ensures that internal
|
||||
private (RFC1918) network addresses from packets inside the network are rewritten so
|
||||
that TCP/IP packets that leave the server over a public connection are seen to come only
|
||||
from the external network address.
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Network Basic Input/Output System</glossterm>
|
||||
<acronym>NetBIOS</acronym>
|
||||
<glossdef><para>
|
||||
NetBIOS is a simple application programming interface (API) invented in the 1980s
|
||||
that allows programs to send data to certain network names. NetBIOS is always run over
|
||||
another network protocol such as IPX/SPX, TCP/IP, or Logical Link Control (LLC).
|
||||
NetBIOS run over LLC is best known as NetBEUI (The NetBIOS Extended User Interface
|
||||
&smbmdash; a complete misnomer!).
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>NetBT</glossterm>
|
||||
<acronym>NBT</acronym>
|
||||
<glossdef><para>
|
||||
Protocol for transporting NetBIOS frames over TCP/IP. Uses ports 137, 138, and 139.
|
||||
NetBT is a fully routable protocol.
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>NT/LanManager Security Support Provider</glossterm>
|
||||
<acronym>NTLMSSP</acronym>
|
||||
<glossdef><para>
|
||||
The NTLM Security Support Provider (NTLMSSP) service in Windows NT4/200x/XP is responsible for
|
||||
handling all NTLM authentication requests. It is the front end for protocols such as SPNEGO,
|
||||
Schannel, and other technologies. The generic protocol family supported by NTLMSSP is known as
|
||||
GSSAPI, the Generic Security Service Application Program Interface specified in RFC2078.
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Server Message Block</glossterm>
|
||||
<acronym>SMB</acronym>
|
||||
<glossdef><para>
|
||||
SMB was the original name of the protocol spoken by Samba. It was invented in the 1980s
|
||||
by IBM and adopted and extended further by Microsoft. Microsoft renamed the protocol to
|
||||
CIFS during the Internet hype in the 1990s.
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>The Simple and Protected GSS-API Negotiation</glossterm>
|
||||
<acronym>SPNEGO</acronym>
|
||||
<glossdef><para>
|
||||
The purpose of SPNEGO is to allow a client and server to negotiate a security mechanism for
|
||||
authentication. The protocol is specified in RFC2478 and uses tokens as built via ASN.1 DER.
|
||||
DER refers to Distinguished Encoding Rules. These are a set of common rules for creating
|
||||
binary encodings in a platform-independent manner. Samba has support for SPNEGO.
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>The Official Samba-3 HOWTO and Reference Guide</glossterm>
|
||||
<acronym>TOSHARG</acronym>
|
||||
<glossdef><para>
|
||||
This book makes repeated reference to <quote>The Official Samba-3 HOWTO and Reference Guide</quote>
|
||||
by John H. Terpstra (Author) and Jelmer R. Vernooij (Author). This publication is available from
|
||||
Amazon.com. Publisher: Prentice Hall PTR (October 2003),
|
||||
ISBN: 0131453556.
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>User IDentifier</glossterm>
|
||||
<acronym>UID</acronym>
|
||||
<glossdef><para>
|
||||
The UNIX system User Identifier; on older systems, a 32-bit unsigned integer, and on newer systems,
|
||||
an unsigned 64-bit integer. The UID is used in UNIX-like operating systems for all user level access
|
||||
control.
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
<glossentry>
|
||||
<glossterm>Universal Naming Convention</glossterm>
|
||||
<acronym>UNC</acronym>
|
||||
<glossdef><para>A syntax for specifying the location of network resources (such as file shares).
|
||||
The UNC syntax was developed in the early days of MS DOS 3.x and is used internally by the SMB protocol.
|
||||
</para></glossdef>
|
||||
</glossentry>
|
||||
|
||||
</glossary>
|
423
docs/guide/gpl.xml
Normal file
@ -0,0 +1,423 @@
|
||||
<appendix>
|
||||
<appendixinfo>
|
||||
<title>GNU General Public License</title>
|
||||
<pubdate>Version 2, June 1991</pubdate>
|
||||
<copyright>
|
||||
<year>1989, 1991</year>
|
||||
<holder>Free Software Foundation, Inc.</holder>
|
||||
</copyright>
|
||||
<legalnotice>
|
||||
<para>
|
||||
<address>Free Software Foundation, Inc.
|
||||
<street>59 Temple Place, Suite 330</street>,
|
||||
<city>Boston</city>,
|
||||
<state>MA</state>
|
||||
<postcode>02111-1307</postcode>
|
||||
<country>USA</country>
|
||||
</address>.
|
||||
</para>
|
||||
<para> Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
|
||||
</para>
|
||||
</legalnotice>
|
||||
<releaseinfo> Version 2, June 1991</releaseinfo>
|
||||
</appendixinfo>
|
||||
<title>GNU General Public License</title>
|
||||
<sect1>
|
||||
<title>Preamble</title>
|
||||
<para> 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.
|
||||
</para>
|
||||
<para> 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.
|
||||
</para>
|
||||
<para> 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.
|
||||
</para>
|
||||
<para> 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.
|
||||
</para>
|
||||
<para> We protect your rights with two steps:
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para> copyright the software, and
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para> offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
<para> 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.
|
||||
</para>
|
||||
<para> 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.
|
||||
</para>
|
||||
<para> The precise terms and conditions for copying, distribution and modification
|
||||
follow.
|
||||
</para>
|
||||
</sect1>
|
||||
<sect1>
|
||||
<title>TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</title>
|
||||
<sect2>
|
||||
<title>Section 0</title>
|
||||
<para> 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
|
||||
<quote>work based on the Program
|
||||
</quote> 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
|
||||
<quote>modification
|
||||
</quote>.) Each licensee is addressed as <quote>you</quote>.
|
||||
</para>
|
||||
<para> 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.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 id="sect1">
|
||||
<title>Section 1</title>
|
||||
<para> 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.
|
||||
</para>
|
||||
<para> 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.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2 id="sect2">
|
||||
<title>Section 2</title>
|
||||
<para> 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
|
||||
<link linkend="sect1">Section 1
|
||||
</link> above, provided
|
||||
that you also meet all of these conditions:
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para> You must cause the modified files to carry prominent notices stating that
|
||||
you changed the files and the date of any change.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para> 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.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para> 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.
|
||||
<note>
|
||||
<title>Exception:
|
||||
</title>
|
||||
<para> 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.)
|
||||
</para>
|
||||
</note>
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
<para> 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.
|
||||
</para>
|
||||
<para> 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.
|
||||
</para>
|
||||
<para> 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.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Section 3
|
||||
</title>
|
||||
<para> You may copy and distribute the Program (or a work based on it, under
|
||||
<link linkend="sect2">Section 2
|
||||
</link> in object code or executable form under the terms of
|
||||
<link linkend="sect1">Sections 1
|
||||
</link> and
|
||||
<link linkend="sect2">2
|
||||
</link> above provided that you also do one of the following:
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para> 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,
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para> 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,
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para> 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.)
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</para>
|
||||
<para> 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.
|
||||
</para>
|
||||
<para> 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.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Section 4
|
||||
</title>
|
||||
<para> 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.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Section 5
|
||||
</title>
|
||||
<para> 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.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Section 6
|
||||
</title>
|
||||
<para> 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.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Section 7
|
||||
</title>
|
||||
<para> 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.
|
||||
</para>
|
||||
<para> 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.
|
||||
</para>
|
||||
<para> 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.
|
||||
</para>
|
||||
<para> This section is intended to make thoroughly clear what is believed to be a consequence of the
|
||||
rest of this License.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Section 8
|
||||
</title>
|
||||
<para> 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.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Section 9
|
||||
</title>
|
||||
<para> 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.
|
||||
</para>
|
||||
<para> 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.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Section 10
|
||||
</title>
|
||||
<para> 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.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>NO WARRANTY Section 11
|
||||
</title>
|
||||
<para> 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.
|
||||
</para>
|
||||
</sect2>
|
||||
<sect2>
|
||||
<title>Section 12
|
||||
</title>
|
||||
<para> 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.
|
||||
</para>
|
||||
<para>END OF TERMS AND CONDITIONS
|
||||
</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
<sect1>
|
||||
<title>How to Apply These Terms to Your New Programs
|
||||
</title>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
<para>
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
</para>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
<para>
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
</para>
|
||||
<para>
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
</para>
|
||||
<para>
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
</para>
|
||||
<para>
|
||||
Gnomovision version 69, Copyright (C) year 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.
|
||||
</para>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
<para>
|
||||
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:
|
||||
</para>
|
||||
<para>
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
</para>
|
||||
<para>
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
</para>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
</sect1>
|
||||
</appendix>
|
56
docs/guide/guide-main.xml
Normal file
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
|
||||
|
||||
<!-- Stuff for xincludes -->
|
||||
<!ENTITY % xinclude SYSTEM "../entities/xinclude.dtd">
|
||||
%xinclude;
|
||||
|
||||
<!-- entities files to use -->
|
||||
<!ENTITY % global_entities SYSTEM '../entities/global.entities'>
|
||||
%global_entities;
|
||||
|
||||
]>
|
||||
<book id="S3bE">
|
||||
<title>Samba-3 by Example</title>
|
||||
<subtitle>Practical Exercises in Successful Samba Deployment</subtitle>
|
||||
<bookinfo>
|
||||
<authorgroup>
|
||||
<author>&person.jht;</author>
|
||||
</authorgroup>
|
||||
<pubdate>February 23, 2004</pubdate>
|
||||
<version>20040220</version>
|
||||
</bookinfo>
|
||||
<?latex \clearpage ?>
|
||||
<para>boo</para>
|
||||
<?latex \clearpage ?>
|
||||
<para>boo</para>
|
||||
<?latex \clearpage ?>
|
||||
<para>boo</para>
|
||||
<xi:include href="inside-cover.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
|
||||
<xi:include href="acknowledgements.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
|
||||
<xi:include href="foreword.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
|
||||
<xi:include href="preface.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
|
||||
<?latex \cleardoublepage ?>
|
||||
<toc/>
|
||||
<?latex \cleardoublepage ?>
|
||||
<?latex \listofexamples ?>
|
||||
<?latex \cleardoublepage ?>
|
||||
<lot/>
|
||||
<!-- Chapters -->
|
||||
<xi:include href="Chap01-WindowsNetworkingPrimer.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
|
||||
<xi:include href="Chap02-SimpleOfficeServer.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
|
||||
<xi:include href="Chap03-TheSmallOffice.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
|
||||
<xi:include href="Chap04-SecureOfficeServer.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
|
||||
<xi:include href="Chap05-500UserNetwork.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
|
||||
<xi:include href="Chap06-MakingHappyUsers.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
|
||||
<xi:include href="Chap07-2000UserNetwork.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
|
||||
<xi:include href="Chap08-MigrateNT4Samba3.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
|
||||
<xi:include href="Chap09-AddingUNIXClients.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
|
||||
<xi:include href="Chap10-KerberosFastStart.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
|
||||
<xi:include href="Chap10b-DomainAppsSupport.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
|
||||
<xi:include href="Chap11-HighAvailability.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
|
||||
<xi:include href="Chap12-Appendix.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
|
||||
<?latex \include{gpl}?>
|
||||
<xi:include href="glossary.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
|
||||
<index/>
|
||||
</book>
|
BIN
docs/guide/images/AccountingNetwork.dia
Normal file
BIN
docs/guide/images/AccountingNetwork.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
docs/guide/images/Charity-Network.dia
Normal file
BIN
docs/guide/images/Charity-Network.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
docs/guide/images/Domain-WorkgroupAnnouncement.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
docs/guide/images/HostAnnouncment.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
docs/guide/images/LocalMasterAnnouncement.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
docs/guide/images/NullConnect.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
docs/guide/images/UNIX-Samba-and-LDAP.dia
Normal file
BIN
docs/guide/images/UNIX-Samba-and-LDAP.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
docs/guide/images/UserConnect.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
docs/guide/images/UserMgrNT4.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
docs/guide/images/WINREPRESSME-Capture.png
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
docs/guide/images/WINREPRESSME-Capture2.png
Normal file
After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 7.8 KiB |
BIN
docs/guide/images/WindowsXP-NullConnection.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
docs/guide/images/WindowsXP-UserConnection.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
docs/guide/images/XP-screen001.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
docs/guide/images/acct2net.dia
Normal file
BIN
docs/guide/images/acct2net.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
docs/guide/images/ch7-dual-additive-LDAP-Ok.dia
Normal file
BIN
docs/guide/images/ch7-dual-additive-LDAP-Ok.png
Normal file
After Width: | Height: | Size: 8.1 KiB |
BIN
docs/guide/images/ch7-dual-additive-LDAP.dia
Normal file
BIN
docs/guide/images/ch7-dual-additive-LDAP.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
docs/guide/images/ch7-fail-overLDAP.dia
Normal file
BIN
docs/guide/images/ch7-fail-overLDAP.png
Normal file
After Width: | Height: | Size: 6.1 KiB |
BIN
docs/guide/images/ch7-singleLDAP.dia
Normal file
BIN
docs/guide/images/ch7-singleLDAP.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
docs/guide/images/ch8-migration.dia
Normal file
BIN
docs/guide/images/ch8-migration.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
docs/guide/images/chap4-net.dia
Normal file
BIN
docs/guide/images/chap4-net.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
docs/guide/images/chap5-net.dia
Normal file
BIN
docs/guide/images/chap5-net.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
docs/guide/images/chap6-net.dia
Normal file
BIN
docs/guide/images/chap6-net.png
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
docs/guide/images/chap7-idresol.dia
Normal file
BIN
docs/guide/images/chap7-idresol.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
docs/guide/images/chap7-net-A.dia
Normal file
BIN
docs/guide/images/chap7-net-A.png
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
docs/guide/images/chap7-net-Ar.png
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
docs/guide/images/chap7-net.dia
Normal file
BIN
docs/guide/images/chap7-net.png
Normal file
After Width: | Height: | Size: 74 KiB |
BIN
docs/guide/images/chap7-net2-B.dia
Normal file
BIN
docs/guide/images/chap7-net2-B.png
Normal file
After Width: | Height: | Size: 86 KiB |
BIN
docs/guide/images/chap7-net2-Br.png
Normal file
After Width: | Height: | Size: 98 KiB |
BIN
docs/guide/images/chap7-net2.dia
Normal file
BIN
docs/guide/images/chap7-net2.png
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
docs/guide/images/chap7-net2r.png
Normal file
After Width: | Height: | Size: 94 KiB |
BIN
docs/guide/images/chap7-netr.png
Normal file
After Width: | Height: | Size: 82 KiB |