diff options
Diffstat (limited to 'docs/docbook')
25 files changed, 1341 insertions, 0 deletions
diff --git a/docs/docbook/devdoc/.cvsignore b/docs/docbook/devdoc/.cvsignore new file mode 100644 index 0000000000..3bbac303f5 --- /dev/null +++ b/docs/docbook/devdoc/.cvsignore @@ -0,0 +1 @@ +attributions.xml diff --git a/docs/docbook/devdoc/vfs.xml b/docs/docbook/devdoc/vfs.xml new file mode 100644 index 0000000000..ed2afef53e --- /dev/null +++ b/docs/docbook/devdoc/vfs.xml @@ -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@metzemix.de</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> diff --git a/docs/docbook/devdoc/windows-debug.xml b/docs/docbook/devdoc/windows-debug.xml new file mode 100644 index 0000000000..3535c38dbd --- /dev/null +++ b/docs/docbook/devdoc/windows-debug.xml @@ -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> diff --git a/docs/docbook/manpages/profiles.1.sgml b/docs/docbook/manpages/profiles.1.sgml new file mode 100644 index 0000000000..6fd2b6fd86 --- /dev/null +++ b/docs/docbook/manpages/profiles.1.sgml @@ -0,0 +1,86 @@ +<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [ +<!ENTITY % globalentities SYSTEM '../global.ent'> %globalentities; +]> +<refentry id="profiles.1"> + +<refmeta> + <refentrytitle>profiles</refentrytitle> + <manvolnum>1</manvolnum> +</refmeta> + + +<refnamediv> + <refname>profiles</refname> + <refpurpose>A utility to report and change SIDs in registry files + </refpurpose> +</refnamediv> + +<refsynopsisdiv> + <cmdsynopsis> + <command>profiles</command> + <arg choice="opt">-v</arg> + <arg choice="opt">-c SID</arg> + <arg choice="opt">-n SID</arg> + <arg choice="req">file</arg> + </cmdsynopsis> +</refsynopsisdiv> + +<refsect1> + <title>DESCRIPTION</title> + + <para>This tool is part of the <citerefentry><refentrytitle>Samba</refentrytitle> + <manvolnum>7</manvolnum></citerefentry> suite.</para> + + <para><command>profiles</command> is a utility that + reports and changes SIDs in windows registry files. It currently only + supports NT. + </para> +</refsect1> + + +<refsect1> + <title>OPTIONS</title> + + <variablelist> + <varlistentry> + <term>file</term> + <listitem><para>Registry file to view or edit. </para></listitem> + </varlistentry> + + + <varlistentry> + <term>-v,--verbose</term> + <listitem><para>Increases verbosity of messages. + </para></listitem> + </varlistentry> + + <varlistentry> + <term>-c SID1 -n SID2</term> + <listitem><para>Change all occurences of SID1 in <filename>file</filename> by SID2. + </para></listitem> + </varlistentry> + + &stdarg.help; + + </variablelist> +</refsect1> + +<refsect1> + <title>VERSION</title> + + <para>This man page is correct for version 3.0 of the Samba + suite.</para> +</refsect1> + +<refsect1> + <title>AUTHOR</title> + + <para>The original Samba software and related utilities + were created by Andrew Tridgell. Samba is now developed + by the Samba Team as an Open Source project similar + to the way the Linux kernel is developed.</para> + + <para>The profiles man page was written by Jelmer Vernooij. </para> +</refsect1> + +</refentry> diff --git a/docs/docbook/projdoc/.cvsignore b/docs/docbook/projdoc/.cvsignore new file mode 100644 index 0000000000..3bbac303f5 --- /dev/null +++ b/docs/docbook/projdoc/.cvsignore @@ -0,0 +1 @@ +attributions.xml diff --git a/docs/docbook/projdoc/Backup.xml b/docs/docbook/projdoc/Backup.xml new file mode 100644 index 0000000000..b3c37aba53 --- /dev/null +++ b/docs/docbook/projdoc/Backup.xml @@ -0,0 +1,36 @@ +<chapter id="Backup"> +<chapterinfo> + &author.jht; +</chapterinfo> + +<title>Samba Backup Techniques</title> + +<sect1> +<title>Note</title> + +<para> +This chapter did not make it into this release. +It is planned for the published release of this document. +If you have something to contribute for this section please email it to +<link url="mail://jht@samba.org">jht@samba.org</link>/ +</para> + +</sect1> + +<sect1> +<title>Features and Benefits</title> + +<para> +We need feedback from people who are backing up samba servers. +We would like to know what software tools you are using to backup +your samba server/s. +</para> + +<para> +In particular, if you have any success and / or failure stories you could +share with other users this would be appreciated. +</para> + +</sect1> + +</chapter> diff --git a/docs/docbook/projdoc/DNS-DHCP-Configuration.xml b/docs/docbook/projdoc/DNS-DHCP-Configuration.xml new file mode 100644 index 0000000000..21bda63276 --- /dev/null +++ b/docs/docbook/projdoc/DNS-DHCP-Configuration.xml @@ -0,0 +1,17 @@ +<chapter id="DNSDHCP"> +<chapterinfo> + &author.jht; +</chapterinfo> + +<title>DNS and DHCP Configuration Guide</title> + +<sect1> +<title>Note</title> + +<para> +This chapter did not make it into this release. +It is planned for the published release of this document. +</para> + +</sect1> +</chapter> diff --git a/docs/docbook/projdoc/FastStart.xml b/docs/docbook/projdoc/FastStart.xml new file mode 100644 index 0000000000..a1aee9b7df --- /dev/null +++ b/docs/docbook/projdoc/FastStart.xml @@ -0,0 +1,17 @@ +<chapter id="FastStart"> +<chapterinfo> + &author.jht; +</chapterinfo> + +<title>Fast Start for the Impatient</title> + +<sect1> +<title>Note</title> + +<para> +This chapter did not make it into this release. +It is planned for the published release of this document. +</para> + +</sect1> +</chapter> diff --git a/docs/docbook/projdoc/HighAvailability.xml b/docs/docbook/projdoc/HighAvailability.xml new file mode 100644 index 0000000000..3cd7fac807 --- /dev/null +++ b/docs/docbook/projdoc/HighAvailability.xml @@ -0,0 +1,17 @@ +<chapter id="SambaHA"> +<chapterinfo> + &author.jht; +</chapterinfo> + +<title>High Availability Options</title> + +<sect1> +<title>Note</title> + +<para> +This chapter did not make it into this release. +It is planned for the published release of this document. +</para> + +</sect1> +</chapter> diff --git a/docs/docbook/projdoc/WindowsClientConfig.xml b/docs/docbook/projdoc/WindowsClientConfig.xml new file mode 100644 index 0000000000..ea1d4d5aa3 --- /dev/null +++ b/docs/docbook/projdoc/WindowsClientConfig.xml @@ -0,0 +1,17 @@ +<chapter id="ClientConfig"> +<chapterinfo> + &author.jht; +</chapterinfo> + +<title>MS Windows Network Configuration Guide</title> + +<sect1> +<title>Note</title> + +<para> +This chapter did not make it into this release. +It is planned for the published release of this document. +</para> + +</sect1> +</chapter> diff --git a/docs/docbook/smbdotconf/misc/valid.xml b/docs/docbook/smbdotconf/misc/valid.xml new file mode 100644 index 0000000000..b5756f0afe --- /dev/null +++ b/docs/docbook/smbdotconf/misc/valid.xml @@ -0,0 +1,18 @@ +<samba:parameter name="-valid" + context="S" + xmlns:samba="http://samba.org/common"> + <listitem> + <para> This parameter indicates whether a share is + valid and thus can be used. When this parameter is set to false, + the share will be in no way visible nor accessible. + </para> + + <para> + This option should not be + used by regular users but might be of help to developers. + Samba uses this option internally to mark shares as deleted. + </para> + + <para>Default: <emphasis>True</emphasis></para> +</listitem> +</samba:parameter> diff --git a/docs/docbook/smbdotconf/printing/totalprintjobs.xml b/docs/docbook/smbdotconf/printing/totalprintjobs.xml new file mode 100644 index 0000000000..ccdb137a69 --- /dev/null +++ b/docs/docbook/smbdotconf/printing/totalprintjobs.xml @@ -0,0 +1,22 @@ +<samba:parameter name="total print jobs" + context="G" + print="1" + xmlns:samba="http://samba.org/common"> +<listitem> + <para>This parameter accepts an integer value which defines + a limit on the maximum number of print jobs that will be accepted + system wide at any given time. If a print job is submitted + by a client which will exceed this number, then <citerefentry><refentrytitle>smbd</refentrytitle> + <manvolnum>8</manvolnum></citerefentry> will return an + error indicating that no space is available on the server. The + default value of 0 means that no such limit exists. This parameter + can be used to prevent a server from exceeding its capacity and is + designed as a printing throttle. See also <link linkend="MAXPRINTJOBS"> + <parameter moreinfo="none">max print jobs</parameter></link>. + </para> + + <para>Default: <command moreinfo="none">total print jobs = 0</command></para> + + <para>Example: <command moreinfo="none">total print jobs = 5000</command></para> +</listitem> +</samba:parameter> diff --git a/docs/docbook/smbdotconf/protocol/clientusespnego.xml b/docs/docbook/smbdotconf/protocol/clientusespnego.xml new file mode 100644 index 0000000000..df25fbfb20 --- /dev/null +++ b/docs/docbook/smbdotconf/protocol/clientusespnego.xml @@ -0,0 +1,13 @@ +<samba:parameter name="client use spnego" + context="G" + developer="1" + xmlns:samba="http://samba.org/common"> +<listitem> + <para> This variable controls controls whether samba clients will try + to use Simple and Protected NEGOciation (as specified by rfc2478) with + WindowsXP and Windows2000 servers to agree upon an authentication mechanism. + </para> + + <para>Default: <emphasis>client use spnego = yes</emphasis></para> +</listitem> +</samba:parameter> diff --git a/docs/docbook/smbdotconf/protocol/mapaclinherit.xml b/docs/docbook/smbdotconf/protocol/mapaclinherit.xml new file mode 100644 index 0000000000..5b8ed7f656 --- /dev/null +++ b/docs/docbook/smbdotconf/protocol/mapaclinherit.xml @@ -0,0 +1,17 @@ +<samba:parameter name="map acl inherit" + context="S" + advanced="1" wizard="1" + xmlns:samba="http://samba.org/common"> +<listitem> + <para>This boolean parameter controls whether <citerefentry><refentrytitle>smbd</refentrytitle> + <manvolnum>8</manvolnum></citerefentry> will attempt to map the 'inherit' and 'protected' + access control entry flags stored in Windows ACLs into an extended attribute + called user.SAMBA_PAI. This parameter only takes effect if Samba is being run + on a platform that supports extended attributes (Linux and IRIX so far) and + allows the Windows 2000 ACL editor to correctly use inheritance with the Samba + POSIX ACL mapping code. + </para> + + <para>Default: <command moreinfo="none">map acl inherit = no</command></para> +</listitem> +</samba:parameter> diff --git a/docs/docbook/smbdotconf/protocol/profileacls.xml b/docs/docbook/smbdotconf/protocol/profileacls.xml new file mode 100644 index 0000000000..6f2b3ec510 --- /dev/null +++ b/docs/docbook/smbdotconf/protocol/profileacls.xml @@ -0,0 +1,33 @@ +<samba:parameter name="profile acls" + context="S" + advanced="1" wizard="1" + xmlns:samba="http://samba.org/common"> +<listitem> + <para>This boolean parameter controls whether <citerefentry><refentrytitle>smbd</refentrytitle> + <manvolnum>8</manvolnum></citerefentry> + This boolean parameter was added to fix the problems that people have been + having with storing user profiles on Samba shares from Windows 2000 or + Windows XP clients. New versions of Windows 2000 or Windows XP service + packs do security ACL checking on the owner and ability to write of the + profile directory stored on a local workstation when copied from a Samba + share. When not in domain mode with winbindd then the security info copied + onto the local workstation has no meaning to the logged in user (SID) on + that workstation so the profile storing fails. Adding this parameter + onto a share used for profile storage changes two things about the + returned Windows ACL. Firstly it changes the owner and group owner + of all reported files and directories to be BUILTIN\\Administrators, + BUILTIN\\Users respectively (SIDs S-1-5-32-544, S-1-5-32-545). Secondly + it adds an ACE entry of "Full Control" to the SID BUILTIN\\Users to + every returned ACL. This will allow any Windows 2000 or XP workstation + user to access the profile. Note that if you have multiple users logging + on to a workstation then in order to prevent them from being able to access + each others profiles you must remove the "Bypass traverse checking" advanced + user right. This will prevent access to other users profile directories as + the top level profile directory (named after the user) is created by the + workstation profile code and has an ACL restricting entry to the directory + tree to the owning user. + </para> + + <para>Default: <command moreinfo="none">profile acls = no</command></para> +</listitem> +</samba:parameter> diff --git a/docs/docbook/smbdotconf/security/clientlanmanauth.xml b/docs/docbook/smbdotconf/security/clientlanmanauth.xml new file mode 100644 index 0000000000..a427198ea3 --- /dev/null +++ b/docs/docbook/smbdotconf/security/clientlanmanauth.xml @@ -0,0 +1,28 @@ +<samba:parameter name="client lanman auth" + context="G" + advanced="1" developer="1" + xmlns:samba="http://samba.org/common"> +<listitem> + <para>This parameter determines whether or not <citerefentry><refentrytitle>smbclient</refentrytitle> + <manvolnum>8</manvolnum></citerefentry> and other samba client + tools will attempt to authenticate itself to servers using the + weaker LANMAN password hash. If disabled, only server which support NT + password hashes (e.g. Windows NT/2000, Samba, etc... but not + Windows 95/98) will be able to be connected from the Samba client.</para> + + <para>The LANMAN encrypted response is easily broken, due to it's + case-insensitive nature, and the choice of algorithm. Clients + without Windows 95/98 servers are advised to disable + this option. </para> + + <para>Disabling this option will also disable the <command + moreinfo="none">client plaintext auth</command> option</para> + + <para>Likewise, if the <command moreinfo="none">client ntlmv2 + auth</command> parameter is enabled, then only NTLMv2 logins will be + attempted. Not all servers support NTLMv2, and most will require + special configuration to us it.</para> + + <para>Default : <command moreinfo="none">client lanman auth = yes</command></para> +</listitem> +</samba:parameter> diff --git a/docs/docbook/smbdotconf/security/clientntlmv2auth.xml b/docs/docbook/smbdotconf/security/clientntlmv2auth.xml new file mode 100644 index 0000000000..0bf196488b --- /dev/null +++ b/docs/docbook/smbdotconf/security/clientntlmv2auth.xml @@ -0,0 +1,26 @@ +<samba:parameter name="client ntlmv2 auth" + context="G" + advanced="1" developer="1" + xmlns:samba="http://samba.org/common"> +<listitem> + <para>This parameter determines whether or not <citerefentry><refentrytitle>smbclient</refentrytitle> + <manvolnum>8</manvolnum></citerefentry> will attempt to + authenticate itself to servers using the NTLMv2 encrypted password + response.</para> + + <para>If enabled, only an NTLMv2 and LMv2 response (both much more + secure than earlier versions) will be sent. Many servers + (including NT4 < SP4, Win9x and Samba 2.2) are not compatible with + NTLMv2. </para> + + <para>If disabled, an NTLM response (and possibly a LANMAN response) + will be sent by the client, depending on the value of <command + moreinfo="none">client lanman auth</command>. </para> + + <para>Note that some sites (particularly + those following 'best practice' security polices) only allow NTLMv2 + responses, and not the weaker LM or NTLM.</para> + + <para>Default : <command moreinfo="none">client ntlmv2 auth = no</command></para> +</listitem> +</samba:parameter> diff --git a/docs/docbook/smbdotconf/vfs/vfsobjects.xml b/docs/docbook/smbdotconf/vfs/vfsobjects.xml new file mode 100644 index 0000000000..32a10b5bd6 --- /dev/null +++ b/docs/docbook/smbdotconf/vfs/vfsobjects.xml @@ -0,0 +1,14 @@ +<samba:parameter name="vfs objects" + context="S" + xmlns:samba="http://samba.org/common"> +<listitem> + <para>This parameter specifies the backend names which + are used for Samba VFS I/O operations. By default, normal + disk I/O operations are used but these can be overloaded + with one or more VFS objects. </para> + + <para>Default: <emphasis>no value</emphasis></para> + + <para>Example: <command moreinfo="none">vfs objects = extd_audit recycle</command></para> +</listitem> +</samba:parameter> diff --git a/docs/docbook/smbdotconf/winbind/enableridalgorithm.xml b/docs/docbook/smbdotconf/winbind/enableridalgorithm.xml new file mode 100644 index 0000000000..86786f0734 --- /dev/null +++ b/docs/docbook/smbdotconf/winbind/enableridalgorithm.xml @@ -0,0 +1,17 @@ +<samba:parameter name="enable rid algorithm" + context="G" + advanced="1" developer="1" hide="1" + xmlns:samba="http://samba.org/common"> +<listitem> + <para>This option is used to control whether or not smbd in Samba 3.0 should fallback + to the algorithm used by Samba 2.2 to generate user and group RIDs. The longterm + development goal is to remove the algorithmic mappings of RIDs altogether, but + this has proved to be difficult. This parameter is mainly provided so that + developers can turn the algorithm on and off and see what breaks. This parameter + should not be disabled by non-developers because certain features in Samba will fail + to work without it. + </para> + + <para>Default: <command moreinfo="none">enable rid algorithm = <yes></command></para> +</listitem> +</samba:parameter> diff --git a/docs/docbook/smbdotconf/winbind/idmapgid.xml b/docs/docbook/smbdotconf/winbind/idmapgid.xml new file mode 100644 index 0000000000..8bd46a80c6 --- /dev/null +++ b/docs/docbook/smbdotconf/winbind/idmapgid.xml @@ -0,0 +1,18 @@ +<samba:parameter name="idmap gid" + context="G" + advanced="1" developer="1" hide="1" + xmlns:samba="http://samba.org/common"> +<listitem> + + <para>The idmap gid parameter specifies the range of group ids that are allocated for + the purpose of mapping UNX groups to NT group SIDs. This range of group ids should have no + existing local or NIS groups within it as strange conflicts can occur otherwise.</para> + + <para>The availability of an idmap gid range is essential for correct operation of + all group mapping.</para> + + <para>Default: <command moreinfo="none">idmap gid = <empty string></command></para> + + <para>Example: <command moreinfo="none">idmap gid = 10000-20000</command></para> +</listitem> +</samba:parameter> diff --git a/docs/docbook/smbdotconf/winbind/idmapuid.xml b/docs/docbook/smbdotconf/winbind/idmapuid.xml new file mode 100644 index 0000000000..5e6a245bfe --- /dev/null +++ b/docs/docbook/smbdotconf/winbind/idmapuid.xml @@ -0,0 +1,14 @@ +<samba:parameter name="idmap uid" + context="G" + advanced="1" developer="1" hide="1" + xmlns:samba="http://samba.org/common"> +<listitem> + <para>The idmap uid parameter specifies the range of user ids that are allocated for use + in mapping UNIX users to NT user SIDs. This range of ids should have no existing local + or NIS users within it as strange conflicts can occur otherwise.</para> + + <para>Default: <command moreinfo="none">idmap uid = <empty string></command></para> + + <para>Example: <command moreinfo="none">idmap uid = 10000-20000</command></para> +</listitem> +</samba:parameter> diff --git a/docs/docbook/smbdotconf/winbind/templateprimarygroup.xml b/docs/docbook/smbdotconf/winbind/templateprimarygroup.xml new file mode 100644 index 0000000000..bd59ea7ee0 --- /dev/null +++ b/docs/docbook/smbdotconf/winbind/templateprimarygroup.xml @@ -0,0 +1,14 @@ +<samba:parameter name="template primary group" + context="G" + advanced="1" developer="1" + xmlns:samba="http://samba.org/common"> +<listitem> + <para>This option defines the default primary group for + each user created by <citerefentry><refentrytitle>winbindd</refentrytitle> + <manvolnum>8</manvolnum></citerefentry>'s local account management + functions (similar to the 'add user script'). + </para> + + <para>Default: <command moreinfo="none">template primary group = nobody</command></para> +</listitem> +</samba:parameter> diff --git a/docs/docbook/smbdotconf/winbind/winbindenablelocalaccounts.xml b/docs/docbook/smbdotconf/winbind/winbindenablelocalaccounts.xml new file mode 100644 index 0000000000..f6e7cfb359 --- /dev/null +++ b/docs/docbook/smbdotconf/winbind/winbindenablelocalaccounts.xml @@ -0,0 +1,16 @@ +<samba:parameter name="winbind enable local accounts" + context="G" + advanced="1" developer="1" + xmlns:samba="http://samba.org/common"> +<listitem> + <para>This parameter controls whether or not winbindd + will act as a stand in replacement for the various account + management hooks in smb.conf (e.g. 'add user script'). + If enabled, winbindd will support the creation of local + users and groups as another source of UNIX account information + available via getpwnam() or getgrgid(), etc... + </para> + + <para>Default: <command moreinfo="none">winbind enable local accounts = yes</command></para> +</listitem> +</samba:parameter> diff --git a/docs/docbook/smbdotconf/winbind/winbindtrusteddomainsonly.xml b/docs/docbook/smbdotconf/winbind/winbindtrusteddomainsonly.xml new file mode 100644 index 0000000000..bf383131d4 --- /dev/null +++ b/docs/docbook/smbdotconf/winbind/winbindtrusteddomainsonly.xml @@ -0,0 +1,16 @@ +<samba:parameter name="winbind trusted domains only" + context="G" + advanced="1" developer="1" + xmlns:samba="http://samba.org/common"> +<listitem> + <para>This parameter is designed to allow Samba servers that + are members of a Samba controlled domain to use UNIX accounts + distributed vi NIS, rsync, or LDAP as the uid's for winbindd users + in the hosts primary domain. Therefore, the user 'SAMBA\user1' would + be mapped to the account 'user1' in /etc/passwd instead of allocating + a new uid for him or her. + </para> + + <para>Default: <command moreinfo="none">winbind trusted domains only = <no></command></para> +</listitem> +</samba:parameter> diff --git a/docs/docbook/xslt/generate-attributions.xsl b/docs/docbook/xslt/generate-attributions.xsl new file mode 100644 index 0000000000..c781a77cc4 --- /dev/null +++ b/docs/docbook/xslt/generate-attributions.xsl @@ -0,0 +1,67 @@ +<?xml version='1.0'?> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:exsl="http://exslt.org/common" + xmlns:samba="http://samba.org/common" + version="1.1" + extension-element-prefixes="exsl"> + +<xsl:output method="xml" omit-xml-declaration="yes"/> + +<!-- Remove all character data --> +<xsl:template match="@*|node()"> + <xsl:apply-templates select="@*|node()"/> +</xsl:template> + +<xsl:template match="book"> + <xsl:element name="variablelist"> + <xsl:apply-templates/> + </xsl:element> +</xsl:template> + +<xsl:template match="chapter"> + <xsl:element name="varlistentry"> + <xsl:element name="term"> + <xsl:element name="link"> + <xsl:attribute name="linkend"><xsl:value-of select="@id"/></xsl:attribute> + <xsl:value-of select="title"/> + </xsl:element> + </xsl:element> + <xsl:element name="listitem"> + <xsl:element name="para"> + <xsl:element name="itemizedlist"> + <xsl:apply-templates/> + </xsl:element> + </xsl:element> + </xsl:element> + </xsl:element> +</xsl:template> + +<xsl:template match="author"> + <xsl:element name="listitem"> + <xsl:element name="para"> + <xsl:value-of select="firstname"/><xsl:text> </xsl:text><xsl:value-of select="surname"/> + <xsl:choose> + <xsl:when test="affiliation/address/email != ''"> + <xsl:text> <</xsl:text> + <xsl:element name="ulink"> + <xsl:attribute name="url"> + <xsl:text>mailto:</xsl:text> + <xsl:value-of select="affiliation/address/email"/> + </xsl:attribute> + <xsl:value-of select="affiliation/address/email"/> + </xsl:element> + <xsl:text>></xsl:text> + </xsl:when> + </xsl:choose> + <xsl:choose> + <xsl:when test="contrib != ''"> + <xsl:text> (</xsl:text> + <xsl:value-of select="contrib"/> + <xsl:text>) </xsl:text> + </xsl:when> + </xsl:choose> + </xsl:element> + </xsl:element> +</xsl:template> + +</xsl:stylesheet> |